mysql之行鎖

1.索引失效行鎖變表鎖



 

2.間隙鎖

前段時間系統老是出現insert死鎖,很是糾結。經過排查發現是間隙鎖!間隙鎖是innodb中行鎖的一種, 但是這種鎖鎖住的卻不止一行數據,他鎖住的是多行,是一個數據範圍。間隙鎖的主要作用是爲了防止出現幻讀,但是它會把鎖定範圍擴大,有時候也會給我們帶來麻煩,我們就遇到了。 在數據庫參數中, 控制間隙鎖的參數是:innodb_locks_unsafe_for_binlog, 這個參數默認值是OFF, 也就是啓用間隙鎖, 他是一個bool值, 當值爲true時表示disable間隙鎖。那爲了防止間隙鎖是不是直接將innodb_locaks_unsafe_for_binlog設置爲true就可以了呢? 不一定!而且這個參數會影響到主從複製及災難恢復, 這個方法還尚待商量。

間隙鎖的出現主要集中在同一個事務中先delete 後 insert的情況下, 當我們通過一個參數去刪除一條記錄的時候, 如果參數在數據庫中存在, 那麼這個時候產生的是普通行鎖, 鎖住這個記錄, 然後刪除, 然後釋放鎖。如果這條記錄不存在,問題就來了, 數據庫會掃描索引,發現這個記錄不存在, 這個時候的delete語句獲取到的就是一個間隙鎖,然後數據庫會向左掃描掃到第一個比給定參數小的值, 向右掃描掃描到第一個比給定參數大的值, 然後以此爲界,構建一個區間, 鎖住整個區間內的數據, 一個特別容易出現死鎖的間隙鎖誕生了。

舉個例子:
表task_queue
Id           taskId
1              2
3              9
10            20
40            41

開啓一個會話: session 1

sql> set autocommit=0;

   ##

取消自動提交


sql> delete from task_queue where taskId = 20;
sql> insert into task_queue values(20, 20);

在開啓一個會話: session 2

sql> set autocommit=0;

   ##

取消自動提交


sql> delete from task_queue where taskId = 25;
sql> insert into task_queue values(30, 25);

在沒有併發,或是極少併發的情況下, 這樣會可能會正常執行,在Mysql中, 事務最終都是穿行執行, 但是在高併發的情況下, 執行的順序就極有可能發生改變, 變成下面這個樣子:
sql> delete from task_queue where taskId = 20;
sql> delete from task_queue where taskId = 25;
sql> insert into task_queue values(20, 20);
sql> insert into task_queue values(30, 25);

這個時候最後一條語句:insert into task_queue values(30, 25); 執行時就會爆出死鎖錯誤。因爲刪除taskId = 20這條記錄的時候,20 --  41 都被鎖住了, 他們都取得了這一個數據段的共享鎖, 所以在獲取這個數據段的排它鎖時出現死鎖。

這種問題的解決辦法:前面說了, 通過修改innodb_locaks_unsafe_for_binlog參數來取消間隙鎖從而達到避免這種情況的死鎖的方式尚待商量, 那就只有修改代碼邏輯, 存在才刪除,儘量不去刪除不存在的記錄。

 

間隙鎖摘錄來源http://blog.csdn.net/andyxm/article/details/44810417

 

 

3.間隙鎖再次舉例,爲的是讓大家更清楚瞭解在什麼場景下,會產生間隙鎖

 

4.如何鎖定一行

select * from table where id = 2 for update;

預定某一行後,其他的操作會被阻塞,直到鎖定行的會話提交commit

 

5.查看行鎖

show status like 'innodb_row_lock%'

 

行鎖各狀態說明

Innodb_row_lock_current_waits:當前正在等待鎖定的數量;

Innodb_row_lock_time :等待總時長 重要

Innodb_row_lock_time_avg :每次等待所花平均時間; 重要

Innodb_row_lock_time_max:從系統啓動到現在等待最長的一次所花的時間;

Innodb_row_lock_waits :等待總次數   重要

 

 尤其是當等待次數很高,而且每次等待時長也不小的時候,我們就需要分享系統中爲什麼會有如此多的等待,然後根據分析結果着手指定優化計劃

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章