這段時間一直在學習mysql資料庫,專案組一直用的是oracle,所以對mysql的了解也不深,本文主要是對mysql鎖的總結,
Mysql的鎖主要分為3大類:
表級鎖:存盤引擎為Myisam,鎖住整個表,特點是開銷小,加鎖快,鎖定力度大,發生鎖沖突的概率最高,并發度最低,
頁級鎖:存盤引擎為BDB,鎖住某一頁的資料(16kb左右),特點:開銷和枷鎖時間介于表級和行級之間;會出現死鎖,鎖定力度介于表鎖和行鎖之間,并發度一般,
行級鎖:存盤引擎為innodb,鎖住某一行的資料,特點:鎖的實作更加復雜,開銷大,加鎖速度慢,
根據以上特點,僅從鎖的角度來說:表級鎖更適合于以查詢為主,只有少量按索引條件更新資料的應用,如Web應用;而行級鎖則更適合于有大量按索引條件并發更新少量不同資料,同時又有并發查詢的應用,如一些在線事務處理(OLTP)系統,
接下來進行行級鎖的詳解,行級鎖主要分為以下7類:共享/排他鎖、意向鎖、記錄鎖、間隙鎖、臨建鎖、插入意向鎖、自增鎖,
共享/排他鎖:
共享鎖:又稱讀鎖,可以允許讀,但不能寫,共享鎖可以與共享鎖一起使用,陳述句:
select ... lock in share mode
排他鎖:又稱寫鎖,不能允許讀,也不能允許寫,排他鎖不能與其他所一起使用,陳述句:
select ... for update
在mysql中,update,delete,insert,alter這些寫的操作默認都會加上排他鎖,Select默認不會加任何鎖型別,一旦寫資料的任務沒有完成,資料是不能被其他任務讀取的,這對并發操作有較大的影響,
意向鎖:innoDB為了支持多粒度的鎖,即允許行級鎖和表級鎖共存,而引入意向鎖,意向鎖是指未來的某個時刻,事務可能要加共享/排他鎖,先提前宣告一個意向,這樣如果有人嘗試對全表進行修改,就不需要判斷表中的資料是否被加鎖了,只需要通過等待意向互斥鎖被釋放就行了,
意向共享鎖(IS):事務想要在獲得表中某些記錄的共享鎖,需要在表上先加意向共享鎖,
意向互斥鎖(IX):事務想要在獲得表中某些記錄的互斥鎖,需要在表上先加意向互斥鎖,
意向鎖其實不會阻塞全表掃描之外的任何請求,它們的主要目的是為了表示是否有人請求鎖定表中的某一行資料,
記錄鎖(RS):單個行記錄上的鎖,記錄鎖總是會鎖住索引記錄,如果innoDB存盤引擎表
在建立的時候沒有設定任何一個索引,那么innoDB存盤引擎會使用隱式的主鍵來進行鎖定,
間隙鎖(GR):間隙鎖鎖住記錄中的間隔,即范圍查詢的記錄,
Select * From user where id between 1 and 10 for update
這個腳本會鎖住1到10 的資料,以防止其他事務修改該區間的記錄;
間隙鎖的主要目的,就是為了防止其他事務在間隔中插入資料,以導致“不可重復讀”,如果把事務的隔離級別降級為讀提交(Read Committed, RC),間隙鎖則會自動失效
臨建鎖(next-key Locks):臨建鎖是記錄鎖和間隙鎖的組合,鎖的范圍既包含記錄又包含索引區間,默認情況下,innoDB使用臨建鎖來鎖定記錄,但當查詢的索引含有唯一屬性的時候,臨建鎖會進行優化,將其降級為記錄鎖,即僅鎖住索引本身,不是范圍,
臨鍵鎖的主要目的,也是為了避免幻讀(Phantom Read),如果把事務的隔離級別降級為RC,臨鍵鎖則也會失效,
插入意向鎖(insert intention locks):對已有資料行的修改和洗掉,必須加互斥鎖,對于資料的插入,加插入意向鎖,是專門針對于insert操作的,
自增鎖(auto-inc locks):是一種特殊的表級別的鎖,專門針對事務插入auto-increment型別的列,最簡單的情況,如果一個事務正在往表中插入記錄,所有其他事務的插入必須等待,以便第一個事務插入的行,是連續的主鍵值,
---------------------------------------------------------分界線--------------------------------------------------------------
接下看講一下其他的鎖:
死鎖:產生是因為執行緒鎖之間交替等待產生的,值兩個或兩個以上的事務在執行程序中,因爭奪資源而造成的一種相互等待的現象,
Mysql處理死鎖的方法:根據資料寫的資料量的大小來回滾小事務,
樂觀/悲觀鎖:
樂觀鎖:樂觀的假定大概率不會發生并發更新沖突,訪問,處理資料的程序中不加鎖,只在更新資料時根據版本號或時間戳判斷是否有沖突,有則處理,無責提交事務,
如果系統并發量非常大,悲觀鎖會帶來非常大的性能問題,選擇使用樂觀鎖,現在大部分應用屬于樂觀鎖
悲觀鎖:悲觀的假定大概率會發生并發更新沖突,訪問,處理資料前就加排他鎖,在整個資料處理程序中鎖定資料,事務提交或回滾后才釋放鎖,
優點:
悲觀并發控制實際上是“先取鎖再訪問”的保守策略,為資料處理的安全提供了保證,
缺點:
(a)在效率方面,處理加鎖的機制會讓資料庫產生額外的開銷,還有增加產生死鎖的機會;
(b) 在只讀型事務處理中由于不會產生沖突,也沒必要使用鎖,這樣做只能增加系統負載;還有會降低了并行性,一個事務如果鎖定了某行資料,其他事務就必須等待該事務處理完才可以處理那行數
建議:
- 控制事務的大小(操作寫的資料量)
- 使用鎖的時候盡量要配合與攜帶索引的欄位使用,避免升級為表鎖
- 范圍查詢,盡量減少基于范圍查詢的事務的大小
- 如果業務必須要使用鎖,鎖的沖突特別高的話,改為表鎖
- 可以根據專案自身的情況調節事務的innodb_flush_log_at_trx_commit
感謝以下博主的檔案支持:
https://www.cnblogs.com/volcano-liu/p/9890832.html
https://blog.csdn.net/bruceleenumberone/article/details/81865045
https://blog.csdn.net/qq_32679835/article/details/93745182
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/107779.html
標籤:MySQL
上一篇:MySQL第四課
下一篇:MySQL開發規范與使用技巧總結
