05 難搞的mysql鎖

2021-10-21 03:38:19 字數 2178 閱讀 2296

為了盡可能提高資料庫的併發度,每次鎖定的資料範圍越小越好,理論上每次只鎖定當前操作的資料的方案會得到最大的併發度,但是管理鎖是很耗資源的事情(涉及獲取,檢查,釋放鎖等動作),因此資料庫系統需要在高併發響應和系統效能兩方面進行平衡,這樣就產生了「鎖粒度(lock granularity)」的概念。

innodb 實現了以下兩種型別的行鎖

為了允許行鎖和表鎖共存,實現多粒度鎖機制,innodb 還有兩種內部使用的意向鎖(intention locks),這兩種意向鎖都是表鎖

索引失效會導致行鎖變表鎖。比如 vchar 查詢不寫單引號的情況。

樂觀鎖與悲觀鎖是兩種併發控制的思想,可用於解決丟失更新問題

樂觀鎖會「樂觀地」假定大概率不會發生併發更新衝突,訪問、處理資料過程中不加鎖,只在更新資料時再根據版本號或時間戳判斷是否有衝突,有則處理,無則提交事務。用資料版本(version)記錄機制實現,這是樂觀鎖最常用的一種實現方式

悲觀鎖會「悲觀地」假定大概率會發生併發更新衝突,訪問、處理資料前就加排他鎖,在整個資料處理過程中鎖定資料,事務提交或回滾後才釋放鎖。另外與樂觀鎖相對應的,悲觀鎖是由資料庫自己實現了的,要用的時候,我們直接呼叫資料庫的相關語句就可以了。

問題:select for update有什麼含義,會鎖表還是鎖行還是其他?

innodb這種行鎖實現特點意味著:只有通過索引條件檢索資料,innodb才使用行級鎖,否則,innodb將使用表鎖!假設有個表單 products ,裡面有id跟name二個字段,id是主鍵。

select * from products where id='3' for update;

select * from products where id='3' and type=1 for update;

select * from products where id='-1' for update;
select * from products where name='mouse' for update;
select * from products where id<>'3' for update;
select * from products where id like '3' for update;
死鎖產生

檢測死鎖

資料庫系統實現了各種死鎖檢測和死鎖超時的機制。innodb儲存引擎能檢測到死鎖的迴圈依賴並立即返回乙個錯誤。

死鎖恢復

死鎖發生以後,只有部分或完全回滾其中乙個事務,才能打破死鎖,innodb目前處理死鎖的方法是,將持有最少行級排他鎖的事務進行回滾。所以事務型應用程式在設計時必須考慮如何處理死鎖,多數情況下只需要重新執行因死鎖回滾的事務即可。

外部鎖的死鎖檢測

發生死鎖後,innodb 一般都能自動檢測到,並使乙個事務釋放鎖並回退,另乙個事務獲得鎖,繼續完成事務。但在涉及外部鎖,或涉及表鎖的情況下,innodb 並不能完全自動檢測到死鎖, 這需要通過設定鎖等待超時引數 innodb_lock_wait_timeout 來解決

死鎖影響效能

死鎖會影響效能而不是會產生嚴重錯誤,因為innodb會自動檢測死鎖狀況並回滾其中乙個受影響的事務。在高併發系統上,當許多執行緒等待同乙個鎖時,死鎖檢測可能導致速度變慢。有時當發生死鎖時,禁用死鎖檢測(使用innodb_deadlock_detect配置選項)可能會更有效,這時可以依賴innodb_lock_wait_timeout設定進行事務回滾。

myisam避免死鎖

innodb避免死鎖

如果出現死鎖,可以用show engine innodb status;命令來確定最後乙個死鎖產生的原因。返回結果中包括死鎖相關事務的詳細資訊,如引發死鎖的 sql 語句,事務已經獲得的鎖,正在等待什麼鎖,以及被回滾的事務等。據此可以分析死鎖產生的原因和改進措施。

Python中 神奇又難搞的eval和exec

exec 可以執行字串中的python 動態執行python 也就是說exec可以執行複雜的python 而不像eval函式那樣只能計算乙個表示式的值。exec source,globals none,locals none,source 必選引數,表示需要被指定的python 它必須是字串或cod...

mysql的悲觀鎖 mysql悲觀鎖

1.create database lock test db 2.create user test 1 identified by 123456 3.grant all privileges on lock test db.to test 1 identified by 123456 4.flush...

mysql間隙鎖 mysql的間隙鎖

最近學習了mysql的各種鎖,有點暈,打算通過文章的方式捋一捋。在學習了mvcc後,我就想,他已經很好的解決了併發讀寫了,但我也知道innodb提供了多種型別的鎖,所以很好奇這些鎖有什麼用,為什麼這些鎖的功能是mvcc做不到的?本文討論的都是rr級別下的鎖 我先建立乙個表,並插入幾行資料,如下圖 插...