iis服务器助手广告广告
返回顶部
首页 > 资讯 > 数据库 >MySQL Bug导致异常宕机的分析流程
  • 317
分享到

MySQL Bug导致异常宕机的分析流程

2024-04-02 19:04:59 317人浏览 薄情痞子
摘要

一、数据库重启日志分析 terminate called after throwing an instance of 'std::out_of_range' what(): vector::_


本文主要通过一个bug来记录一下如何分析一个Mysql bug的崩溃信息。
版本:Percona 5.7.17-11


一、数据库重启日志分析

terminate called after throwing an instance of 'std::out_of_range' what():  vector::_M_range_check
04:10:09 UTC - mysqld Got signal 6 ;
mysqld got signal 6 ;
......
Thread pointer: 0x0
Attempting backtrace. You can use the following infORMation to find out where mysqld died. If you see no messages after this, something went
terribly wrong...
stack_bottom = 0 thread_stack 0x40000
/dbdata/mysql3306/bin/mysqld(my_print_stacktrace+0x35)[0xf3e175]
/dbdata/mysql3306/bin/mysqld(handle_fatal_signal+0x4b4)[0x7c3b94]
/lib64/libpthread.so.0(+0xf7e0)[0x7f79f28e87e0]
/lib64/libc.so.6(gsignal+0x35)[0x7f79f137d495]
/lib64/libc.so.6(abort+0x175)[0x7f79f137ec75]
/usr/lib64/libstdc++.so.6(_ZN9__gnu_cxx27__verbose_terminate_handlerEv+0x12d)[0x7f79f1c37a8d]
/usr/lib64/libstdc++.so.6(+0xbcbe6)[0x7f79f1c35be6]
/usr/lib64/libstdc++.so.6(+0xbcc13)[0x7f79f1c35c13]
/usr/lib64/libstdc++.so.6(+0xbcd32)[0x7f79f1c35d32]
/usr/lib64/libstdc++.so.6(_ZSt20__throw_out_of_rangePKc+0x67)[0x7f79f1bdadb7]
/dbdata/mysql3306/bin/mysqld[0x11d8f15]
/dbdata/mysql3306/bin/mysqld[0x11d99d5]
/dbdata/mysql3306/bin/mysqld(_Z17dict_stats_updateP12dict_table_t23Dict_stats_upd_option_t+0x9dc)[0x11de0cc]
/dbdata/mysql3306/bin/mysqld(dict_stats_thread+0x4f2)[0x11e0512]
/lib64/libpthread.so.0(+0x7aa1)[0x7f79f28e0aa1]
/lib64/libc.so.6(clone+0x6d)[0x7f79f1433bcd]
You may download the Percona Server operations manual by visiting
Http://www.percona.com/software/percona-server/. You may find information in the manual which will help you identify the cause of the crash. 

这部分是数据库崩溃的时候的栈帧,因为收到的是信号6 SIGABRT,只要捕获信号后改变其行为即可。这部分在MySQL官方文档中叫做Stack Trace,参考:

28.5.1.5 Using a Stack Trace 

实际上在这里我们已经可以看到大约是统计数据收集的问题,因为我们看到了dict_stats_thread,这是统计收集线程的回调函数。

二、生成更加可视化的Stack Trace

1、通过Stack Trace获得内存地址

获取如下:

[0xf3e175]
[0x7c3b94]
[0x7f79f28e87e0]
[0x7f79f137d495]
[0x7f79f137ec75]
[0x7f79f1c37a8d]
[0x7f79f1c35be6]
[0x7f79f1c35c13]
[0x7f79f1c35d32]
[0x7f79f1bdadb7]
[0x11d8f15]
[0x11d99d5]
[0x11de0cc]
[0x11e0512]
[0x7f79f28e0aa1]
[0x7f79f1433bcd] 
2、将这些地址放入一个文件

如:vi /tmp/err0222.log放入即可

3、通nm命令获取库文件链接文件

