MySQL死鎖問題的相關知識是本文我們主要要介紹的內容,接下來我們就來一一介紹這部分內容,希望能夠對您有所幫助。
1、MySQL常用存儲引擎的鎖機制
MyISAM和MEMORY採用表級鎖(table-level locking)
BDB採用頁面鎖(page-level locking)或表級鎖,默認為頁面鎖
InnoDB支持行級鎖(row-level locking)和表級鎖,默認為行級鎖
2、各種鎖特點
表級鎖:開銷小,加鎖快;不會出現死鎖;鎖定粒度大,發生鎖沖突的概率最高,並發度最低
行級鎖:開銷大,加鎖慢;會出現死鎖;鎖定粒度最小,發生鎖沖突的概率最低,並發度也最高
頁面鎖:開銷和加鎖時間界於表鎖和行鎖之間;會出現死鎖;鎖定粒度界於表鎖和行鎖之間,並發度一般
3、各種鎖的適用場景
表級鎖更適合於以查詢為主,只有少量按索引條件更新數據的應用,如Web應用
行級鎖則更適合於有大量按索引條件並發更新數據,同時又有並發查詢的應用,如一些在線事務處理系統
4、死鎖
是指兩個或兩個以上的進程在執行過程中,因爭奪資源而造成的一種互相等待的現象,若無外力作用,它們都將無法推進下去。
表級鎖不會產生死鎖。所以解決死鎖主要還是針對於最常用的InnoDB。
5、死鎖舉例分析
在MySQL中,行級鎖並不是直接鎖記錄,而是鎖索引。索引分為主鍵索引和非主鍵索引兩種,如果一條sql語句操作了主鍵索引,MySQL就會鎖定這條主鍵索引;如果一條語句操作了非主鍵索引,MySQL會先鎖定該非主鍵索引,再鎖定相關的主鍵索引。
在UPDATE、DELETE操作時,MySQL不僅鎖定WHERE條件掃描過的所有索引記錄,而且會鎖定相鄰的鍵值,即所謂的next-key locking。
例如,一個表db。tab_test,結構如下:
id:主鍵;
state:狀態;
time:時間;
索引:idx_1(state,time)
出現死鎖日誌如下:
?***(1) TRANSACTION:
?TRANSACTION 0 677833455, ACTIVE 0 sec, process no 11393, OSthread id 278546 starting index read
?mysql tables in use 1, locked 1
?LOCK WAIT 3 lock struct(s), heap size 320
?MySQL thread id 83, query id 162348740 dcnet03 dcnet Searching rows for update
?update tab_test set state=1064,time=now() where state=1061 and time < date_sub(now(), INTERVAL 30 minute) (任務1的sql語句)
?***(1) WAITING FOR THIS LOCK TO BE GRANTED: (任務1等待的索引記錄)
?RECORD LOCKS space id 0 page no 849384 n bits 208 index `PRIMARY` of table `db/tab_test` trx id 0 677833455 _mode X locks rec but not gap waiting
?Record lock, heap no 92 PHYSICAL RECORD: n_fields 11; compact format; info bits 0
?0: len 8; hex 800000000097629c; asc b ;; 1: len 6; hex 00002866eaee; asc (f ;; 2: len 7; hex 00000d40040110; asc @ ;; 3: len 8; hex 80000000000050b2; asc P ;; 4: len 8; hex 800000000000502a; asc P*;; 5: len 8; hex 8000000000005426; asc T&;; 6: len 8; hex 800012412c66d29c; asc A,f ;; 7: len 23; hex 8616e642e706870; asc xxx.com/;; 8: len 8; hex 800000000000042b; asc +;; 9: len 4; hex 474bfa2b; asc GK +;; 10: len 8; hex 8000000000004e24; asc N$;;
?*** (2) TRANSACTION:
?TRANSACTION 0 677833454, ACTIVE 0 sec, process no 11397, OS thread id 344086 updating or deleting, thread declared inside InnoDB 499
?mysql tables in use 1, locked 1
?3 lock struct(s), heap size 320, undo log entries 1
?MySQL thread id 84, query id 162348739 dcnet03 dcnet Updating update tab_test set state=1067,time=now () where id in (9921180) (任務2的sql語句)
?*** (2) HOLDS THE LOCK(S): (任務2已獲得的鎖)
?RECORD LOCKS space id 0 page no 849384 n bits 208 index `PRIMARY` of table `db/tab_test` trx id 0 677833454 lock_mode X locks rec but not gap
?Record lock, heap no 92 PHYSICAL RECORD: n_fields 11; compact format; info bits 0
?0: len 8; hex 800000000097629c; asc b ;; 1: len 6; hex 00002866eaee; asc (f ;; 2: len 7; hex 00000d40040110; asc @ ;; 3: len 8; hex 80000000000050b2; asc P ;; 4: len 8; hex 800000000000502a; asc P*;; 5: len 8; hex 8000000000005426; asc T&;; 6: len 8; hex 800012412c66d29c; asc A,f ;; 7: len 23; hex 8616e642e706870; asc uploadfire.com/hand.php;; 8: len 8; hex 800000000000042b; asc +;; 9: len 4; hex 474bfa2b; asc GK +;; 10: len 8; hex 8000000000004e24; asc N$;;
?*** (2) WAITING FOR THIS LOCK TO BE GRANTED: (任務2等待的鎖)
?RECORD LOCKS space id 0 page no 843102 n bits 600 index `idx_1` of table `db/tab_test` trx id 0 677833454 lock_mode X locks rec but not gap waiting
?Record lock, heap no 395 PHYSICAL RECORD: n_fields 3; compact format; info bits 0
?0: len 8; hex 8000000000000425; asc %;; 1: len 8; hex 800012412c66d29c; asc A,f ;; 2: len 8; hex 800000000097629c; asc b ;;
?*** WE ROLL BACK TRANSACTION (1)
?(回滾了任務1,以解除死鎖)
原因分析:
當「update tab_test set state=1064,time=now() where state=1061 and time < date_sub(now(), INTERVAL 30 minute)」執行時,MySQL會使用idx_1索引,因此首先鎖定相關的索引記錄,因為idx_1是非主鍵索引,為執行該語句,MySQL還會鎖定主鍵索引。
假設「update tab_test set state=1067,time=now () where id in (9921180)」幾乎同時執行時,本語句首先鎖定主鍵索引,由於需要更新state的值,所以還需要鎖定idx_1的某些索引記錄。
這樣第一條語句鎖定了idx_1的記錄,等待主鍵索引,而第二條語句則鎖定了主鍵索引記錄,而等待idx_1的記錄,這樣死鎖就產生了。
6、解決辦法
拆分第一條sql,先查出符合條件的主鍵值,再按照主鍵更新記錄:
?select id from tab_test where state=1061 and time < date_sub(now(), INTERVAL 30 minute);
?update tab_test state=1064,time=now() where id in(......);
2. sqldeveloper怎麼殺死死鎖的表
嘗試在sqlplus中通過sql命令進行刪除,如果能夠刪除成功,則萬事大吉。
但通常情況下,出現死鎖時,想通過命令行或者通過oracle的管理工具刪除有死鎖的session,oracle只會將該session標記為killed,但無法清除掉,往往需要通過第二步在操作系統層級進行刪除。
altersystemkillsession29,57107。--刪除進程,如已經刪除過,則會報ora-00031的錯誤,否則oracle會將該session標記為killed狀態,等待一段時間看能否會自動消失,如長時間消失不掉,則需要做後續步驟。一些ORACLE中的進程被殺掉後,狀態被置為killed,但是鎖定的資源很長時間不釋放,有時實在沒辦法,只好重啟資料庫。現在提供一種方法解決這種問題,那就是在ORACLE中殺不掉的,在OS一級再殺。
3. SQL資料庫總是假死或死鎖。
建議:
1、使用事件探查器,跟蹤一下SQL在死鎖之前執行了哪些SQL語句
2、多數死鎖是因為程序沒有經過嚴格的測試造成的
3、少部分原因是因為觸發器嵌套造成的,SQL有內部機制,當嵌套到一定的層級,就自動終止掉相關的進程
願早日解決問題
4. 如何解除sql server資料庫數據被鎖定
1.2 事務的ACID原則
1.3 鎖是關系資料庫很重要的一部分, 資料庫必須有鎖的機制來確保數據的完整和一致性. 1.3.1 SQL Server中可以鎖定的資源:
1.3.2 鎖的粒度:
1.3.3 鎖的升級: 鎖的升級門限以及鎖升級是由系統自動來確定的,不需要用戶設置. 1.3.4 鎖的類型: (1) 共享鎖: 共享鎖用於所有的只讀數據操作. (2) 修改鎖: 修改鎖在修改操作的初始化階段用來鎖定可能要被修改的資源,這樣可以避免使用共享鎖造成的死鎖現象 (3) 獨占鎖: 獨占鎖是為修改數據而保留的。它所鎖定的資源,其他事務不能讀取也不能修改。獨占鎖不能和其他鎖兼容。 (4) 架構鎖 結構鎖分為結構修改鎖(Sch-M)和結構穩定鎖(Sch-S)。執行表定義語言操作時,SQL Server採用Sch-M鎖,編譯查詢時,SQL Server採用Sch-S鎖。 (5) 意向鎖 意向鎖說明SQL Server有在資源的低層獲得共享鎖或獨占鎖的意向。 (6) 批量修改鎖 批量復制數據時使用批量修改鎖 1.3.4 SQL Server鎖類型 (1) HOLDLOCK: 在該表上保持共享鎖,直到整個事務結束,而不是在語句執行完立即釋放所添加的鎖。 (2) NOLOCK:不添加共享鎖和排它鎖,當這個選項生效後,可能讀到未提交讀的數據或「臟數據」,這個選項僅僅應用於SELECT語句。 (3) PAGLOCK:指定添加頁鎖(否則通常可能添加表鎖)。 (4) READCOMMITTED用與運行在提交讀隔離級別的事務相同的鎖語義執行掃描。默認情況下,SQL Server 2000 在此隔離級別上操作。 (5) READPAST: 跳過已經加鎖的數據行,這個選項將使事務讀取數據時跳過那些已經被其他事務鎖定的數據行,而不是阻塞直到其他事務釋放鎖, READPAST僅僅應用於READ COMMITTED隔離性級別下事務操作中的SELECT語句操作。 (6) READUNCOMMITTED:等同於NOLOCK。 (7) REPEATABLEREAD:設置事務為可重復讀隔離性級別。 (8) ROWLOCK:使用行級鎖,而不使用粒度更粗的頁級鎖和表級鎖。
5. 如何處理SQL Server死鎖問題
1)
預防死鎖。
這是一種較簡單和直觀的事先預防的方法。方法是通過設置某些限制條件,去破壞產生死鎖的四個必要條件中的一個或者幾個,來預防發生死鎖。預防死鎖是一種較易實現的方法,已被廣泛使用。但是由於所施加的限制條件往往太嚴格,可能會導致系統資源利用率和系統吞吐量降低。
2)
避免死鎖。
該方法同樣是屬於事先預防的策略,但它並不須事先採取各種限制措施去破壞產生死鎖的的四個必要條件,而是在資源的動態分配過程中,用某種方法去防止系統進入不安全狀態,從而避免發生死鎖。
3)檢測死鎖。
這種方法並不須事先採取任何限制性措施,也不必檢查系統是否已經進入不安全區,此方法允許系統在運行過程中發生死鎖。但可通過系統所設置的檢測機構,及時地檢測出死鎖的發生,並精確地確定與死鎖有關的進程和資源,然後採取適當措施,從系統中將已發生的死鎖清除掉。
4)解除死鎖。
這是與檢測死鎖相配套的一種措施。當檢測到系統中已發生死鎖時,須將進程從死鎖狀態中解脫出來。常用的實施方法是撤銷或掛起一些進程,以便回收一些資源,再將這些資源分配給已處於阻塞狀態的進程,使之轉為就緒狀態,以繼續運行。死鎖的檢測和解除措施,有可能使系統獲得較好的資源利用率和吞吐量,但在實現上難度也最大。
由上面4中處理死鎖的辦法看,其中檢測死鎖和解除死鎖是Lock
Monitor的事,作為DBA或資料庫開發人員,處理死鎖要放在預防和避免死鎖上。
預防死鎖
預防死鎖就是破壞四個必要條件中的某一個和幾個,使其不能形成死鎖。有如下幾種辦法
1)破壞互斥條件
破壞互斥條件有比較嚴格的限制,在SQL
Server中,如果業務邏輯上允許臟讀,則可以通過將隔離等級改為未提交讀或使用索引提示。這樣使得讀取不用加S鎖,從而避免了和其它查詢所加的與S鎖不兼容的鎖互斥,進而減少了死鎖出現的概率。
2)破壞請求和等待條件
這點由於事務存在原子性,是不可破壞的,因為解決辦法是盡量的減少事務的長度,事務內執行的越快越好。這也可以減少死鎖出現的概率。
3)破壞不剝奪條件
由於事務的原子性和一致性,不剝奪條件同樣不可破壞。但我們可以通過增加資源和減少資源佔用兩個角度來考慮。
增加資源:比如說通過建立非聚集索引,使得有了額外的資源,查詢很多時候就不再索要鎖基本表,轉而鎖非聚集索引,如果索引能夠「覆蓋(Cover)」查詢,那更好不過。因此索引Include列不僅僅減少書簽查找來提高性能,還能減少死鎖。增加資源還可以通過SQL
Server
2005之後的行版本控制進行,但這種方式並不推薦,在此不再詳細討論。
減少資源佔用:比如說查詢時,能用select
col1,col2這種方式,就不要用select
*
.這有可能帶來不必要的書簽查找
6. 怎麼樣解決MSSQL產生死鎖的問題
一、 什麼是死鎖
死鎖是指兩個或兩個以上的進程在執行過程中,因爭奪資源而造成的一種互相等待的現象,若無外力作用,它們都將無法推進下去.此時稱系統處於死鎖狀態或系統產生了死鎖,這些永遠在互相等的進程稱為死鎖進程.
二、 死鎖產生的四個必要條件
互斥條件:指進程對所分配到的資源進行排它性使用,即在一段時間內某資源只由一個進程佔用。如果此時還有其它進程請求資源,則請求者只能等待,直至佔有資源的進程用畢釋放
請求和保持條件:指進程已經保持至少一個資源,但又提出了新的資源請求,而該資源已被其它進程佔有,此時請求進程阻塞,但又對自己已獲得的其它資源保持不放
不剝奪條件:指進程已獲得的資源,在未使用完之前,不能被剝奪,只能在使用完時由自己釋放
環路等待條件:指在發生死鎖時,必然存在一個進程——資源的環形鏈,即進程集合{P0,P1,P2,···,Pn}中的P0正在等待一個P1佔用的資源;P1正在等待P2佔用的資源,……,Pn正在等待已被P0佔用的資源
這四個條件是死鎖的必要條件,只要系統發生死鎖,這些條件必然成立,而只要上述條件之一不滿足,就不會發生死鎖。
三、 如何處理死鎖
1) 鎖模式
共享鎖(S)
由讀操作創建的鎖,防止在讀取數據的過程中,其它事務對數據進行更新;其它事務可以並發讀取數據。共享鎖可以加在表、頁、索引鍵或者數據行上。在SQL SERVER默認隔離級別下數據讀取完畢後就會釋放共享鎖,但可以通過鎖提示或設置更高的事務隔離級別改變共享鎖的釋放時間。
2.獨占鎖(X)
對資源獨占的鎖,一個進程獨佔地鎖定了請求的數據源,那麼別的進程無法在此數據源上獲得任何類型的鎖。獨占鎖一致持有到事務結束。
3.更新鎖(U)
更新鎖實際上並不是一種獨立的鎖,而是共享鎖與獨占鎖的混合。當SQL SERVER執行數據修改操作卻首先需要搜索表以找到需要修改的資源時,會獲得更新鎖。
更新鎖與共享鎖兼容,但只有一個進程可以獲取當前數據源上的更新鎖,
其它進程無法獲取該資源的更新鎖或獨占鎖,更新鎖的作用就好像一個序列化閥門(serialization gate),將後續申請獨占鎖的請求壓入隊列中。持有更新鎖的進程能夠將其轉換成該資源上的獨占鎖。更新鎖不足以用於更新數據—實際的數據修改仍需要用到獨占鎖。對於獨占鎖的序列化訪問可以避免轉換死鎖的發生,更新鎖會保留到事務結束或者當它們轉換成獨占鎖時為止。
4. 意向鎖(IX,IU,IS)
意向鎖並不是獨立的鎖定模式,而是一種指出哪些資源已經被鎖定的機制。
如果一個表頁上存在獨占鎖,那麼另一個進程就無法獲得該表上的共享表鎖,這種層次關系是用意向鎖來實現的。進程要獲得獨占頁鎖、更新頁鎖或意向獨占頁鎖,首先必須獲得該表上的意向獨占鎖。同理,進程要獲得共享行鎖,必須首先獲得該表的意向共享鎖,以防止別的進程獲得獨占表鎖。
5. 特殊鎖模式(Sch_s,Sch_m,BU)
SQL SERVER提供3種額外的鎖模式:架構穩定鎖、架構修改鎖、大容量更新鎖。
6.轉換鎖(SIX,SIU,UIX)
轉換鎖不會由SQL SERVER 直接請求,而是從一種模式轉換到另一種模式所造成的。SQL SERVER 2008支持3種類型的轉換鎖:SIX、SIU、UIX.其中最常見的是SIX鎖,如果事務持有一個資源上的共享鎖(S),然後又需要一個IX鎖,此時就會出現SIX。
7.鍵范圍鎖
鍵范圍鎖是在可序列化隔離級別中鎖定一定范圍內數據的鎖。保證在查詢數據的鍵范圍內不允許插入數據。
http://www.cnblogs.com/qiaokai/p/5344252.html
7. 在資料庫中解決死鎖的常用方法有哪些
1、要求每個事務一次就將所有要使用的數據全部加鎖,否則不能執行。
2、採用按序加鎖法.預先規定一個封鎖順序,所有的事務都必須按這個順序對數據執行封鎖。
3、不採取任何措施來預防死鎖的發生,而是周期性地檢查系統中是否有死鎖.如果發現死鎖就設法解除。