1. 程式人生 > >mysqldump大致原理以及mysqldump備份過程中進行DDL操作的影響

mysqldump大致原理以及mysqldump備份過程中進行DDL操作的影響

mysqldump大致原理以及mysqldump備份過程中進行DDL操作的影響
mysqldump大致原理
第一種情況
第二種情況

mysqldump大致原理以及mysqldump備份過程中進行DDL操作的影響

  • MySQL版本:5.7.18 
    隔離級別:REPEATABLE-READ 
    如果隔離級別不是RR,啟動事務快照讀的時候會報錯:

 
  1. [email protected] : (none) 10:38:48> show variables like '%isola%';
  2. +---------------+----------------+
  3. | Variable_name | Value |
  4. +---------------+----------------+
  5. | tx_isolation | READ-COMMITTED |
  6. +---------------+----------------+
  7. 1 row in set (0.00 sec)
  8. [email protected] : (none) 10:38:50> START TRANSACTION /*!40100 WITH CONSISTENT SNAPSHOT */ ;
  9. Query
    OK, 0 rows affected, 1 warning (0.00 sec)
  10. Warning (Code 138): InnoDB: WITH CONSISTENT SNAPSHOT was ignored because this phrase can only be used with REPEATABLE READ isolation level.
  11. [email protected] : (none) 10:39:01> set global tx_isolation='REPEATABLE-READ';
  12. Query OK, 0 rows affected
    (0.00 sec)
  13. #退出客戶端重進
  14. [email protected] : (none) 10:44:17> show variables like '%isola%';
  15. +---------------+-----------------+
  16. | Variable_name | Value |
  17. +---------------+-----------------+
  18. | tx_isolation | REPEATABLE-READ |
  19. +---------------+-----------------+
  20. 1 row in set (0.00 sec)
  21. [email protected] : (none) 10:44:38> START TRANSACTION /*!40100 WITH CONSISTENT SNAPSHOT */ ;
  22. Query OK, 0 rows affected (0.00 sec)

mysqldump大致原理

  • 1.FLUSH /!40101 LOCAL / TABLES 
    關閉所有在記憶體中開啟的表,清理查詢快取。
  • 2.FLUSH TABLES WITH READ LOCK 
    加一個全域性讀鎖,只允許讀,不允許更新操作。
  • 3.SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ 
    設定當前會話的事務隔離等級為RR,RR可避免不可重複讀和幻讀,保證在備份期間,一個事務中所有相同的查詢讀取到同樣的資料。
  • 4.START TRANSACTION /!40100 WITH CONSISTENT SNAPSHOT 
    獲取當前資料庫的快照,這個是由mysqldump中–single-transaction決定的,類似於開啟事務並對所有表執行了一次SELECT操作,這樣可保證備份時,在任意時間點執行select * from table得到的資料和執行START TRANSACTION WITH CONSISTENT SNAPSHOT時的資料一致。
  • 5.SHOW MASTER STATUS 
    –master-data決定的,記錄了開始備份時,binlog的狀態資訊,包括MASTER_LOG_FILE和MASTER_LOG_POS
  • 6.UNLOCK TABLES 
    釋放鎖,也就是說其實mysqldump這個語句,其實是有鎖表,只不過鎖了很短的時間
  • 7.SHOW CREATE DATABASE IF NOT EXISTS test 
    生成創庫語句。
  • 8.SAVEPOINT sp 
    設定SAVEPOINT,然後備份完每個表後再回滾到該SAVEPOINT。
  • 9.show create table test 
    生成創表語句
  • 10.SELECT /!40001 SQL_NO_CACHE / * FROM test 
    該語句會查詢到表test1的所有資料,在備份檔案中會生成相應的insert語句。 
    其中SQL_NO_CACHE的作用是查詢的結果並不會快取到查詢快取中。
  • 11.SHOW TRIGGERS LIKE 'test'; 
    備份觸發器。
  • 12.ROLLBACK TO SAVEPOINT sp 
    如果不執行ROLLBACK TO SAVEPOINT sp,可能會阻塞同時進行的DDL操作,執行了該語句後,DDL操作可以繼續執行。
  • 13.SHOW FUNCTION STATUS WHERE Db = 'test' 
    SHOW CREATE FUNCTION mycat_seq_currval 
    SHOW PROCEDURE STATUS WHERE Db = 'test' 
    用於備份儲存過程和函式