如:nm -D -n ./mysqld > /tmp/mysqld.sym

4、使用mysql工具resolve_stack_dump得到输出

如下:

[root@dyzsdb2 bin]# ./resolve_stack_dump -s /tmp/mysqld.sym -n /tmp/err0222.log | c++filt 
0xf3e175 my_print_stacktrace + 53 
0x7c3b94 handle_fatal_signal + 1204
 0x7f79f28e87e0 _end + -258115144 
0x7f79f137d495 _end + -280574355 
0x7f79f137ec75 _end + -280568243 
0x7f79f1c37a8d _end + -271422363 
0x7f79f1c35be6 _end + -271430210 
0x7f79f1c35c13 _end + -271430165 
0x7f79f1c35d32 _end + -271429878 
0x7f79f1bdadb7 _end + -271802481 
0x11d8f15 dict_stats_analyze_index_for_n_prefix(dict_index_t*, unsigned long, std::vector<unsigned long, ut_allocator<unsigned long> > const*, n_diff_data_t*, mtr_t*) + 4949 
0x11d99d5 dict_stats_analyze_index(dict_index_t*) + 2693 
0x11de0cc dict_stats_update(dict_table_t*, dict_stats_upd_option_t) + 2524 
0x11e0512 dict_stats_thread + 1266 0x7f79f28e0aa1 _end + -258147207 
0x7f79f1433bcd _end + -279827035 

实际上到这里通过函数的调用我们可以发现是统计数据收集出现了问题。

三、通过官方网站查询Bug
  • https://bugs.launchpad.net/percona-server
  • https://bugs.mysql.com/

在报错信息中提起比较代表性的信息在官方网站中进行搜索通过在percona中查看发现本bug由上游MySQL代码造成BUG号:Bug #84940
并且发现在5.7.18中得到修复同时给出了内部BUG号如下:

[10 Feb 2017 8:12] Shane Bester
Oli, Umesh, this would be same as internal:
Bug 24585978 - INNODB: ASSERTION TOTAL_RECS > 0 FaiLURE IN FILE DICT0STATS.CC 

四、查询Bug到底修改了什么地方

这里请教了阿里的印风兄才知道怎么查看,首先拿到了内部bug号:24585978
然后在git的commit log中搜索得到
git --no-pager log >/root/commitlog
vi /root/commitlog 找到commit号为:
29acdaaaeef9afe32b42785f1da3d79d56ed7e59
如下是这个bug的修复地方:

commit 29acdaaaeef9afe32b42785f1da3d79d56ed7e59
Author: Thirunarayanan Balathandayuthapani 
Date:   Wed Feb 8 12:00:52 2017 +0530 Bug #24585978 INNODB: ASSERTION TOTAL_RECS > 0 FAILURE
                        IN FILE DICT0STATS.CC
    
    Analysis:
    ========
    There was missing bracket for IF conditon in dict_stats_analyze_index_level() and it leads to wrong result.
    
    Fix:
    ====
    Fix the IF condition in dict_stats_analyze_index_level() so that it satisfied
    the if condtion only if level is zero.
    
    Reviewed-by : Jimmy Yang 

