1. 程式人生 > >MySQL所有操作hang住問題的故障排查

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. 外建作用 * 使兩張