MySQL dba在平常工做中,數據備份絕對是工做頻度最高的工做內容之一。當你使用邏輯方式進行備份(mydumper,mysqldump)或物理方式進行備份(percona-xtrabackup),爲了保證數據的一致性,這兩種備份方式都會在備份過程當中執行 flush table with read lock 這個命令(**如下簡稱爲FTWRL**
),經過執行FTWRL,來對事務和非事務表來加table level級別的共享鎖,取得此時的gtid或者binlog偏移量,繼而獲得某一個時間點的備份數據。mysql
在過去的很長一段時間內,咱們作備份一直是按以上的方式來作的,那麼這種依靠FTWRL這種方式得到備份點的作法是否真的合理,對數據庫有什麼不良的影響嗎?sql
首先讓咱們來看下,FTWRL具體作了哪些事情,當flush tables with read lock這條命令在數據庫中被執行的時候,執行邏輯能夠分爲下面的幾個步驟:數據庫
步驟1、請求得到相關類型的 MDL lock,這裏咱們暫時稱之爲 FTWRL_MDL_LOCK. 步驟2、清空query cache中的內容(當前應該不多有人開啓這個功能了) 步驟3、FLUSH TABLES,將當前全部打開的table的fd關閉 步驟4、請求得到全局table-level lock
步驟5、上全局COMMIT鎖(make_global_read_lock_block_commit)
以上步驟,在某些db場景下會產生很是嚴重的問題,咱們如下面栗子說明:
當有很大的事務在進行的時候,此時FTWRL的步驟一,步驟二能夠完成,可是進行到步驟三的時候,因爲表相關的事務正在執行中,相應table的句柄被佔用,沒法進行flush table操做。ide
筆者當時在現網就遇到這種情景,當時使用的工具是mydumper,該工具在進行到FTWRL步驟的時候,在步驟三卡住了,此時工具hang在那裏,可是還誤覺得加鎖失敗,天然對業務不會形成影響,實際上步驟一,步驟二已經成功執行了,要命的是步驟一的FTWRL_MDL_LOCK對DML事務的排他的,因此在工具hang住的期間,其餘的後續DML事務都是被阻塞的 -_-工具
咱們發現FTWRL是一種很是重量級鎖,或者說採起了一些額外過分的動做。有很是大的可能失敗,好比很是大的事務正在執行,這時候會被阻塞;而阻塞的時候又會影響其餘的DML事務的執行,這時候是很危險的!spa
那是否有改良的更好方案呢,percona的回答的是確定的,在 5.6.16-64.0這個版本中,percona開始引入了兩個新的MDL類型的鎖,相應的引入了兩個新的備份命令code
> LOCK TABLES FOR BACKUP > LOCK BINLOG FOR BACKUP
執行該命令後,得到的新的MDL鎖會阻塞對非事務表的更新及全部DDL動做,此時其餘用戶能夠繼續更新inonodb引擎的表,可是沒法對myisam表進行更新動做。server
執行該命令後,若是加鎖成功,將會阻塞binglog的更新,此時全部的DML操做被阻塞。事務
那麼經過上面兩個命令在獲取一致性的數據備份相比以前用FTWRL,有什麼好處呢,咱們經過下面兩張圖能夠看到區別:v8
首先咱們看下在非percona-5.6.16-64.0版本中。xtrabackup的工做流程:
而後咱們看下percona-5.6.16-64.0版本及以上中,xtrabackup備份的流程是怎樣的:
從上面兩張圖咱們能夠總結以下:
一、使用FTWTRL備份的方式,若是myisam表數量衆多,或者當前有大事務在執行,FTWTRL處於等待或者FTWTRL保持,這個時間段期間,後續對innod的DML都將被阻塞,所以時間持續越長,對業務影響越大。
二、使用 lock tables for backup備份myisam表期間,對innodb的dml事務無影響,且加鎖過程不受當前是否有大事務正在執行的影響
咱們能夠發現使用 lock table和lock binlog來備份數據,不只能夠實現更輕量級的上鎖,而且能夠節約myisam備份期間對業務的寫操做影響,我在percona server的環境下試驗證瞭如下,能夠看到xtrabackup再也不使用FTWRL命令了
percona這個小的改動解決了以前長期以來熱備數據的問題,特別是非percona server 版本下的雲平用戶有的執着使用myisam引擎,在備份期間很是容易形成監控程序的寫入失敗,從而觸發告警,-_-。