重新認識mysqldump

?????? mysql數據備份從備份方式上可分為物理備份和邏輯備份,物理備份有mysql企業版自帶工具,或者選擇percona的開源備份工具percona-xtra-backup,可以簡稱pxb。

?????? pxb主要對innodb引擎的表進行備份,同時也會全備份myisam表數據,原理大概是這樣:開啟讀取redo日志的線程,記錄備份期間數據的變化情況,同時記錄下此刻的lsn,然后以page為單位掃描出所有數據文件中page塊中lsn號小于等于之前記錄的lsn號的page,即找出了所有在備份期間沒有修改的page塊,同時加上讀取的redo日志內容,那么在數據恢復的時候,通過備份文件加上日志文件即可恢復出完整的innodb引擎數據。

?????? 本篇主要說mysqldump,重新認識下mysqldump這個常用的工具。mysqldump是mysql自帶的邏輯備份工具,多用于數據量較小的庫做整庫備份,把數據結構和內容以語句的形式備份成便于執行的sql文件,數據遷移相對簡單,數據量小的時候也非常快捷。(數據量在百G以內可以使用)

??????? 這里不多介紹具體的命令,我們重點關注mysqldump如何在數據導出過程中保持某個時點的數據一致性,也就是說在導出所有數據,均是這一時點的數據,不會因為表在導出過程中,其他dml操作對導出數據造成影響。

?????? 直接給出生產中使用備份命令:

mysqldump -ubacker -p --default-character-set=utf8? --single-transaction --flush-logs --master-dat

a=2 --databases test1 test2 test3 | gzip > $backupdir/full_iTOU_$time.sql.gz

重點關注 --single-transaction --flush-logs --master-data=2 這三個選項

官方手冊中對single-transaction

--single-transaction

This option sets the transaction isolation mode to REPEATABLE READ and sends a START TRANSACTION SQL statement to the server before dumping data. It is useful only with transactional tables such as InnoDB, because then it dumps the consistent state of the database at the time when START TRANSACTION was issued without blocking any applications.

這個選項做了兩件事情,1是設置了事務的隔離級別為可重復讀,2是啟動了事務;起到的作用就是:對于innoDB,保證了導出數據的一致性,并且不會阻塞應用系統。

When using this option, you should keep in mind that only InnoDB tables are dumped in a consistent state. For example, any MyISAM or MEMORY tables dumped while using this option may still change state.

這個選項能夠保證導出InnoDB引擎的表是一致性的狀態,其他引擎MyISAM或者MEMORY表的導出數據仍然可能不是一致性狀態的。

While a --single-transaction dump is in process, to ensure a valid dump file (correct table contents and binary log coordinates), no other connection should use the following statements: ALTER TABLE, CREATE TABLE, DROP TABLE, RENAME TABLE, TRUNCATE TABLE. A consistent read is not isolated from those statements, so use of them on a table to be dumped can cause the SELECT that is performed by mysqlpump to retrieve the table contents to obtain incorrect contents or fail.

在導出數據的過程中,需要保證dump文件的有效性;因為ALTER TABLE, CREATE TABLE, DROP TABLE, RENAME TABLE, TRUNCATE TABLE 這些DDL語句會改變表結構,一致性讀并不會對隔離這些語句,那么這些語句會導致導出數據不正確或者失敗。

那我們使用--single-transaction,并開啟general日志,看看具體都做了什么操作。

tips:在研究mysql后臺操作時,可以把詳細日志開啟,以便獲取更細致的信息。


Query SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ

設置隔離級別為可重復讀


Query START TRANSACTION /*!40100 WITH CONSISTENT SNAPSHOT */

開啟事物并且設置一致性快照,在這個transaction中所有的查詢均能得到同一版本的數據,通過MVCC來實現。

注意:

(1)此刻打開其他session對表做DML操作:例如,表中有100萬行數據,delete這個表的所有數據,然后再插入100萬行數據,正常情況下表空間大小應該和原空間大小差不多;但這個時候的因為插入100萬數據,會增加幾乎一倍,也就是說實際上物理上100萬行數據因為有session需要,并未真正的在磁盤中刪除。

也就是通過mvcc的數據的快照版本會存放在自身的數據表空間里,在未真正失去作用之前,會一直保留。

另外與ORACLE數據庫做對比,已刪除數據的快照從UNDO表空間去獲取,如果UNDO表空間內數據被覆蓋無法找到,則會報錯到前端,ORA-01555快照過久

(2)此時并不會對表結構做保護,如果對表做ddl操作,會導致導出報錯。

mysqldump: Couldn't execute 'show create table `z_test`': Table 'test.z_test' doesn't exist (1146)


再看看--single-transaction --master-data=2

官方手冊中master-data 參數的解釋:

Use this option to dump a master replication server to produce a dump file that can be used to set up another server as a slave of the master. It causes the dump output to include a CHANGE MASTER TO statement that indicates the binary log coordinates (file name and position) of the dumped server. These are the master server coordinates from which the slave should start replicating after you load the dump file into the slave.

If the option value is 2, the CHANGE MASTER TO statement is written as an SQL comment, and thus is informative only; it has no effect when the dump file is reloaded. If the option value is 1, the statement is not written as a comment and takes effect when the dump file is reloaded. If no option value is specified, the default value is 1.

This option requires the RELOAD privilege and the binary log must be enabled.

The --master-data option automatically turns off --lock-tables. It also turns on --lock-all-tables, unless --single-transaction also is specified, in which case, a global read lock is acquired only for a short time at the beginning of the dump (see the description for --single-transaction). In all cases, any action on logs happens at the exact moment of the dump.

It is also possible to set up a slave by dumping an existing slave of the master, using the --dump-slave option, which overrides --master-data and causes it to be ignored if both options are used.

使用這個選項備份出的文件可以做用來搭建slave,輸出的dump文件中有change master to的語句,包含二進制日志文件的坐標,用來告訴slave該從哪里開始進行日志的復制。

如果選項值是2,這條語句會被加注釋;如果選項值是1,則語句沒注釋,還原的時候會被執行;

使用此選項,會默認關閉--lock-tables和--lock-all-tables選項。

為了確保備份出來的數據在某一個時點的一致性,可以通過兩種方式來實現:

(1)先對所有表加讀鎖,備份數據,等待備份數據結束后,解開讀鎖。

主要通過flush table with read lock來實現,FTWRL三個步驟

1.上全局讀鎖(lock_global_read_lock)

2.清理表緩存(close_cached_tables)

3.上全局COMMIT鎖(make_global_read_lock_block_commit)

(2)先對所有表加讀鎖,設置隔離級別為可重復讀,開啟事物,解鎖,備份數據。

因為開啟了事務,查詢結果的一致性可以通過MVCC多版本并發控制來實現。

那么實際上持有讀鎖的時間會非常短,也就是通常 --single-transaction 加--master-data聯合使用的原因。

第一種方法會加MDL 元數據鎖,備份期間所有表的DML,DDL均無法執行。

第二種方法通過MVCC來實現,備份期間可以對表執行DDL操作,可能會導致整體數據結構不一致。

值得注意的是 flush table 是個比較重的動作,可能會引起問題,例如:

SESSION a:一個大表的查詢正在執行,

SESSION b:執行flush table命令,需要等待查詢結束后做再表緩存的清理,此時等待狀態為(Waiting for table flush)

這時如果有第三個session查詢查詢此表,則同樣會被阻塞,等待狀態為(Waiting for table flush)

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容