mysql中InnoDB存儲引擎的行鎖和表鎖


Mysql的InnoDB存儲引擎支持事務,默認是行鎖。因為這個特性,所以數據庫支持高並發,但是如果InnoDB更新數據的時候不是行鎖,而是表鎖的話,那么其並發性會大打折扣,而且也可能導致你的程序出錯。

而導致行鎖變為表鎖的情況之一就是:

  SQL的更新(update)或者刪除(delete)語句中未使用到索引,導致在InnoDB在對數據進行相應操作的時候必須把整個表鎖起來進行檢索(表鎖)。而如果使用了索引的話,InnoDB只會通過索引條件檢索數據,而只鎖住索引對應的行(行鎖)。

下面記錄一下我遇到的問題:

  描述:

  1. 系統中有一個實時的定時任務,當有條件觸發的時候,會更新對應的表,就先叫其為A表;
  2. 但是同時有一個任務有時候會對A表有寫操作,因此當進行測試的時候,有時候會不固定的出“Lock wait timeout exceeded”的錯誤。

  當出現這個問題的時候,從很多的地方進行了分析,然后都無法得到正確的解決方案(因為描述1模塊不是我寫的,所以沒有去查看更新表的代碼操作)

  導致原因:

       在描述1中定時任務更新表A的時候,更新條件中沒有使用索引,導致當進行定時任務更新表的時候形成了表鎖。然后因為表A數據量比較大,檢索較慢,然后導致了描述2中對表A的寫操作的等鎖超時。

最常見的索引:

  • 主鍵:眾所周知,自帶最高效的索引屬性
  • 唯一索引:屬性值重復率為0,可以作為業務主鍵
  • 普通索引:屬性值重復率大於0,不能作為唯一指定條件

  注意:對於普通索引,“重復率”低時,甚至接近主鍵或者唯一索引的效果時,依然是行鎖;但是如果“重復率”高時,Mysql不會把這個普通索引當做索引,即會造成一個沒有索引的SQL,從而形成表鎖。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM