MySQL所有操作hang住問題的故障排查
1. 系統環境
CentOS release 6.7
mysql社群版MySQL-5.5.24(原始碼編譯安裝)
2. 故障簡述
首先收到故障告警,所有的監控無法讀取到資料。無法正常連線資料庫。
3. 故障排查
如下過程是在開發環境復現了故障後,對故障排查具體過程的模擬。
3.1. 嘗試登陸資料庫
發現登陸發生hang住的情況,無法正常連線。無任何提示資訊報出。
shell>mysql-h192.168.150.21 -P50001 -uabc -pabc
shell>mysql -S /var/lib/mysql/mysql.sock -uabc -pabc
3.2. 檢視錯誤日誌
錯誤日誌完全正常,無任何錯誤日誌報出。
3.3. 使用pstack和gdb
在使用常規手段無法讀取資料庫的基本資訊和錯誤資訊的情況下,我們考慮使用linux環境下的程序除錯工具pstack和gdb。其中pstack可以打印出指定程序的全部堆疊資訊,gdb可以除錯程序,檢視程序的具體堆疊資訊、記憶體使用情況等一系列具體資訊。
3.3.1. 使用pstack
使用pstack工具檢視程序內各個執行緒的堆疊資訊。執行命令:
shell>pstack <mysqld pid> > pstack.log
將堆疊日誌存放到pstack.log檔案中,分析堆疊日誌的內容。發現存在很多執行緒處於等待執行緒互斥量mutex的狀態,並且等待的mutex是兩個不同的mutex,猜測是原始碼記憶體在bug,造成了程序死鎖:
Thread 2 (Thread0x7f8df41f8700 (LWP 13789)):
#0 0x00007f8df8fea2e4 in __lll_lock_wait () from/lib64/libpthread.so.0
#1 0x00007f8df8fe5588 in_L_lock_854 () from/lib64/libpthread.so.0
#2 0x00007f8df8fe5457 in pthread_mutex_lock () from/lib64/libpthread.so.0
#3 0x00000000008d36d6 in safe_mutex_lock ()
#4 0x00000000007fa28b in inline_mysql_mutex_lock()
#5 0x000000000080364d inMYSQL_BIN_LOG::reset_logs(THD*) ()
#6 0x000000000061d211 in reset_master(THD*) ()
#7 0x00000000006fa4ce inreload_acl_and_cache(THD*, unsigned long, TABLE_LIST*, int*) ()
#8 0x00000000005f7c55 in mysql_execute_command(THD*)()
Thread 3 (Thread0x7f8df4239700 (LWP 13070)):
#0 0x00007f8df8fea2e4 in __lll_lock_wait () from/lib64/libpthread.so.0
#1 0x00007f8df8fe55be in _L_lock_995 () from/lib64/libpthread.so.0
#2 0x00007f8df8fe5526 in pthread_mutex_lock () from/lib64/libpthread.so.0
#3 0x00000000008d36d6 in safe_mutex_lock ()
#4 0x00000000006187e7 in inline_mysql_mutex_lock()
#5 0x000000000061981b in log_in_use(char const*)()
#6 0x0000000000804200 inMYSQL_BIN_LOG::purge_logs(char const*, bool, bool, bool, unsigned long long*)()
#7 0x0000000000619a27 in purge_master_logs(THD*,char const*) ()
#8 0x00000000005f35f0 inmysql_execute_command(THD*) ()
其中執行緒2和執行緒3分別在等待不同的mutex。
Thread N (Thread0x7f8df427a700 (LWP 7759)):
#0 0x00007f8df8fea2e4 in __lll_lock_wait () from/lib64/libpthread.so.0
#1 0x00007f8df8fe55be in _L_lock_995 () from/lib64/libpthread.so.0
#2 0x00007f8df8fe5526 in pthread_mutex_lock () from/lib64/libpthread.so.0
#3 0x00000000008d36d6 in safe_mutex_lock ()
#4 0x0000000000651e42 in inline_mysql_mutex_lock()
#5 0x0000000000657368 inmysqld_list_processes(THD*, char const*, bool) ()
#6 0x00000000005f5f2a inmysql_execute_command(THD*) ()
而其他新連線或者已經連線無應答的程序,也在等待其中的一個mutex。
3.3.2. 使用gdb檢視具體資訊
執行如下命令attach到mysqld程序,檢視當前執行緒堆疊的具體情況。
shell>gdb -p <mysqld pid>
執行命令info thread檢視執行緒的具體資訊,發現很多執行緒均在等待鎖資訊,通過上面描述的pstack日誌資訊,我們知道執行緒2和執行緒3存在等待不同鎖的行為且可疑性比較高。
(gdb) info thread
M Thread 0x7f8df784a700 (LWP 7185) 0x00007f8df8ddb614 in ?? () from/lib64/libaio.so.1
……
N Thread 0x7f8de251b700 (LWP 7365) [email protected]@GLIBC_2.3.2 ()
at../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S:239
……
4 Thread 0x7f8df427a700 (LWP 7759) __lll_lock_wait () at../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:136
3 Thread 0x7f8df4239700 (LWP 13070) __lll_lock_wait () at../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:136
2 Thread 0x7f8df41f8700 (LWP 13789) __lll_lock_wait () at../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:136
* 1 Thread 0x7f8df93fd720(LWP 7141) __lll_lock_wait () at../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:136
切換到執行緒2檢視,執行緒在等待的mutex為LOCK_index。
(gdb) thread 2
[Switching to thread 2(Thread 0x7f8df41f8700 (LWP 13789))]#0 __lll_lock_wait ()
at ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:136
136 2: movl %edx, %eax
(gdb) bt
……
#4 0x00000000007fa28b in inline_mysql_mutex_lock(that=0x12cc8d0,
src_file=0xc10968"/..../mysql-5.5.24/sql/log.cc",src_line=3425)
at/....../mysql-5.5.24/include/mysql/psi/mysql_thread.h:615
#5 0x000000000080364d in MYSQL_BIN_LOG::reset_logs(this=0x12cc400, thd=0x21d1ed0)
at /....../mysql-5.5.24/sql/log.cc:3425
……
(gdb) frame 5
#5 0x000000000080364d inMYSQL_BIN_LOG::reset_logs (this=0x12cc400, thd=0x21d1ed0)
at/....../mysql-src/mysql-5.5.24/sql/log.cc:3425
3425 mysql_mutex_lock(&LOCK_index);
切換到執行緒3檢視,執行緒在等待的mutex為LOCK_thread_count。
(gdb) thread 3
[Switching to thread 3(Thread 0x7f8df4239700 (LWP 13070))]#0 __lll_lock_wait ()
at../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:136
136 2: movl %edx, %eax
(gdb) bt
……
#4 0x00000000006187e7 in inline_mysql_mutex_lock(that=0x12b1500,
src_file=0xb86c30"/....../mysql-src/mysql-5.5.24/sql/sql_repl.cc",src_line=254)
at/....../mysql-src/mysql-5.5.24/include/mysql/psi/mysql_thread.h:615
#5 0x000000000061981b in log_in_use (log_name=0x7f8df4236c60"./my_log.000001")
at /....../mysql-src/mysql-5.5.24/sql/sql_repl.cc:254
……
#7 0x0000000000619a27 in purge_master_logs (thd=0x21ca8f0,to_log=0x7f8dd0004cf8 "my_log.000004")
at /....../mysql-src/mysql-5.5.24/sql/sql_repl.cc:311
……
(gdb) frame 5
#5 0x000000000061981b in log_in_use(log_name=0x7f8df4236c60 "./my_log.000001")
at/....../mysql-src/mysql-5.5.24/sql/sql_repl.cc:254
254 mysql_mutex_lock(&LOCK_thread_count);
由此猜測,是原始碼中由於存在LOCK_index和LOCK_thread_count相互等待的BUG,導致兩個mutex均未被釋放,發生死鎖情況,其它需要獲得鎖的操作均發生一致等待的情況(即發生hang住)。
3.4. 檢視原始碼
根據gdb除錯中執行緒2和執行緒3的資訊,檢視命令purgebinlog和reset master對應的原始碼。檢視發現兩個命令對於LOCK_thread_count和LOCK_index呼叫順序是不同的。導致同時執行時會發生相互等待,發生死鎖的情況。
dispatch_command
| purge_master_logs
| | MYSQL_BIN_LOG::purge_logs
| | mysql_mutex_lock(&LOCK_index);
| | log_in_use
| | mysql_mutex_lock(&LOCK_thread_count);
|
| reload_acl_and_cache
| | reset_master
| | MYSQL_BIN_LOG::reset_logs
| | mysql_mutex_lock(&LOCK_thread_count);
| | mysql_mutex_lock(&LOCK_index);
4. 故障解決
同時執行了purge binlog和reset master命令,會小概率導致瞭如上問題的產生。
在我們分析原始碼的過程中,同時發現,設定了引數expir_logs_days後,在binlog發生切換時(當前binlog寫滿或者執行flush logs命令),也會走到發生死鎖的程式碼分支,即如果同時執行reset master命令,也會發生死鎖的情況。
在檢視官方修復後,發現該bug已經修復。
該bug由官方在修復另一問題時同時修復,在版本5.5.39時修復。github上的Bug描述和修復細節為以下:
https://github.com/mysql/mysql-server/commit/33f15dc7acf817e1e99203734d3e4b16b50fcc17
相關推薦
MySQL所有操作hang住問題的故障排查
1. 系統環境 CentOS release 6.7 mysql社群版MySQL-5.5.24(原始碼編譯安裝) 2. 故障簡述 首先收到故障告警,所有的監控無法讀取到資料。無法正常連線資料庫。 3. 故障排查 如下過程是在開發環境復現了故障後,對故障排
MySQL所有操作hang住了,怎麼破?
作者介紹 王鬆磊,現任職於UCloud,從事MySQL資料庫核心研發工作。主要負責UCloud雲資料庫udb的核心故障排查工作以及資料庫新特性的研發工作。 系統環境 CentOS release 6.7 MySQL社群版MySQL-5.5.24 故障簡述 首先收到故障告警,所有的監控無法讀取到資料。
Oracle資料庫監聽非常慢,基本hang住故障處理
測試人員郵件反饋: 訂購資料庫的連線非常慢,甚至是無法連線,想要我檢檢視看。 經檢視: [email protected]:~/app/admin/wdadb/adump> lsnrctl status LSNRCTL for Linux: Version
mysql 執行狀態分析 執行故障排查
目錄 一、優化概述 二、查詢與索引優化分析 1效能瓶頸定位 Show命令 慢查詢日誌 explain分析查詢 profiling分析查詢 2索引及查詢優化 一、優化概述 MySQL資料庫是常見的兩個瓶頸是CPU和I/
NDMCDB資料庫hang住故障分析
問題描述: 上午剛剛到辦公室,就有監控人員郵件反饋,昨晚NDMCDB407資料庫被重啟過,讓我分析一下資料庫重啟的原因。由於昨晚業務有版本上線,所以簡訊警告關閉了,所以沒有簡訊下發到我手機上,而且故障時相關人員也沒有通知到我。 1 檢查alert日誌 從alert
mysql 線上故障排查
mysql 線上故障排查Mysql 系統報連接池滿iostatslowlogWhat’s in slow log?Mk-query-digest mk-query-digest 全面分析slow log本文出自 “李世龍” 博客,謝絕轉載!mysql 線上故障排查
記錄一次MySQL進程崩潰,無法重啟故障排查
not pool function 解決 variables fail data class 緩沖 最近程序在跑著沒幾天,突然訪問不了,查看應用進程都還在。只有數據庫的進程down掉了。於是找到日誌文件看到如下錯誤 2017-07-24 01:58:53 19934 [N
MySQL 故障排查
從服務器 火墻 服務器 slave fail mysql服務器 mas rest ops Linux服務器重啟後發現Mysql無法啟動了 故障一:啟動故障 錯誤提示:Can‘t connect to local MySQL server through socket
mysql批量操作所有表用遊標方式迴圈(直接copy可用)
直接在navcat上新建過程 copy即可(過程和函式的區別就是 函式有引數) BEGIN DECLARE s_tablename VARCHAR(100); -- 變數名 s_tablename #顯示所有
oracle故障處理之刪除大表空間hang住
背景 資料庫分割槽表資料越來越大,需要對過期話的資料進行遷移,以及大的分割槽表需要進行資料的清理和刪除,達到釋放磁碟空間的目的。 問題說明 環境:linux 6.X 資料庫:oracle 11.2.0.4 (PSU為2016年6月份的) 問題說明: S_T_RTNRP_STATUS_2017是分割槽表,每
MySQL DeadLock故障排查過程
【作者】 劉博:攜程技術保障中心資料庫高階經理,主要關注Sql server和Mysql的運維和故障處理。 【環境】 版本號:5.6.21 隔離級別:REPEATABLE READ 【問題描述】 接到監控報警,有一個線上的應用DeadLock報錯,每15分鐘會準時出現,報錯統計如下圖: 登入My
ceph 集群報 mds cluster is degraded 故障排查
ceph 故障排查 mds degraded ceph 集群報 mds cluster is degraded 故障排查ceph 集群版本:ceph -vceph version 10.2.7 (50e863e0f4bc8f4b9e31156de690d765af245185)ceph -w
Mysql delete操作
from ber ignore aml cor syn 1.3 -s cti 以下摘自官方文檔: 語法: DELETE [LOW_PRIORITY] [QUICK] [IGNORE] FROM tbl_name [PARTITION (partition_
配置IP和網絡故障排查
虛擬主機 配置文件 網絡服務 計算機 ip地址 1:nat模式和橋接模式的區別橋接:虛擬機和主機一個網段,好處:設置簡單,可以訪問局域網其他計算機和外網。 缺點:占用一個外網ip地址nat:使用的是vmnet8網卡,能和主機外網通信,不能和局域網其他的主機通信。2:網卡配置文件目錄v
mysql 選取操作日誌(mysql-bin.0000恢復數據)
com boa .cn ini 啟用 分享 時間段 結束時間 開始 my.ini 配置log-bin=mysql-bin 啟用日誌 用 mysql-bin.0000 mysqlbinlog -d keyboard ../data/mysql-bin.000024
MySQL主從同步報錯故障處理記錄
記錄 error start record master 前言在發生故障切換後,經常遇到的問題就是同步報錯,下面是最近收集的報錯信息。記錄刪除失敗在master上刪除一條記錄,而slave上找不到Last_SQL_Error: Could not execute Delete_rows e
MySQL DLL操作--------臨時表存儲實戰
mysql dba temporary 1. 背景 * 臨時表是基於會話的(session),只在當前連接可見 * 當這個連接(會話)關閉的時候,會自動drop。 * 兩個不同的連接(會話)裏使用相同的臨時表名,並且相互不會沖突,或者使用已經存在的表,但不是臨時表的表名。 * 當這個臨時
MySQL DML操作--------CURD最佳實戰
mysql dba curd 1. 背景 * CURD 操作通常是使用關系型數據庫系統中的結構化查詢語言(Structured Query Language,SQL)完成的 * CURD 定義了用於處理數據的基本原子操作 * CURD 代表創建(Create)、更新(Update)、讀取(
MySQL DML操作--------多表聯合查詢實戰
join 聯合查詢 mysql dba 1. 背景 * 多表聯合查詢是把不同表的記錄到一起的一種方式 * 在SQL標準中規劃的聯合(join)大致分內連接,外連接,全連接。其中外連接又分左外連接,右外連接。2. 內連接例子 (inner join) [ 員工 --> 部門 ]
MySQL DDL操作--------外鍵最佳實戰
mysql dba 外鍵約束 1. 背景 * MySQL有兩種常用的引擎類型MyISAM和InnoDB。目前只有InnoDB引擎類型支持外鍵約束。 * 本表的列必須與外鍵類型相同, 外鍵必須是外表的主鍵 * 設置外建的列不能設置 NO NULL 字段屬性。2. 外建作用 * 使兩張