mysql優化二之鎖機制 mysql提供了鎖機制和MVCC機制來保證併發操作的安全性,這裡主要討論鎖機制, MVCC見下篇文章 mysql的鎖按照鎖粒度可分為行鎖與表鎖,按照操作類型劃分可讀鎖和寫鎖 InnoDB存儲引擎支持表鎖和行鎖,預設鎖為行鎖,MyIsam只支持表鎖 鎖粒度越高則併發性越好 表 ...
mysql優化二之鎖機制
mysql提供了鎖機制和MVCC機制來保證併發操作的安全性,這裡主要討論鎖機制,
MVCC見下篇文章
mysql的鎖按照鎖粒度可分為行鎖與表鎖,按照操作類型劃分可讀鎖和寫鎖
InnoDB存儲引擎支持表鎖和行鎖,預設鎖為行鎖,MyIsam只支持表鎖
鎖粒度越高則併發性越好
表鎖
一、操作語法
1、 show open tables;查看資料庫中哪些表加了鎖
in-use為0則表示未加鎖
2、 lock table (table_name) read(write)
3、 unlock tables;解鎖
二、示例
1、 讀鎖
開了兩個mysql客戶端,左邊客戶端中給mytest資料庫中的test1表加了讀鎖
左客戶端執行讀操作,右客戶端執行讀操作,可以看到兩者都可以執行
對於同一資料庫中的其他表操作,左客戶端拒絕執行,右客戶端可以執行
- 對於被鎖住的表執行寫操作
左客戶端拒絕執行
右客戶端阻塞住
此時我們解鎖
可以看到右客戶端立即被釋放並正確執行操作
2、 寫鎖
給左客戶端test1表加上寫鎖
左客戶端讀/寫正常,右客戶端讀/寫均被阻塞
左客戶端讀/寫該資料庫中的其他表拒絕執行,右客戶端可以正常執行
行鎖
因為mysql預設的存儲引擎是InnoDB,而InnoDB預設為行鎖,我們要測試行鎖首先需要把mysql的自動提交關閉
行級鎖讀操作兩個客戶端互不影響
寫操作如果操作的不是同一行,也不影響,若操作的是同一行則後一個客戶端的請求被阻塞,直到前一個客戶端的請求提交
註意點
1、 間隙鎖
我們在左邊客戶端對id在(0,5]範圍內的數據做寫操作,但是由於數據表中沒有id為4的數據行,按理說右邊資料庫插入一個id為4的數據行不會被鎖住,但是事實表明它被鎖住了。這既是mysql的間隙鎖機制。因此我們在資料庫操作時其實應該避免這種間隙的產生,我們可以在表裡設置一個狀態位,當要刪除某一數據行時,可以選擇將該狀態位設置為無效而不是真正的刪除。
2、 索引失效
當where查詢條件沒有索引時,行鎖變表鎖
當where查詢條件有索引但是索引失效時,行鎖仍然變表鎖
當左客戶端在已經減了索引的loc列用int型來查找時,索引失效就會導致整張表被鎖住
行鎖變表鎖的原因:mysql的行鎖是用索引實現的
3、 如何鎖住一行
在select語句找出某一行之後加一個for update