MySQL 两个备机同时挂掉故障分析

news/2024/12/22 20:25:27/

来源:

接报线上出现两个5.7.38的备库同时crash,crash堆栈相同,内容如下:

stack_bottom = 7fd7700b0d30 thread_stack 0x40000
/home/service/app/mysql33066/bin/mysqld(my_print_stacktrace+0x2c)[0xf1062c]
/home/service/app/mysql33066/bin/mysqld(handle_fatal_signal+0x4f5)[0xd4f155]
/lib64/libpthread.so.0(+0xf5d0)[0x7fdbc8c2f5d0]
/lib64/libc.so.6(gsignal+0x37)[0x7fdbc73662c7]
/lib64/libc.so.6(abort+0x148)[0x7fdbc73679b8]
/home/service/app/mysql33066/bin/mysqld[0x7828ae]
/home/service/app/mysql33066/bin/mysqld(_Z27row_ins_sec_index_entry_lowmmP12dict_index_tP16mem_block_info_tS2_P8dtuple_tmP9que_thr_tb+0x187b)[0x108e5bb]
/home/service/app/mysql33066/bin/mysqld(_Z23row_ins_sec_index_entryP12dict_index_tP8dtuple_tP9que_thr_tb+0x13a)[0x109271a]
/home/service/app/mysql33066/bin/mysqld(_Z12row_ins_stepP9que_thr_t+0x2c4)[0x1094e44]
/home/service/app/mysql33066/bin/mysqld[0x10a7d6b]
/home/service/app/mysql33066/bin/mysqld(_ZN11ha_innobase9write_rowEPh+0x214)[0xfb69e4]
/home/service/app/mysql33066/bin/mysqld(_ZN7handler12ha_write_rowEPh+0x11a)[0x7bd6aa]
/home/service/app/mysql33066/bin/mysqld(_ZN20Write_rows_log_event9write_rowEPK14Relay_log_infob+0x12d)[0xe8d19d]
/home/service/app/mysql33066/bin/mysqld(_ZN20Write_rows_log_event11do_exec_rowEPK14Relay_log_info+0x19)[0xe8d509]
/home/service/app/mysql33066/bin/mysqld(_ZN14Rows_log_event12do_apply_rowEPK14Relay_log_info+0x26)[0xe76316]
/home/service/app/mysql33066/bin/mysqld(_ZN14Rows_log_event14do_apply_eventEPK14Relay_log_info+0x446)[0xe8b156]
/home/service/app/mysql33066/bin/mysqld(_Z27slave_worker_exec_job_groupP12Slave_workerP14Relay_log_info+0x17f)[0xee71ef]
/home/service/app/mysql33066/bin/mysqld(handle_slave_worker+0x433)[0xec94f3]
/home/service/app/mysql33066/bin/mysqld(pfs_spawn_thread+0x1b4)[0xf27ef4]
/lib64/libpthread.so.0(+0x7dd5)[0x7fdbc8c27dd5]
/lib64/libc.so.6(clone+0x6d)[0x7fdbc742e02d]

这个crash堆栈可以看到,是在回放binlog时,出现了crash。这类问题比较常见,看到堆栈能确定大概原因:物理备份时拷贝文件有损坏。一般此类问题直接重新用最新冷备文件重建解决即可,但这次的现象有两个不同,一是两个备库都运行了10多天了,二是从堆栈上看应该是索引的问题,可以尝试修复。

分析:

既然是会crash,那么首先应该确定是哪个binlog事务回放导致crash,进入定位到是执行哪个sql,然后再确定是哪个表。

  1. 在my.cnf中增加停止复制参数:skip-slave-start

  2. 使用show slave status 和show master status确定当前同步到的位点,如果曾经同步过的主机多,需要登陆master确定当前的master uuid。

  3. 通过上面找到的binlog位置,在备机relay-log中找到执行会导致crash的事务,发现是一个insert语句。

  4. 接下来要验复现定crash,直接select count(*)这个表,扫一下表数据,一般数据文件损坏的会直接crash,但本次案例没有crash,这说明表数据没问题。通过show create table查看表结构,发现该还有一个联合唯一索引,当我们通过主键扫表时,不会调用辅助索引,但插入或者更新时,一定会同步更新索引。

  5. 继续验证索引问题,因为表数据不大,又是没流量的备库,可直接重建索引测试:

    SET sql_log_bin = 0;
    ALTER TABLE desc_table ENGINE=InnoDB;
    SET sql_log_bin = 1;
    START SLAVE;

