程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> MYSQL數據庫 >> MySQL綜合教程 >> Mysql查詢語句使用select.. for update導致的數據庫死鎖分析

Mysql查詢語句使用select.. for update導致的數據庫死鎖分析

編輯:MySQL綜合教程

Mysql查詢語句使用select.. for update導致的數據庫死鎖分析


近期有一個業務需求,多台機器需要同時從Mysql一個表裡查詢數據並做後續業務邏輯,為了防止多台機器同時拿到一樣的數據,每台機器需要在獲取時鎖住獲取數據的數據段,保證多台機器不拿到相同的數據。   我們Mysql的存儲引擎是innodb,支持行鎖。解決同時拿數據的方法有很多,為了更加簡單,不增加其他表和服務器的情況下,我們考慮采用select... for update的方式,這樣X鎖鎖住查詢的數據段,表裡其他數據沒有鎖,其他業務邏輯還是可以操作。   這樣一台服務器比如select .. for update limit 0,30時,其他服務器執行同樣sql語句會自動等待釋放鎖,等待前一台服務器鎖釋放後,該台服務器就能查詢下一個30條數據。如果達到更智能,oracle支持for update skip locked跳過鎖區域,這樣能不等待馬上查詢出下一個30條記錄。   這裡還是需要說mysql for update導致的死鎖。   經過分析,mysql的innodb存儲引擎實務鎖雖然是鎖行,但它內部是鎖索引的,根據where條件和select的值是否只有主鍵或非主鍵索引來判斷怎麼鎖,比如只有主鍵,則鎖主鍵索引,如果只有非主鍵,則鎖非主鍵索引,如果主鍵非主鍵都有,則內部會按照順序鎖。但同樣的select .. for update語句怎麼就死鎖了呢?同樣的sql語句查詢條件和結果順序都一致,按理不會導致一個鎖了主鍵索引,等待鎖非主鍵索引,另外一個鎖了非主鍵索引,等待主鍵索引導致的死鎖。   最後經過分析,發現是for update的sql語句,和另外一個update語句導致的死鎖。   比如有60條數據,select .. for update查詢第31-60條數據,update在更新1-10條數據,按照innodb存儲引擎的行鎖原理,應該不會導致不同行的鎖導致的互相等待。開始以為是行鎖在數據量較大情況下,會鎖數據塊。導致一個段的數據被鎖住,但經過大量數據測試,發現感覺把整個表都鎖住了,但實際不是。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved