MySQL DeadLock故障排查過程

来源:https://www.cnblogs.com/CtripDBA/archive/2019/01/02/10207784.html
-Advertisement-
Play Games

【作者】 劉博:攜程技術保障中心資料庫高級經理,主要關註Sql server和Mysql的運維和故障處理。 【環境】 版本號:5.6.21 隔離級別:REPEATABLE READ 【問題描述】 接到監控報警,有一個線上的應用DeadLock報錯,每15分鐘會準時出現,報錯統計如下圖: 登錄Mysq ...


【作者】

劉博:攜程技術保障中心資料庫高級經理,主要關註Sql server和Mysql的運維和故障處理。

【環境】

版本號:5.6.21
隔離級別:REPEATABLE READ

【問題描述】

接到監控報警,有一個線上的應用DeadLock報錯,每15分鐘會準時出現,報錯統計如下圖:

登錄Mysql伺服器查看日誌:

mysql> show engine innodb status\G
*** (1) TRANSACTION:
TRANSACTION 102973, ACTIVE 11 sec starting index read
mysql tables in use 3, locked 3
LOCK WAIT 4 lock struct(s), heap size 1136, 3 row lock(s)
MySQL thread id 6, OS thread handle 140024996574976, query id 83 localhost us updating
UPDATE TestTable
SET column1 = 1,
Column2 = sysdate(),
Column3= '026’
Column4 = 0
AND column5 = 485
AND column6 = 'SEK'
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 417 page no 1493 n bits 1000 index idx_column6 of table test.TestTable trx id 102973 lock_mode X waiting
Record lock, heap no 859 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 3; hex 53454b; asc SEK;;
1: len 8; hex 80000000007e1452; asc ~ R;;

*** (2) TRANSACTION:
TRANSACTION 102972, ACTIVE 26 sec starting index read
mysql tables in use 3, locked 3
219 lock struct(s), heap size 24784, 2906 row lock(s), undo log entries 7
MySQL thread id 5, OS thread handle 140024996841216, query id 84 localhost us updating
UPDATE TestTable
SET Column1 = 1,
Column2 = sysdate(),
Column3 = '026'
Column4 = 0
AND Column5 = 485
AND Column6 = 'SEK'
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 417 page no 1493 n bits 1000 index idx_Column6 of table test.TestTable trx id 102972 lock_mode X
Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0
0: len 8; hex 73757072656d756d; asc supremum;;

Record lock, heap no 859 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 3; hex 53454b; asc SEK;;
1: len 8; hex 80000000007e1452; asc ~ R;;

*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 601 page no 89642 n bits 1000 index idx_column6 of table test.TestTable trx id 32231892482 lock_mode X locks rec but not gap waiting
Record lock, heap no 38 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 3; hex 53454b; asc SEK;;
1: len 8; hex 80000000007eea14; asc ~ ;;

大致一看,更新同一索引的同一行,應該是一個Block,報TimeOut的錯才對,怎麼會報DeadLock?

【初步分析】

先分析下(2) TRANSACTION,TRANSACTION 32231892482。
等待的鎖信息為:

0: len 3; hex 53454b; asc SEK;;
1: len 8; hex 80000000007eea14; asc

持有的鎖信息為:
0: len 3; hex 53454b; asc SEK;;
1: len 8; hex 80000000007eeac4; asc

再先分析下(1) TRANSACTION,TRANSACTION 32231892617。
等待的鎖信息為:
0: len 3; hex 53454b; asc SEK;;
1: len 8; hex 80000000007eeac4; asc

於是可以畫出的死鎖表,兩個資源相互依賴,造成死鎖:

TRANSACTION Hold Wait
32231892617 53454b\80000000007eea14 53454b\80000000007eeac4
32231892482 53454b\80000000007eeac4 53454b\80000000007eea14

讓我們再看一下explain結果:

mysql>desc UPDATE TestTable SET Column1=1, Column2 = sysdate(),Column3 = '025' Column4 = 0 AND Column5 = 477 AND Column6 = 'SEK' \G;
*************************** 1. row ***************************
id: 1
select_type: UPDATE
table: TestTable
partitions: NULL
type: index_merge
possible_keys: column5_index,idx_column5_column6_Column1,idxColumn6
key: column5_index,idxColumn6
key_len: 8,9
ref: NULL
rows: 7
filtered: 100.00
Extra: Using intersect(column5_index,idxColumn6); Using where

可以看到 EXTRA 列:

Using intersect(column5_index,idxColumn6)

從5.1開始,引入了 index merge 優化技術,對同一個表可以使用多個索引分別進行條件掃描。
相關文檔:http://dev.mysql.com/doc/refman/5.7/en/index-merge-optimization.html

The Index Merge method is used to retrieve rows with several range scans and to merge their results into one. The merge can produce unions, intersections, or unions-of-intersections of its underlying scans. This access method merges index scans from a single table; it does not merge scans across multiple tables.

【模擬與驗證】

根據以上初步分析,猜測應該就是intersect造成的,於是在測試環境模擬驗證,開啟2個session模擬死鎖:

時間序列 Session1 Session2
1 Begin;
2 UPDATE TestTable SET Column2 = sysdate() Column4 = 0 AND Column5 = 47 AND Column6 = 'SEK
執行成功,影響7行
3 Begin;
4 UPDATE TestTable SET Column2 = sysdate(),Column4 = 0 AND Column5 = 485 AND Column6 = 'SEK';
被Blocking
5 UPDATE TestTable SET Column2 = sysdate(),Column4 = 0 AND Column5 = 485 AND Column6 = 'SEK';
執行成功
ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction

依據以上信息可以發現Session2雖然被Block了,但也獲取了一些Session1在時間序列5時所需資源的X鎖,可以再開啟一個查詢select count(Column5) from TestTable where Column5 = 485,設置SET TRANSACTION ISOLATION LEVEL SERIALIZABLE,去查詢Column5 = 485的行,觀察鎖等待的信息:

mysql> SELECT r.trx_id waiting_trx_id, r.trx_mysql_thread_id waiting_thread, r.trx_query waiting_query, b.trx_id blocking_trx_id, b.trx_mysql_thread_id blocking_thread, b.trx_query blocking_query FROM information_schema.innodb_lock_waits w INNER JOIN information_schema.innodb_trx b ON b.trx_id = w.blocking_trx_id INNER JOIN information_schema.innodb_trx r ON r.trx_id = w.requesting_trx_id \G;
*************************** 1. row ***************************
waiting_trx_id: 103006
waiting_thread: 36
waiting_query: UPDATE TestTable SET Column1 = 1, Column2 = sysdate(), Column3 = '026' Column4 = 0 AND Column5 = 485 AND Column6 = 'SEK'
blocking_trx_id: 103003
blocking_thread: 37
blocking_query: NULL
*************************** 2. row ***************************
waiting_trx_id: 421500433538672
waiting_thread: 39
waiting_query: select count(Column5) from TestTable where Column5 = 485
blocking_trx_id: 103006
blocking_thread: 36
blocking_query: UPDATE TestTable SET Column1 = 1, Column2 = sysdate(), Column3 = '026' Column4 = 0 AND Column5 = 485 AND Column6 = 'SEK'
2 rows in set, 1 warning (0.00 sec)

mysql> select * from information_schema.innodb_lock_waits \G;
*************************** 1. row ***************************
requesting_trx_id: 103006
requested_lock_id: 103006:417:1493:859
blocking_trx_id: 103003
blocking_lock_id: 103003:417:1493:859
*************************** 2. row ***************************
requesting_trx_id: 421500433538672
requested_lock_id: 421500433538672:417:749:2
blocking_trx_id: 103006
blocking_lock_id: 103006:417:749:2
2 rows in set, 1 warning (0.00 sec)

mysql> select * from INNODB_LOCKS \G;
*************************** 1. row ***************************
lock_id: 103006:417:1493:859
lock_trx_id: 103006
lock_mode: X
lock_type: RECORD
lock_table: test.TestTable
lock_index: idxColumn6
lock_space: 417
lock_page: 1493
lock_rec: 859
lock_data: 'SEK', 8262738
*************************** 2. row ***************************
lock_id: 103003:417:1493:859
lock_trx_id: 103003
lock_mode: X
lock_type: RECORD
lock_table:test.TestTable
lock_index: idxColumn6
lock_space: 417
lock_page: 1493
lock_rec: 859
lock_data: 'SEK', 8262738
*************************** 3. row ***************************
lock_id: 421500433538672:417:749:2
lock_trx_id: 421500433538672
lock_mode: S
lock_type: RECORD
lock_table: test.TestTable
lock_index: column5_index
lock_space: 417
lock_page: 749
lock_rec: 2
lock_data: 485, 8317620
*************************** 4. row ***************************
lock_id: 103006:417:749:2
lock_trx_id: 103006
lock_mode: X
lock_type: RECORD
lock_table: test.TestTable
lock_index: column5_index
lock_space: 417
lock_page: 749
lock_rec: 2
lock_data: 485, 8317620
4 rows in set, 1 warning (0.00 sec)

可以看到Session2,trx_id 103006阻塞了trx_id 421500433538672,而trx_id 421500433538672 requested_lock也正好是lock_data: 485, 8317620。由此可見Session2雖然別block了,但是還是獲取到了Index column5_index相關的鎖。被Block是因為intersect的原因,還需要idxColumn6的鎖,至此思路已經清晰,對整個分配鎖的信息簡化一下,如下表格(請求到的鎖用青色表示,需獲取但未獲取到的鎖用紅色表示):

時間點 Session1 Session2
1 477 SEK
2 485 SEK
3 485 SEK 死鎖發生

可以看到485 SEK這兩個資源形成了一個環狀,最終發生死鎖。

【解決方法】

  1. 最佳的方法是添加column5和Column6的聯合索引。
  2. 我們環境當時的情況發現Column6的篩選度非常低,就刪除了Column6的索引。
    10:55左右刪除索引後,報錯沒有再發生:

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1.XShell中上傳文件命令 首先需要安裝rz文件上傳工具: yum y install lrzsz 然後執行以下命令,可打開本地系統的選擇文件視窗:(或者直接把本地的文件拖動到SSH Shell視窗) rz y 2. 查看某個文件夾所占空間大小 du sh data/ 例: $ du sh da ...
  • 列舉了MySQL主從複製主要的相關參數 binlog server_id 伺服器在集群中唯一標識符 log_bin[=binlog_name] 啟動二進位日誌 log_bin_index 二進位日誌索引名稱 binlog_format 二進位日誌的類型 binlog_row_image 二進位鏡像保 ...
  • 本文我們來談談項目中常用的MySQL優化方法,共19條,具體如下: 1、EXPLAIN 做MySQL優化,我們要善用EXPLAIN查看SQL執行計劃。 下麵來個簡單的示例,標註(1、2、3、4、5)我們要重點關註的數據: type列,連接類型。一個好的SQL語句至少要達到range級別。杜絕出現al ...
  • 簡單的SQL語句增刪改查操作 說明: 在mysql裡面親測結果正確 用到的表(學生表:studnets) 1.創建一個學生表,(學號,姓名,性別,家庭住址) mysql> create table students -> ( -> studentId int(11) not null primary ...
  • 刪除登陸賬戶註意事項 不能刪除正在登錄的登錄名。 也不能刪除擁有任何安全對象、伺服器級對象或 SQL Server 代理作業的登錄名。 可以刪除資料庫用戶映射到的登錄名,但是這會創建孤立用戶。 有關詳細信息,請參閱 孤立用戶故障排除 (SQL Server)。 在 SQL Database中,對連接 ...
  • 本文由雲+社區發表 文章《MySQL查詢分析》講述了使用MySQL慢查詢和explain命令來定位mysql性能瓶頸的方法,定位出性能瓶頸的sql語句後,則需要對低效的sql語句進行優化。本文主要討論MySQL索引原理及常用的sql查詢優化。 一個簡單的對比測試 前面的案例中,c2c_zwdb.t_ ...
  • 場景: Aix 7.2 上安裝Oracle 18.4 RAC 執行root.sh腳本,ASM failed to start !查看日誌文件:ORA-40238: invalid linear algebra shared library /u01/app/oracle/product/18.0.0 ...
  • MySQL資料庫設計規範 目錄 1. 規範背景與目的 MySQL資料庫與 Oracle、 SQL Server 等資料庫相比,有其內核上的優勢與劣勢。我們在使用MySQL資料庫的時候需要遵循一定規範,揚長避短。本規範旨在幫助或指導RD、QA、OP等技術人員做出適合線上業務的資料庫設計。在資料庫變更和 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...