mysql 鎖的機制

鎖的認識

1.1 鎖的解釋

計算機協調多個進程或線程併發訪問某一資源的機制

1.2 鎖的重要性

在數據庫中,除傳統計算資源(CPU、RAM、I\O等)的爭搶,數據也是一種供多用戶共享的資源。 如何保證數據併發訪問的一致性,有效性,是全部數據庫必需要解決的問題。 鎖衝突也是影響數據庫併發訪問性能的一個重要因素,所以鎖對數據庫尤爲重要。

1.3 鎖的缺點

加鎖是消耗資源的,鎖的各類操做,包括得到鎖、檢測鎖是否已解除、釋放鎖等 ,都會增長系統的開銷。

鎖的類型

2.1 表鎖

種類

讀鎖(read lock),也叫共享鎖(shared lock)
針對同一份數據,多個讀操做能夠同時進行而不會互相影響(select)
寫鎖(write lock),也叫排他鎖(exclusive lock)
當前操做沒完成以前,會阻塞其它讀和寫操做(update、insert、delete)
 

存儲引擎默認鎖   : MyISAM

特色

1. 對整張表加鎖 2. 開銷小 3. 加鎖快 4. 無死鎖 5. 鎖粒度大,發生鎖衝突機率大,併發性低

結論

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

2.2 行鎖

種類

讀鎖(read lock),也叫共享鎖(shared lock)
容許一個事務去讀一行,阻止其餘事務得到相同數據集的排他鎖
若事務T對數據對象A加上S鎖,則事務T能夠讀A但不能修改A,其餘事務只能再對A加S鎖,而不能加X鎖,直到T釋放A上的S鎖。這保證了其餘事務能夠讀A,但在T釋放A上的S鎖以前不能對A作任何修改。
寫鎖(write lock),也叫排他鎖(exclusive lock)
容許得到排他鎖的事務更新數據,阻止其餘事務取得相同數據集的共享鎖和排他鎖
若事務T對數據對象A加上X鎖,事務T能夠讀A也能夠修改A,其餘事務不能再對A加任何鎖,直到T釋放A上的鎖。
排他鎖指的是一個事務在一行數據加上排他鎖後,其餘事務不能再在其上加其餘的鎖。mysql InnoDB引擎默認的修改數據語句
update,delete,insert都會自動給涉及到的數據加上排他鎖,select語句默認不會加任何鎖類型,若是加排他鎖能夠使用select …for update語句,加共享鎖能夠使用select … lock in share mode語句。
因此加過排他鎖的數據行在其餘事務種是不能修改數據的,也不能經過for update和lock in share mode鎖的方式查詢數據,但能夠直接經過select …from…查詢數據,由於普通查詢沒有任何鎖機制。
意向共享鎖(IS) 一個事務給一個數據行加共享鎖時,必須先得到表的IS鎖
意向排它鎖(IX) 一個事務給一個數據行加排他鎖時,必須先得到該表的IX鎖

存儲引擎默認鎖 :InnoDB

特色

1. 對一行數據加鎖 2. 開銷大 3. 加鎖慢 4. 會出現死鎖 5. 鎖粒度小,發生鎖衝突機率最低,併發性高
 

事務併發帶來的問題



1. 更新丟失 解決:讓事務變成串行操做,而不是併發的操做,即對每一個事務開始---對讀取記錄加排他鎖 2. 髒讀 解決:隔離級別爲Read uncommitted 3. 不可重讀 解決:使用Next-Key Lock算法來避免 4. 幻讀 解決:間隙鎖(Gap Lock)

如何上鎖?

 

3.1 表鎖

 

隱式上鎖(默認,自動加鎖自動釋放)

select //上讀鎖
insert、update、delete //上寫鎖
 

顯式上鎖(手動)

lock table tableName read;//讀鎖 lock table tableName write;//寫鎖
 

解鎖(手動)

unlock tables;//全部鎖表

3.2 行鎖

 

隱式上鎖(默認,自動加鎖自動釋放)

select //不會上鎖
insert、update、delete //上寫鎖
 

顯式上鎖(手動)

select * from tableName lock in share mode;//讀鎖 select * from tableName for update;//寫鎖
 

解鎖(手動)

1. 提交事務(commit) 2. 回滾事務(rollback) 3. kill 阻塞進程

優化建議

1. 儘量讓全部數據檢索都經過索引來完成,避免無索引行鎖升級爲表鎖 2. 合理設計索引,儘可能縮小鎖的範圍 3. 儘量較少檢索條件,避免間隙鎖 4. 儘可能控制事務大小,減小鎖定資源量和時間長度 5. 儘量低級別事務隔離

死鎖

 

6.1 解釋

指兩個或者多個事務在同一資源上相互佔用,並請求鎖定對方佔用的資源,從而致使惡性循環的現象
 

6.2 產生的條件

1. 互斥條件:一個資源每次只能被一個進程使用 2. 請求與保持條件:一個進程因請求資源而阻塞時,對已得到的資源保持不放 3. 不剝奪條件:進程已得到的資源,在沒有使用完以前,不能強行剝奪 4. 循環等待條件:多個進程之間造成的一種互相循環等待的資源的關係
 

6.1 解決

1. 查看死鎖:show engine innodb status \G 2. 自動檢測機制,超時自動回滾代價較小的事務(innodb_lock_wait_timeout 默認50s) 3. 人爲解決,kill阻塞進程(show processlist) 4. wait for graph 等待圖(主動檢測)
 

6.1 如何避免

1. 加鎖順序一致,儘量一次性鎖定所需的數據行 2. 儘可能基於primary(主鍵)或unique key更新數據 3. 單次操做數據量不宜過多,涉及表儘可能少 4. 減小表上索引,減小鎖定資源 5. 儘可能使用較低的隔離級別 6. 儘可能使用相同條件訪問數據,這樣能夠避免間隙鎖對併發的插入影響 7. 精心設計索引,儘可能使用索引訪問數據 8. 藉助相關工具:pt-deadlock-logger
相關文章
相關標籤/搜索