Mysql系列之鎖機制

通常一個程序滿,從消耗的角度,一個是cpu,一個是IO,但有的時候mysql慢,是由於某條sql不當心把整個表給鎖了。mysql

什麼是鎖?

鎖是計算機協調多個進程或線程併發訪問某一資源的機制。
在數據庫中,除了傳統的計算機資源(如CPU,RAM,I/O)的爭用外,數據也是供不少用戶共享的資源。如何保證數據併發訪問的一致性,有效性是全部數據庫必須解決的一個問題,鎖衝突也是影響數據庫併發訪問性能的一個重要因素。程序員

鎖的分類?

從對數據操做的類型:分爲讀鎖/寫鎖sql

  • 讀鎖(共享鎖):針對同一份數據,多個讀操做能夠同時進行而不會互相影響
  • 寫鎖(排它鎖):當寫操做沒有完成前,會阻斷其它寫鎖和讀鎖

從對數據操做的粒度:分爲表鎖/行鎖數據庫

Mysql的三鎖

表鎖(偏讀)

1.特色:偏向MyISAM存儲引擎,開銷小,加鎖快,無死鎖;鎖定粒度大,發生鎖衝突的機率最高,併發度最低
2.案例分析:session

  • 加讀鎖
  1. session1獲取讀鎖,能夠讀取數據,session2也能夠讀取數據
  2. session1獲取讀鎖,能夠讀取數據,可是當要向表中插入數據時,會報錯,由於尚未釋放讀鎖,可是session2向表中插入數據時,會處於等待狀態,等session1釋放讀鎖後,session2的寫入操做就完成了
  • 加寫鎖
    1.session1加完寫鎖後,session1能夠對錶進行查詢,插入,更新等操做,而此時session2對該表進行讀或寫操做時都會被阻塞

3.案例總結
MyISAM在執行查詢語句以前,會自動給所涉及的表加讀鎖,在執行增改刪操做前,會自動給涉及的表加寫鎖
MyISAM表級鎖有兩種模式:併發

  • 表共享讀鎖
  • 表獨佔寫鎖

結論:性能

  1. 對MyISAM表的讀操做(加讀鎖),不會阻塞其它進程對同一表的讀請求,但會阻塞對同一表的寫請求。只有當讀鎖釋放後,纔會執行其它進程的寫操做
  2. 對MyISAM表進行寫操做(加寫鎖),會阻塞其它進程對同一表的讀和寫操做,只有當釋放了寫鎖時,纔會執行其它進程的讀寫操做

簡而言之就是,讀鎖會阻塞寫,但不會阻塞讀,而寫鎖會阻塞讀和寫優化

4.表鎖分析,如何排查鎖的狀況
看看哪些表被鎖了:show open tables;
如何分析表鎖定:能夠經過table_locks_waited和table_locks_immediate狀態變量來分析系統上的表鎖定
SQL:show status like 'table%';spa

  • table_locks_immediate:產生表級鎖定的次數,表示能夠當即獲取鎖的查詢次數,每當即得到取鎖值加1;
  • table_locks_waited:出現表級鎖定爭用而發生的等待次數(不能當即獲取鎖的次數,每等待一次鎖值加1),此值高則說明存在較嚴重的表級鎖徵用狀況;

另外,MyISAM的讀寫鎖調度是寫優先,這也是MyISAM不適合作寫爲主表的引擎。由於寫鎖後,其它線程不能作任何操做,大量的更新會使查詢很可貴到鎖,從而形成永遠阻塞線程

行鎖(偏寫)

1.特色:偏向InnoDB存儲引擎,開銷大,加鎖慢,有死鎖,鎖定力度小,發生鎖衝突的機率最低,併發度也最高
InnoDB與MyISAM二者的不一樣:一是支持事務,而是採用了行級鎖
2.併發事務處理帶來的問題

  • 更新丟失:兩個事務不知道彼此的存在,最後的更新覆蓋了由其它事務所作的更新,若是在一個程序員完成並提交事務以前,另外一個程序員不能訪問同一文件則能夠解決
  • 髒讀:事務A讀取到了事務B已修改但還沒有提交的數據,還在這個數據的基礎上作了操做,此時,若是事務B回滾,A讀取的數據無效,不符合一致性的要求
  • 不可重複讀:事務A讀取到了事務B已經提交的修改數據,不符合隔離性
  • 幻讀:事務A讀取到了事務B體提交的新增數據,不符合隔離性。幻讀和髒讀有點相似,髒讀是事務B裏面修改了數據,幻讀是事務B裏面新增了數據。

3.事務的隔離級別

clipboard.png

4.案例分析

5.無索引行鎖升級爲表鎖

6.間隙鎖的危害

7.分析行鎖定
經過檢查InnoDB_row_lock狀態變量來分析系統上的行鎖爭奪狀況
show status like 'innodb_row_lock%';

clipboard.png

8.優化建議

clipboard.png

頁鎖

clipboard.png

相關文章
相關標籤/搜索