總結
對於MyISAM的表鎖,主要有以下幾點:
- 共享讀鎖(S)之間是兼容的,但共享讀鎖(S)和排他寫鎖(X)之間,以及排他寫鎖之間(X)是互斥的,也就是說讀和寫是串行的。
- 在一定條件下,MyISAM允許查詢和插入併發執行,我們可以利用這一點來解決應用中對同一表中查詢和插入的爭鎖問題。
- MyISAM默認的鎖調度機制是寫優先,這並不一定適合於所有應用中,用戶可以通過設置LOW_PRIPRITY_UPDATES參數,或在INSERT,UPDATE,DELETE語句中指定LOW_PRIORITY選項來調節寫鎖的爭用。
- 由於表鎖的鎖粒度大,讀取之間有是串行的,因此,如果更新操作較多,MySIAM表可能會出現嚴重的鎖等待,可以考慮InnoDB表來減少鎖衝突。
對於InnoDB表,主要有以下幾點
- InnoDB的行鎖是基於索引實現的,如果不通過索引訪問數據,InnoDB會使用表鎖。
- InnoDB使用間隙鎖的目的意識防止幻讀,以滿足相關隔離級別的要求。另一方面,是爲了滿足其回覆和複製的需要。
- 在不同的隔離級別下,InnoDB的鎖機制和一致性讀策略不同。
- MySQL的回覆和複製對InnoDB鎖機制和一致性讀策略也有較大的影響
- 鎖衝突甚至死鎖很難避免。
在瞭解innoDB的鎖特性後,用戶可以通過設計和SQL調整等措施減少鎖衝突和死鎖,包括:
- 儘量使用較低的隔離級別
- 精心設計索引,並儘量使用索引訪問數據,使枷鎖更精確,從而減少鎖衝突的機會。
- 選擇合理的事務大小,小事務發生鎖衝突的機率也更小。
- 給記錄集顯示加鎖時,最好一次性請求足夠級別的鎖。比如要修改數據的話,最好直接申請排他鎖,而不是共享鎖,修改時再請求排他鎖,這樣容易產生死鎖。
- 不同的程序訪問一組表時,應儘量約定以相同的順序訪問各表,對一個表而言,儘可能一固定的順序存取表中的行。這樣能減小死鎖的機會。
- 對於特定的事務,可以使用表鎖來提高處理速度或減少死鎖的可能。
一篇關於MySQL的存儲引擎的博客