MySQL鎖(一)全局鎖:如何做全庫的邏輯備份?


數據庫鎖設計的初衷是處理並發問題,這也是數據庫與文件系統的最大區別。

根據加鎖的范圍,MySQL里大致可以分為三種鎖:全局鎖、表鎖和行鎖。接下來我們會分三講來介紹這三種鎖,今天要講的是全局鎖。

全局鎖

全局鎖,顧名思義,就是對整個數據庫加鎖。MySQL 提供了一個加全局讀鎖的方法,命令是 Flush tables with read lock(FTWRL)。

全局鎖典型的應用場景是做全庫的邏輯備份

通過FTWRL加全局鎖

通過FTWRL確保不會有其他線程對數據庫做更新,然后對整個庫做備份。注意,在備份過程中整個庫完全處於只讀狀態。

  • 如果在主庫上備份。那么在備份期間都不能執行更新。
  • 如果在從庫上備份。那么在備份期間,從庫不能執行主庫同步過來的 binlog,從而造成主從延時。

在備份過程中數據庫無法寫,這對業務會有很大的影響,為什么要加鎖呢,不加鎖行不行呢?

我們來看看不加鎖會怎樣。以銀行轉賬為例。


圖1 備份同時在轉賬

當用戶A轉100給用戶B,如果在用戶A賬戶扣除了100,但還沒給用戶B賬戶增加100時,對賬戶表完成了備份,那此時備份數據與生產環境的數據出現不一致性。

也就是說,不加鎖的話,備份得到的庫不是一個邏輯時間點,這個視圖是邏輯不一致的。當進行備份還原時,用戶B賬戶就少了100,這就出現很嚴重的問題了。

通過加全局鎖會影響業務,那有更好的辦法嗎?

在事務隔離的實現原理那一篇文章里,我們學習了事務隔離中的可重復讀隔離級別是能夠得到一致性視圖的。而一致性視圖能夠確保數據的邏輯一致性。

官方自帶的邏輯備份工具是 mysqldump。當 mysqldump 使用參數 -single-transaction 的時候,導數據之前就會啟動一個事務,來確保拿到一致性視圖。而由於MVCC的支持,這個過程中數據是可以正常更新的。查看這篇文章,了解更多關於MVCC和一致性讀的內容。

有了一致性讀后,還需要 FTWRL 嗎?

一致性讀是好,但前提是引擎要支持這個隔離級別。比如,對於MyISAM這種不支持事務的引擎,如果備份過程中有更新,總是只能取到最新的數據,那么就破壞了備份的一致性。這時,我們就需要使用FTWRL命令了。

所以 -single-transaction 方法只適用於所有的表使用事務引擎的庫

既然要全庫只讀,為什么不使用set global readonly=true的方式呢?

雖然 readonly 也能夠設置全庫為只讀狀態。但還是建議使用 FTWRL,原因有兩個:

  1. 在有些系統中,readonly的值會被用來做其他邏輯,比如用來判斷一個庫是主庫還是備庫。因此,修改global變量的方式影響面更大,不建議你使用。
  2. 在異常處理機制上有差異。如果執行FTWRL命令之后由於客戶端發生異常斷開,那么MySQL會自動釋放這個全局鎖,整個庫回到可以正常更新的狀態。而將整個庫設置為readonly之后,如果客戶端發生異常,則數據庫就會一直保持readonly狀態,這樣會導致整個庫長時間處於不可寫狀態,風險較高。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM