mysql崩溃怎么办 mysql崩溃日志

面试官:MySQL权限表损坏导致无法启动怎么办?一、背景
近期mysql崩溃怎么办 , 公司RDS云产品的MySQL Server版本进行升级mysql崩溃怎么办,由目前使用的5.7.26版本升级到最新版本5.7.31mysql崩溃怎么办;升级后测试同学发现:在MySQL创建用户后,5.7.31版本重新启动集群会出现启动失败的现象;而5.7.26版本在相同测试场景下是正常启动的 。这到底是为什么呢?
二、问题复现
2.1实验环境
2.2操作步骤
按照测试同学的测试步骤,首先创建一个用户:
然后关闭mysqld;这里需要介绍一下,我们集群的关闭方式是如下方式:
这种方式的内部实现类似于kill -9模式 。所以我在线下环境使用kill -9的方式来复现,操作如下:
然后重启mysqld,操作如下:
此时问题复现mysql崩溃怎么办了,mysqld启动失败,我们查看了下error日志,信息如下:
根据报错信息可以看出:MySQL的权限系统表发生了损坏 , 导致了mysqld启动失败;由于在MySQL 5.7及其之前版本该表是MyISAM引擎,且该引擎不支持事务,所以在mysqld异常崩溃会导致该类型引擎表的损坏;但在mysqld启动时是有参数控制MyISAM引擎的恢复模式,且该参数在我们产品中也配置到了my.cnf中,如下所示:
2.3参数解析
对于该参数的官方文档的解释如下:
设置MyISAM存储引擎恢复模式 。选项值是OFF、DEFAULT、BACKUP、FORCE或QUICK的值的任意组合 。如果指定多个值,请用逗号分隔 。指定不带参数的选项与指定DEFAULT相同,指定显式值" "将禁用恢复(与OFF值相同) 。如果启用了恢复,则mysqld每次打开MyISAM表时,都会检查该表是否标记为已崩溃或未正确关闭 。(只有在禁用外部锁定的情况下运行,最后一个选项才起作用 。)在这种情况下 , mysqld在表上运行检查 。如果表已损坏,mysqld将尝试对其进行修复 。
服务器自动修复表之前,它将有关修复的注释写到错误日志中 。如果您希望能够在无需用户干预的情况下从大多数问题中恢复,则应使用选项BACKUP,FORCE 。即使某些行将被删除,这也会强制修复表,但是它将旧的数据文件保留为备份 , 以便您以后可以检查发生了什么 。
全局变量,只读变量,默认为OFF 。
三、问题修复
这类MySQL用户表损耗的问题解决方式也是有多种,我这里列举其中一种:
(1)my.cnf中的[mysqld]标签下添加skip_grant_tables,启动时跳过加载系统字典 。
(2)重启mysqld , 然后修复mysql schema下的所有表 。
(3)在[mysqld]标签下注释或删除掉skip_grant_tables,然后重启mysqld 。
此时mysqld是可以正常启动的,无异常 。
四、深入排查
在产品化中,以上修复方式很不优雅,只是作为临时的解决方案;并且也存在一些令人疑惑的点:
【mysql崩溃怎么办 mysql崩溃日志】带着这些疑问,我们继续排查出现该现象的原因;此时Google也没有找到一些有效的信息 , 那么只能通过MySQL源代码来寻找一些答案 。
首先需要下载mysql 5.7.31版本的源代码,并搭建mysql debug环境;具体步骤可以自动Google搜索一下 , 本文就不再赘述了 。
在源代码中搜索一下关键词,用于打断点的位置,然后进行调试:
定位到相关代码,大概是sql/mysqld.cc的4958行,且存在if条件判断,此时我们开始调试:
通过以上调试信息,可以判断出acl_init函数返回的值为真;此时我们查看该函数的代码 (sql/auth/sql_auth_cache.cc:1365):
根据该函数的注释发现:该函数是初始化负责用户/数据库级特权检查的结构,并从mysql schema中的表中为其加载特权信息;且return值为1代表的是初始化权限失败 。

推荐阅读