MySQL 三種鎖


MySQL 三種鎖

全局鎖

Flush tables with read lock (FTWRL) 對整個數據庫加鎖,整個庫處於只讀狀態,之后的其他線程例如DML,DDL,TCL等語句將會被阻塞。

全局鎖的使用場景是做全庫邏輯備份,但讓整庫處於只讀狀態,會導致兩個問題。

  1. 如果你在主庫上備份,那么在備份期間都不能執行更新,業務基本上就得停擺
  2. 如果你在從庫上備份,那么備份期間從庫不能執行主庫同步過來的 binlog,會導致主從延遲

MySQL官方使用mysql dump -single-transaction,導數據之前會啟動一個事務,來確保拿到一致性視圖,不支持事務隔離的引擎如MyISAM,只能通過 FTWRL.

全庫只讀不使用set global readonly=true的原因:

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

表級鎖

1.表鎖

上鎖:lock tables ...read/write 解鎖:unlock tables。

unlock tables可以主動釋放鎖,也可以在客戶端斷開的時候自動釋放鎖。

lock tables,語法除了會限制線程的讀寫外,還會限定該線程接下來的操作對象。

2.元數據鎖(meta data lock)

不需要顯式使用,在訪問表時會自動加上,MDL的作用是保證讀寫的正確性。

當對一張表進行DML操作時會加MDL讀鎖,對表結構做操作時會加DML寫鎖。

  1. 讀鎖之間不互斥,可以多個線程同時對一張表進行增刪改查
  2. 讀寫鎖,寫鎖之間相互互斥,用來保證表結構操作的安全性。

事務中的MDL鎖,在語句開始執行時申請,但是語句結束后並不會馬上釋放,而是等整個事務提交后釋放。

如何安全的給小標加字段?

alter table 語句里面設定等待時間,如果在這個指定的等待時間里面能夠拿到 MDL 寫鎖最好,拿不到也不要阻塞后面的業務語句,先放棄。之后開發人員或者 DBA 再通過重試命令重復這個過程。

3.行鎖

MySQL行鎖在引擎層,由各個引擎自己實現,MyIsAM不支持行鎖。行鎖就是在表中行記錄的鎖。

兩階段鎖

在 InnoDB 事務中,行鎖是在需要的時候才加上的,但並不是不需要了就立刻釋放,而是要等到事務結束時才釋放。這個就是兩階段鎖協議。兩階段鎖,鎖的添加與釋放分到兩個階段進行,之間不允許交叉加鎖和釋放鎖。 也就是在事務開始執行后為涉及到的行按照需要加鎖,但執行完不會馬上釋放,而是在事務結束時再統一釋放他們。

如果你的事務中需要鎖多個行,要把最可能造成鎖沖突、最可能影響並發度的鎖盡量往后放

死鎖和死鎖檢測

當並發系統中不同線程出現循環資源依賴,涉及的線程都在等待別的線程釋放資源時,就會導致這幾個線程都進入無限等待的狀態,稱為死鎖。

出現死鎖后的策略

  1. 直接進入等待,直到超時。這個超時時間可以通過參數 innodb_lock_wait_timeout 來設置。
  2. 發起死鎖檢測,發現死鎖后,主動回滾死鎖鏈條中的某一個事務,讓其他事務得以繼續執行。將參數 innodb_deadlock_detect 設置為 on,表示開啟這個邏輯。

死鎖檢測的條件:如果要加鎖訪問 的行上 有鎖,他才要進行死鎖檢測。

  • 一致性讀不會加鎖,不會進行死鎖檢測
  • 並不是每次死鎖檢測都會掃描所有事務,比如現在有B在等A,D在等C,現在來了一個E,發現E需要等D,那么E就判斷跟D、C是否會形成死鎖,這個檢測不用管B和A

如果是我們上面說到的所有事務都要更新同一行的場景呢?

每個新來的被堵住的線程,都要判斷會不會由於自己的加入導致了死鎖,這是一個時間復雜度O(n^2)

怎么解決由這種熱點行更新導致的性能問題呢

  1. 如果你能確保這個業務一定不會出現死鎖,可以臨時把死鎖檢測關掉。風險太高,關掉死鎖檢測意味着可能會出現大量的超時,這是業務有損的
  2. 控制並發度:在數據庫服務器端做並發控制。如果有中間件,可以在中間件實現;如果可以修改MySQL源碼,也可以做在MySQL里面,對於相同行的更新,在進入引擎之前排隊。這樣在 InnoDB 內部就不會有大量的死鎖檢測工作了。
  3. 從邏輯上將一行拆分為多行,


免責聲明!

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



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