简介 汇总遇到过的异常宕机汇总
说明
1 本人也不懂代码,无法找到原因,所以只记录浅显的解决办法
2 异常宕机 分为能自行启动和 必须通过调整隔离级别才能启动两种情况.本文应对的是第一种情况
场景1 mysql特性引起的(常见于相关特性,常见AHI 松散扫描等)
案例1
核心报错区域
1 SEMAPHORES
2 has waited at buf0flu.cc line 1209 for 936.00 seconds the semaphore
3 SX-lock on RW-latch at thread_id created in file buf0buf.cc line a writer (thread id) has reserved it in mode
4 InnoDB: Semaphore wait has lasted > 600 seconds.
5 InnoDB: Assertion failure in thread 140282241115904 in file
分析
1 MySQL后台线程srv_error_monitor_thread发现存在阻塞超过600s的latch锁时,如果连续10次检测该锁仍没有释放,就会触发panic避免服务持续hang下去。等待的数据字典锁
2 基本都是超过900S才会崩溃
3 根据 a writer后面的thread_id定位具体的线程语句
可能造成的原因
1 由于AHI导致的latch争用,同样是rw latch锁争用,日志关键字(btr0sea.c文件)
官网的描述
You can monitor the use of the adaptive hash index and the contention for its use in the SEMAPHORES section of the output of the SHOW ENGINE INNODB STATUS command. If you see many threads waiting on an RW-latch created in btr0sea.c, then it might be useful to disable adaptive hash indexing.
2 由于慢查询导致的RW-Latch占有,导致其他事务阻塞
3 由于大事务导致的latch占有,比如replace into
解决方式
1 可以选择暂时关闭AHI然后进行持续观察 set global innodb_adaptive_hash_index=0;
2 根据show innodb status记录的查询语句进行分析优化
3 根据show innodb status记录的事务语句进行分析优化
定义总结
latch锁 Latch在MySQL中是用于保护高速缓冲区中共享数据的,举个例子: 当我们执行select时,数据是缓存在buffer pool中的,多个线程并发访问或者修改这个数据必然需要一个并发控制机制,这个就是 Latch.
1 只有多线程访问相同的目标latch才有意义
2 mysql RW-LATCH
案例2
核心报错区域
Trying to get some variables.
Some pointers may be invalid and cause the dump to abort.
Query (7fefc00bf590): select语句
Connection ID (thread ID): 508
Status: NOT_KILLED
分析
1 一旦执行指定的select记录语句就会导致mysql重启(包括程序与手动执行)
2 其他表的查询没有问题,可能是此表的问题
3 执行非特定select语句的其他select没有任何问题
4 在从库进行此表的此语句查询也没有任何问题
总结 就是特定表的特定查询语句导致mysql宕机
解决方式
1 此问题联系开发进行解决改造特定的查询sql进行暂时解决,不会影响该数据库的其他业务.至于造成的具体原因,只能根据pstack gdb进行跟踪分析了
最新补充 关闭loosescan=off 就可以不用更改sql.是由于这个参数导致的.这个参数的作用是semi-join 的优化.explain的查询语句一旦出现loosescan出现就代表应用了这个特性,导致当机,其他关于此表的查询就不会出现问题
总结
1 对于此类BUG导致的宕机事件大部分的解决方式查到定位某个参数,然后关闭即可.根本不必升级
场景2 无法启动汇总 (常见于基本页的损坏导致LSN不一致)
案例1
报错日志
2018-06-11T12:50:24.617098Z0[ERROR] InnoDB: Page [page id: space=42, page number=3]logsequence number14532708is in the future! Current systemlogsequence number12151645.
2018-06-11T12:50:24.617116Z0[ERROR] InnoDB: Your database may be corrupt or you may have copied the InnoDB tablespace but not the InnoDBlogfiles. Please refer to http://dev.mysql.com/doc/refman/5.7/en/forcing-innodb-recovery.html for information about forcing recovery.、
错误原因: redo page损坏,无法进行修复
解决方式: 调整恢复级别进行拯救
案例2
报错日志
index for table is corrupt
错误原因: 表的index page页出现损坏,导致一操作就会出问题
解决方式: 1 调整隔离级别为1 就不会启动corrput检测线程了 2 将数据进行备份 删除原表 3 注释参数 重新启动
案例3
报错日志
[ERROR] /usr/local/mysql/bin/mysqld: Binary logging not possible. Message: An error occurred during flush stage of the commit. 'binlog_error_action' is set to 'ABORT_SERVER'. Hence aborting the server
分析
binlog_error_action=ABORT_SERVER
Binlog_error_action参数控制当不能写binlog时,mysql-server将会采取什么行动。
设置binlog_error_action=ABORT_SERVER会使mysql-server在写binlog遇到严重错误时退出,比如磁盘满了,文件系统不可写入了等。在ABORT_SERVER选项下,binlog和从库都是安全的,这是官方修改此默认值的原因。
解决方式: 从linux层面寻找原因,可能是文件系统或者磁盘满了(可能是由于断电导致的异常)
1 导致各种page损坏的原因
- 硬件问题
- 驱动程序错误
- 内核错误
- 电源故障 (常见)
- 罕见的MySQL bug错误(常见)、
2 调整恢复级别需要从1-6进行逐步调整,在恢复之前进行备份一份数据文本. 因为 级别越高 对数据的影响会越大,所以逐步进行恢复测试
场景3 可以启动但是可能是产品BUG导致的
案例1
报错日志 [FATAL] InnoDB: Native Linux AIO interface. io_submit() call failed when resubmitting a partial I/O request on the file ./db_message_00001.ibd.
分析 : A Linux AIO handler function failed to check if completed I/O events AIO检测IO事件失败导致的
查看mysql官网 也能查到相应BUG BUG:90402
现在可能造成此问题的有两个因素:1 执行 DDL语句 2 数据库服务器的磁盘占满
解决方式: 升级版本到5.7.26
案例3
报错日志
InnoDB: Failing assertion: btr_page_get_next(get_page, mtr) == buf_frame_get_page_no(page)
分析 可能是innodb页损坏的
解决方式 按照通用方式解决,此BUG常见于小于5.7版本,可以进行版本升级
案例 4
报错日志 Database page corruption on disk or a failed"
说明: 为了保护数据,InnoDB使用校验和(与页储存在一起)。当InnoDB从磁盘读取时,它计算每个页的校验和,并与磁盘加载的校验和进行比较。如果值是不同的,可能真的发生了一些错误。InnoDB将关闭MySQL服务器,以防止进一步的逻辑或物理损坏。
解决方案 先通过innodbchecksum先定位损坏的库表文件,然后调整恢复级别为1,恢复级别1的时候会忽略相应的损坏的页.导出其他安全的库表,然后重建实例 也可以尝试 Repair the ibd file with innochecksum with --write=innodb 进行覆盖, 记住 作此操作之前需要备份
1 根据我之前的文章,你最好提前准备好一个源码包,和你线上的版本相对应,这样在出现BUG的时候能查询指定的CC代码获取具体的内容
2 taobao.mysql有着关于mysql源码的大量解读