观察每次必crash的binlog顺利通过,修复成功,以相同方法修复另一台,至此完全确定就是索引文件损坏。

6. 去掉my.cnf中skip-slave-start,否则下次有问题重启之后不会启动复制。

其它补充:

为什么这次是可修复的?

备库运行时间长,数据整体上不会有大面积问题。这是索引问题,重建索引会直接drop掉索引,不会访问索引内容,不会导致crash,如果是表文件没办法直接重建修复。

为什么数据文件损坏会导致数据库crash?

数据库存储在硬盘的数据文件,实际上是将内存中数据直接以页面为单位写盘,加载时也是直接将页面加载到内存中访问,页面里除了数据外,还有大量的相对指针偏移数据,访问页面内数据时依赖相对偏移指针来找目标内容,当页面数据损坏时,指针偏移的目标位置很容易访问到非法内存,导致进程crash。对此类问题,通过debug或core文件方式来分析源码意义不大,直接重建修复即可。

为什么数据文件会有损坏?

目前,MySQL的备份方式数据有两大类,一是逻辑方式备份,直接登陆数据库select数据保存。二是物理方式备份,通过xtraBackup直接拷贝物理文件,先拷redo,再拷数据文件,恢复时先拷数据文件,然后再按页面应用redo日志,我们用的就是第二种,几乎所有的公有云都是用第二种,它备份恢复速度是逻辑方式的5~10倍。

xtraBackup是第三方公司percona开发的开源工具,备份时不侵入MySQL,直接拷文件,可能在某些场景下有缺陷,备份备份文件损坏现象,但这个概率不高(每天备份上万次,几个月出现一次问题),在可承受范围,并且该工具一直在不停迭代升级,因此业界一直用它来做备份恢复。

 


http://www.ppmy.cn/news/222244.html

相关文章

Misumi米思米数据线驱动无法安装

Misumi米思米数据线驱动无法安装 • Win10 系统无法安装。 • 驱动只能在 XP 或 Win7 使用 • KCA-M538F-000 • M538F USB High Speed Serial Converter

Python 经纬度转化为米

import math from math import cosdef position_turn(Latitude,Longitude):参考地址:https://blog.csdn.net/Dust_Evc/article/details/102847870?utm_mediumdistribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-7.control&…

python任务:用米粒填充国际棋盘

1.代码如下: 先上图 2.代码如下: sum 0 for i in range(64): sum sum 2i print(’{}: {}’.format(i 1, 2i)) print(‘sum {}’.format(sum)) 3.运行结果:

红米手机安装google商店问题总结

①机型:redmi K30 Ultra, Android10 ②用什么工具? Go 安装器 ③go安装器安装google商店,显示“需安装应用过多” 去浏览器手动下,google商店 ④google play商店登录时显示“此账号已在此设备” 账户与同步>删除当前输入的账号 ⑤…

Python:阿基米德棋盘放米问题

国王与数学家阿基米德下棋,在棋盘上放米,国王输了,国王问阿基米德要什么奖赏? 阿基米德对国王说: 我只要在棋盘上第一格放一粒米,第二格放二粒,第三格放四粒,第四格放十六粒……… 按这个倍增的…

平方米用计算机怎么打,平方米符号怎么打m2 ㎡平方米符号输入方法

平方米符号多用于面积,在电脑中文字处理时有时候需要打㎡平方米符号,那么平方米符号怎么打m2 ?其实很简单,下面小编给大家介绍比较简单的几种方法。 方法一:输入法直接输入 其实很多朋友电脑中都安装有搜狗输入法或QQ输…

python棋盘放米问题_棋盘堆米的难题怎么解决?

原标题:棋盘堆米的难题怎么解决? 国外有个故事,一个人和国王打赌。如果国王输了就给他米。但是他要的你看上去很少,实则算起来确实非常多,甚至一个国家的米都不够。国王为了用人信守承诺。国王为了应向所有人显示自己很…

Android手机开启开发者选项(红米note7举例)

工具/原料 Redmi Note7 方法/步骤 打开手机桌面。 找到“设置”,点击进入。 点击第一个选项--“我的设备”。 找到全部参数,点击进入 找到“MIUI版本”,连续点击7下。每点击一下就会看到一个倒计次的提示框。这个时候返回“设置…