mysqldump –single-transaction,但更新查詢正在等待備份
如果我使用 mysqldump –single-transaction,根據文件,它應該使用讀鎖刷新表以獲得一致的狀態,然後啟動事務並且沒有寫入器應該等待。
但是,我昨晚發現了以下情況:
摘自顯示完整程序列表:
數百個…
Command: Query Time: 291 State: Waiting for table flush Info: insert into db_external_notification.....
那麼這個:
Command: Query Time: 1204 State: Sending data Info: SELECT /*!40001 SQL_NO_CACHE */ * FROM `db_external_notification`
其餘執行緒處於睡眠狀態
有誰知道這些外掛在等什麼?我沒有看到任何 FLUSH 表或 DDL 或手冊中提到的任何可能導致查詢等待的內容。
完整的 mysqldump 命令
mysqldump --quick --add-drop-table --single-transaction --master-data=2 -uxx -pxx dbname
我猜 –quick 在這裡是多餘的,可能是早期的遺留物,這個腳本很舊,但不應該傷害任何東西
mysqldump的–single-transaction選項不起作用。它會導致 mysqldump 為所有被轉儲的表設置一個可重複的讀取事務。
FLUSH TABLES WITH READ LOCK;
從您的問題中,您說 mysqldump 的
db_external_notification
表 SELECT 將數百個 INSERT 命令保存到同一個表中。為什麼會這樣?最有可能的事情是鎖在gen_clust_index(更好地稱為聚集索引)上。此範例導致表的數據頁和索引頁共存。這些索引頁基於 PRIMARY KEY 或自動生成的 RowID 索引(如果沒有 PRIMARY KEY)。
您應該能夠通過執行並從gen_clust_index中查找具有排他鎖
SHOW ENGINE INNODB STATUS\G
的任何頁面來發現這一點。對帶有聚集索引的表執行 INSERT 操作需要排他鎖來處理 PRIMARY KEY 的 BTREE,以及 auto_increment 的序列化。我之前討論過這個現象
Aug 08, 2011
: InnoDB 死鎖是 INSERT/UPDATE/DELETE 獨有的嗎?Dec 22, 2011
: MySQL 死鎖 - 無法正常重啟?Dec 13, 2012
: MySQL InnoDB 在刪除時鎖定主鍵,即使在 READ COMMITTED更新 2014-07-21 15:03 EDT
請查看 PastBin 的第 614-617 行
mysql tables in use 1, locked 0 MySQL thread id 6155315, OS thread handle 0x85f11b70, query id 367774810 localhost root Sending data SELECT /*!40001 SQL_NO_CACHE */ * FROM `db_external_notification` Trx read view will not see trx with id >= 1252538405, sees < 1252538391
請注意,第 617 行說
Trx read view will not see trx with id >= 1252538405, sees < 1252538391
這告訴我什麼?您有一些帶有 auto_increment on 的 PRIMARY KEY
id
。
id
表的最大值db_external_notification
小於1252538391
啟動 mysqldump 時的最大值。當您從 中減去1252538391
時1252538405
,這意味著已嘗試了 14 個或更多 INSERT 命令。在內部,這需要移動該表的 auto_increment 至少 14 次。id
然而,由於管理這個差距,沒有任何東西可以送出甚至推入日誌緩衝區。現在,查看 PasteBin 中的程序列表。除非我記錯了,否則我看到 38 個 DB 連接在執行 INSERT(在 mysqldump 程序(程序 id
6155315
)之前 19 個,之後有 19 個)。由於管理 auto_increment 間隙,我確信其中有 14 個或更多連接被凍結。