diff --git a/storage/innobase/dict/dict0stats.cc b/storage/innobase/dict/dict0stats.cc
index 3494070..55a2626 100644 --- a/storage/innobase/dict/dict0stats.cc
+++ b/storage/innobase/dict/dict0stats.cc
@@ -1099,10 +1099,10 @@ dict_stats_analyze_index_level(
                leaf-level delete marks because delete marks on
                non-leaf level do not make sense. */
 
- if (level == 0 && srv_stats_include_delete_marked? 0:
+ if (level == 0 && (srv_stats_include_delete_marked ? 0:
                    rec_get_deleted_flag(
                            rec,
-                           page_is_comp(btr_pcur_get_page(&pcur)))) {
+                           page_is_comp(btr_pcur_get_page(&pcur))))) { if (rec_is_last_on_page
                            && !prev_rec_is_copied 

五、为什么这么修改

这里是我的浅显的分析,不对的地方的还请见谅。
我们发现这里实际上修改就是多了一个括号而已,但是意义是相当重要的。

if (level == 0 && srv_stats_include_delete_marked ? 0:
            rec_get_deleted_flag(
                rec,
                page_is_comp(btr_pcur_get_page(&pcur)))) 
修改为了 if (level == 0 && (srv_stats_include_delete_marked ? 0:
            rec_get_deleted_flag(
                rec,
                page_is_comp(btr_pcur_get_page(&pcur))))) 

修改前:
如果level != 0 不管innodb_stats_include_delete_marked参数如何设置必然触发判断是否存在del_flag,然后通过设置偏移量的方式 跳过这行,但是随后的(*total_recs)++; 将不会触发,极端情况下可能为0。
而在上层代码dict_stats_analyze_index中的found_level:地方实际上是需要非叶子结点行数不为0的如下:

 
        ut_ad(total_recs > 0);
        ut_ad(n_diff_on_level[n_prefix - 1] > 0); 

六、如何规避

在官网查看的时候有如下方式可以规避这个Bug

  • 升级到5.7.18
  • 设置参数
innodb-stats-persistent             = 0 
innodb-stats-transient-sample-pages = 20 
innodb-stats-auto-recalc            = 0 

设置这些参数后实际上是使用的老的非固化的统计数据收集的方式,而不会通过线程dict_stats_thread收集下面是逻辑片段位于row_update_statistics_if_needed中如下:

 if (dict_stats_is_persistent_enabled(table)) { //参数innodb-stats-persistent 作用 if (counter > n_rows / 10  && dict_stats_auto_recalc_is_enabled(table)) {//参数innodb-stats-auto-recalc 作用 dict_stats_recalc_pool_add(table);
            table->stat_modified_counter = 0;
        } return;
    }  if (counter > 16 + n_rows / 16 ) {

        ut_ad(!mutex_own(&dict_sys->mutex));  dict_stats_update(table, DICT_STATS_RECALC_TRANSIENT);
    } 

这样做的话肯定不会调用到触发bug的函数,有兴趣的可以看看dict_stats_update(table, DICT_STATS_RECALC_TRANSIENT);的逻辑。实际上使用的是老的方式断点可以打在btr_estimate_number_of_different_key_vals函数上。

作者微信


您可能感兴趣的文档:

--结束END--

本文标题: MySQL Bug导致异常宕机的分析流程

本文链接: https://www.lsjlt.com/news/47309.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Moment的feature导致线上bug解决分析
    目录bug的出现bug排查bug的根因解决方案bug的出现 这一天,本来是平平淡淡的一天,我正准备一如既往的到点下班,结果qa说线上出了个匪夷所思的bug。 表象为:用户在日期选择器...
    99+
    2024-04-02
  • C++的异常机制导致的crash问题
    问题背景 最近工作中遇到了一个非常奇怪的crash问题,反反复复分析了好久。由于保密原因,这里只记录一下分析思路,不会涉及到代码。 初步log分析 tombstone显示这是一个abort:Cmdline: /vendor/bin/hw/v...
    99+
    2023-09-20
    c++ linux android
  • Mysql 字符集不一致导致连表异常的解决
    目录1. 解决方法 2. mysql字符集 字符集 校验规则 做一个简单的如下的连表查询,居然直接提示错误,居然是字符集不一致的问题,本文记录一下mysql的字符集类型,以及下面这个...
    99+
    2024-04-02
  • @RefreshScope在Quartz触发器类导致异常问题解决分析
    目录背景问题启示录背景 承接上篇,测试过程中又遇到了 Nacos Config 的动态刷新注解 @RefreshScope 与 Quartz 框架结合的问题,Bug 排查路上,顺手...
    99+
    2023-02-10
    @RefreshScope Quartz异常 Quartz 触发器类异常
  • redis使用不当导致应用卡死bug的过程解析
    目录topjstack 查看堆内存执行thread命令 首先说下问题现象:内网sandbox环境API持续1周出现应用卡死,所有api无响应现象 刚开始当测试抱怨环境响应慢...
    99+
    2024-04-02
  • 数据库中分区维护DDL导致DML异常中断举例分析
    这篇文章主要讲解了“数据库中分区维护DDL导致DML异常中断举例分析”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“数据库中分区维护DDL导致DML异常中断举...
    99+
    2024-04-02
  • 网站流量异常的示例分析
    小编给大家分享一下网站流量异常的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!网站流量异常一直是站长们最头疼的问题,而每次在反馈中心提交问题,经常得到回复...
    99+
    2023-06-10
  • MySQL异常处理的示例分析
    这篇文章给大家分享的是有关MySQL异常处理的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。针对存储过程 、触发器或函数内部语句可能发生的错误或警告信息,需要进行相关异常...
    99+
    2024-04-02
  • 大量删除导致MySQL慢查的示例分析
    这篇文章将为大家详细讲解有关大量删除导致MySQL慢查的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。一、背景监控上收到了大量慢查的告警,业务也反馈查询很慢,随即...
    99+
    2024-04-02
  • PHP异常机制的流程及原理
    本篇内容介绍了“PHP异常机制的流程及原理”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!PHP的异常机制的原理是什么?在PHP每一个可独立执...
    99+
    2023-06-17
  • PHP PCNTL fork失败导致的程序异常及修复方法
    PHP PCNTL是PHP提供的一个扩展库,用于处理进程控制相关的函数。在编写PHP多进程程序时,PCNTL库可以帮助我们创建子进程,进行进程间通信,以及管理进程的状态等。然而,在使用...
    99+
    2024-02-28
    php fork pcntl
  • Python中异常机制的示例分析
    小编给大家分享一下Python中异常机制的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!一、对异常的理解1、什么是异常  异常即“与正常情况不同”,何为正...
    99+
    2023-06-08
  • MySQL中mysqldump导出数据异常重启及drop栈帧的示例分析
    小编给大家分享一下MySQL中mysqldump导出数据异常重启及drop栈帧的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一...
    99+
    2024-04-02
  • PHP中Exception异常机制的示例分析
    这篇文章将为大家详细讲解有关PHP中Exception异常机制的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。异常的基本使用当异常被抛出时,其后的代码不会继续执行,PHP 会尝试查找匹配的 &qu...
    99+
    2023-06-20
  • Java异常处理机制的示例分析
    这篇文章给大家分享的是有关Java异常处理机制的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。1.初识异常我们在写代码的时候都或多或少碰到了大大小小的异常,例如:public class&nbs...
    99+
    2023-06-26
  • Python异常处理机制的示例分析
    这篇文章将为大家详细讲解有关Python异常处理机制的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。什么是异常?def num(a, b):   ...
    99+
    2023-06-22
  • 怎么分析pymysql非线程安全导致的故障
    今天就跟大家聊聊有关怎么分析pymysql非线程安全导致的故障,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。mysqldb   这个python 驱动只支持到 p...
    99+
    2023-06-03
  • Java中异常处理机制的示例分析
    这篇文章给大家分享的是有关Java中异常处理机制的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。  你觉得自己是一个Java专家吗?是否肯定自己已经全面掌握了Java的异常处理机制?在下面这段代码中,你能...
    99+
    2023-06-03
  • MySQL游标和异常处理的示例分析
    这篇文章给大家分享的是有关MySQL游标和异常处理的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。复杂异常处理drop procedure ...
    99+
    2024-04-02
  • Golang中异常处理机制的示例分析
    小编给大家分享一下Golang中异常处理机制的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!前言通常我们需要编写好的错误处理方式,在了避免某些程序员滥用异...
    99+
    2023-06-15
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作