部分生產環境采用mysqldump –single-transaction的方式在夜間進行數據庫備份,而同事恰好在備份期間執行了alter table操作,操作部分成功部分失敗,為啥呢?
測試在MySQL 5.6.36上執行,該問題存在版本差異!
##========================================================================##
在mysqldump對single-transaction參數的解釋為:
Creates?a?consistent?snapshot?by?dumping?all?tables?in?a single?transaction.?Works?ONLY?for?tables?stored?in storage?engines?which?support?multiversioning?(currently only?InnoDB?does);?the?dump?is?NOT?guaranteed?to?be consistent?for?other?storage?engines. ?While?a --single-transaction?dump?is?in?process,?to?ensure?a valid?dump?file?(correct?table?contents?and?binary?log position),?no?other?connection?should?use?the?following statements:?ALTER?TABLE,?DROP?TABLE,?RENAME?TABLE, TRUNCATE?TABLE,?as?consistent?snapshot?is?not?isolated from?them. ?Option?automatically?turns?off?--lock-tables.
紅色字體部分是重點,但是看得有些迷糊,還是動手測試下。
根據《mysqldump的幾個主要選項探究》的介紹,我們備份執行的命令mysqldump –single-transaction –master-data相當于執行下面代碼:
FLUSH TABLES; FLUSH TABLES WITH READ LOCK;SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; START TRANSACTION WITH CONSISTENT SNAPSHOT; SHOW MASTER STATUS; UNLOCK TABLES; SHOW TABLES LIKE 'xxx'SET OPTION SQL_QUOTE_SHOW_CREATE=1SHWO CREATE TABLE 'xxx'SHOW FIELDS FROM 'xxx'SHOW TABLE STATUS LIKE 'xxx'SELECT /*!40001 SQL_NO_CACHE */ * FROM xxx QUIT
場景1:mysqldump開始但尚未備份到表tb001時,另外回話對表tb001進行alter操作,然后mysqldump對表tb001進行導出
alter操作順利完成,但是mysqldump操作失敗。
?
場景2:mysqldump開始備份并完成tb001的導出,在對其他表進行導出過程中,其他回話對表進行alter操作
alter table操作被阻塞直至mysqldump完成或失敗后退出。
?
使用mysqldump備份時,模擬場景2的環境,報錯信息為:
mysqldump: Error 1412: Table definition has changed, please retry transaction when dumping table `tb1002` at row: 0
查看導出文件,最后內容為:
-- -- Dumping data for table `tb1002`--LOCK TABLES `tb1002` WRITE;/*!40000 ALTER TABLE `tb1002` DISABLE KEYS */;
總結:?
single-transaction參數通過Innodb的多版本來獲得數據一致性,而ALTER TABLE, DROP TABLE, RENAME TABLE,TRUNCATE TABLE等操作會破壞數據一致性,兩種操作不能并發執行。
如果修改表操作在 ”mysqldump開啟后但還未導出修改表數據前“ 的時間段內開始,則修改表操作成功完成,而mysqldump會執行失敗;
如果修改表操作在 “mysqldum已導出修改表數據但還未結束mysqldump操作前”的時間段內開始,則修改表操作被阻塞,mysqldum能成功完成,在mysqldump操作完成后修改表操作方可正常執行。