首頁>技術>

資料庫鎖設計的初衷是處理併發問題,這也是資料庫與檔案系統的最大區別。

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

全域性鎖

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

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

透過FTWRL加全域性鎖

透過FTWRL確保不會有其他執行緒對資料庫做更新,然後對整個庫做備份。注意,在備份過程中整個庫完全處於只讀狀態。

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

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

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

圖1 備份同時在轉賬

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

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

透過加全域性鎖會影響業務,那有更好的辦法嗎?

在事務隔離的實現原理那一篇文章裡,我們學習了事務隔離中的可重複隔離級別是能夠得到一致性檢視的。而一致性檢視能夠確保資料的邏輯一致性。

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

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

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

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

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

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

作者:大雜草

原文連結:https://www.cnblogs.com/liang24/p/14136898.html

16
最新評論
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • 記一次 TCP 全佇列溢位問題排查過程