第一種情況


 
  1. session 1 session 2
  2. test 05:37:00> START TRANSACTION /*!40100 WITH CONSISTENT SNAPSHOT */ ;
  3. Query OK, 0 rows affected (0.00 sec)
  4. test 05:37:02> savepoint sp;
  5. Query OK, 0 rows affected (0.00 sec)
  6. test 05:37:08> show create table uniq_test;
  7. Query OK, 0 rows affected (0.00 sec)
  8. test 05:37:14> alter table uniq_test add column name7 varchar(10);
  9. Query OK, 0 rows affected (0.32 sec)
  10. test 05:37:24> select * from uniq_test;
  11. ERROR 1412 (HY000): Table definition has changed, please retry transaction
  12. test 05:37:39> rollback to savepoint sp;
  13. Query OK, 0 rows affected (0.00 sec)
  • START TRANSACTION /!40100 WITH CONSISTENT SNAPSHOT之後 /到select * from uniq_test之前,這中間,如果session 2執行ddl操作,則session 1中接著執行select * from uniq_test;就會報錯:Table definition has changed, please retry transaction 
    體現在mysqldump(unlock tables語句到SELECT /!40001 SQL_NO_CACHE / * FROM test 語句之間)出來的檔案就是無資料,無insert語句,表結構是在的。

第二種情況


 
  1. session 1 session 2
  2. test 05:37:00> START TRANSACTION /*!40100 WITH CONSISTENT SNAPSHOT */ ;
  3. Query OK, 0 rows affected (0.00 sec)
  4. test 05:37:02> savepoint sp;
  5. Query OK, 0 rows affected (0.00 sec)
  6. test 05:37:08> show create table uniq_test;
  7. Query OK, 0 rows affected (0.00 sec)
  8. test 05:37:24> select * from uniq_test;
  9. +----+------+-------+-------+-------+-------+-------+
  10. | id | name | name1 | name2 | name3 | name4 | name5 |
  11. +----+------+-------+-------+-------+-------+-------+
  12. | 1 | NULL | NULL | NULL | NULL | NULL | NULL |
  13. | 1 | NULL | NULL | NULL | NULL | NULL | NULL |
  14. | 2 | NULL | NULL | NULL | NULL | NULL | NULL |
  15. | 3 | NULL | NULL | NULL | NULL | NULL | NULL |
  16. +----+------+-------+-------+-------+-------+-------+
  17. 4 rows in set (0.00 sec)
  18. test 05:37:44> alter table uniq_test add column name6 varchar(10);
  19. test 05:38:10> rollback to savepoint sp;
  20. test 05:38:46> alter table uniq_test add column name6 varchar(10);
  21. Query OK, 0 rows affected (21.73 sec)
  • 在select * from uniq_test;之後到rollback to savepoint sp;之前,這中間,如果session 2執行ddl操作,則session 2的ddl操作會hang住,此時show processlist:

 
  1. test 05:37:52> show processlist;
  2. +----+------+-----------+------+---------+------+---------------------------------+-----------------------------------------------------+
  3. | Id | User | Host | db | Command | Time | State | Info |
  4. +----+------+-----------+------+---------+------+---------------------------------+-----------------------------------------------------+
  5. | 21 | root | localhost | test | Query | 4 | Waiting for table metadata lock | alter table uniq_test add column name6 varchar(10) |
  6. | 22 | root | localhost | test | Query | 0 | starting | show processlist |
  7. +----+------+-----------+------+---------+------+---------------------------------+-----------------------------------------------------+
  8. 2 rows in set (0.00 sec)

可以看