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

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

根據加鎖的範圍,MySQL裏大體能夠分爲三種鎖:全局鎖、表鎖和行鎖。接下來咱們會分三講來介紹這三種鎖,今天要講的是全局鎖。mysql

全局鎖

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

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

經過FTWRL加全局鎖

經過FTWRL確保不會有其餘線程對數據庫作更新,而後對整個庫作備份。注意,在備份過程當中整個庫徹底處於只讀狀態。併發

  • 若是在主庫上備份。那麼在備份期間都不能執行更新。
  • 若是在從庫上備份。那麼在備份期間,從庫不能執行主庫同步過來的 binlog,從而形成主從延時。

在備份過程當中數據庫沒法寫,這對業務會有很大的影響,爲何要加鎖呢,不加鎖行不行呢?工具

咱們來看看不加鎖會怎樣。以銀行轉帳爲例。學習


圖1 備份同時在轉帳

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

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

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

在事務隔離的實現原理那一篇文章裏,咱們學習了事務隔離中的可重複讀隔離級別是可以獲得一致性視圖的。而一致性視圖可以確保數據的邏輯一致性。code

官方自帶的邏輯備份工具是 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狀態,這樣會致使整個庫長時間處於不可寫狀態,風險較高。
相關文章
相關標籤/搜索