记一次MySQL生产环境故障处理

1、故障描述

在2020年5月15日 凌晨三点,某台生产环境的MySQL进程异常,无法连接到数据库。早上上班开始排查问题并解决。
服务器是windows环境,设置每2天凌晨自动重启主机,MySQL以及其他应用都设置了自动启动。
注:以下所有步骤需要先关闭使用到数据库的应用程序。

2、故障处理过程

2.1 故障定位1

查看系统的计划任务,发现刚好15日凌晨3点执行了启动任务。上次运行结果这一栏显示0x40010004
在这里插入图片描述
在cn.bing.com上搜索“windows 0x400100004”找到一篇文章https://stackoverflow.com/questions/37078953/in-which-cases-does-program-exit-with-0x40010004-code。
文章是这样回答的
记一次MySQL生产环境故障处理_第1张图片
【文章大意是说这个错误很可能是在windows系统重启的时候发生。当windows系统要重启时,它会尝试以一种很友好的方式关闭正在运行中的程序,如果某个程序拒绝被关闭则会返回一个错误码0x40010004。】

2.2 故障定位2

以管理员身份打开cmd窗口执行net start MySQL57返回mysql启动失败,并且没有任何提示。
面向百度找到一篇文章https://blog.csdn.net/qq_37915248/article/details/82631398里面提到【进入DOS界面,到MySQL文件夹下输入mysqld --console】
于是进入到MySQL\bin目录下执行:mysqld --console
此处日志提示在mysql的Server目录下找不到mysql的data文件夹[D:\company\software\MySQL\MySQL Server 5.7\data]但是我的数据文件是放在安装目录外面的。
我用的MySQL是安装版,安装目录如下:

D:\company\software\MySQL
D:\company\software\MySQL\Connector.C++ 1.1
D:\company\software\MySQL\Connector.J 5.1
D:\company\software\MySQL\Connector.NET 6.9
D:\company\software\MySQL\Connector.ODBC 5.3
D:\company\software\MySQL\MySQL Connector.C 6.1
D:\company\software\MySQL\MySQL Documentation 5.7
D:\company\software\MySQL\MySQL Notifier 1.1
D:\company\software\MySQL\MySQL Router 2.1
D:\company\software\MySQL\MySQL Server 5.7
D:\company\software\MySQL\MySQL Utilities 1.6
D:\company\software\MySQL\MySQL Workbench 6.3 CE
D:\company\software\MySQL\Samples and Examples 5.7

外部数据目录:
D:\nannar\database\MySQL_DATA\my.ini
D:\nannar\database\MySQL_DATA\data

这里就很奇怪了:
1、系统重启前MySQL的运行一直是正常的。
2、此前mysql一直是从D:\nannar\database\MySQL_DATA\my.ini读取运行配置,从D:\nannar\database\MySQL_DATA\data读取数据文件。
3、故障出错时提示MySQL从D:\company\software\MySQL\MySQL Server 5.7\data下面读取数据文件。

由于对MySQL底层不够了解,此处果断卸载MySQL改用解压免安装的版本。
卸载后,将D:\nannar\database\MySQL_DATA更名为D:\nannar\database\MySQL_DATA-back

MySQL重装后目录结构如下:
免安装解压目录
D:\company\software\mysql-5.7.18-winx64
my.ini位置
D:\company\software\mysql-5.7.18-winx64\my.ini
数据库目录(在my.ini中配置)
D:\company\database\MySQL_DATA

环境变量
MYSQL_HOME指向D:\company\software\mysql-5.7.18-winx64
%MYSQL_HOME%\bin;追加到path中。

2.3 故障处理1-数据迁移

  1. 重新创建数据库 (不需要建表)
  2. 关闭数据库net stop MySQL57
  3. 从旧的数据目录中拷贝数据文件到新的数据目录中。
    例如库名是monitor
    D:\company\database\MySQL_DATA-back\data\monitor
    拷贝到D:\company\database\MySQL_DATA\monitor
  4. 启动数据库net start MySQL57
  5. 验证数据库
    命令行登录数据库后show databases; 数据库列表包含monitor。OK
    use monitor
    show tables ; 可以查到表清单。OK
    select * from dict_enum; 抛出异常:“ERROR 1146 (42S02):Table monitor.dict_enum’ doesn’t exist”
    百度找到一篇文章https://blog.csdn.net/qq_25600055/article/details/48903629
    记一次MySQL生产环境故障处理_第2张图片
    对比之下,我的情况跟这位朋友的一样。于是我关闭数据库继续拷贝了
    ib_logfile0、ib_logfile1和ibdata1这三个文件到以下路径(若已存在则覆盖)
    D:\company\database\MySQL_DATA\ib_logfile0
    D:\company\database\MySQL_DATA\ib_logfile1
    D:\company\database\MySQL_DATA\ibdata1

2.4 故障处理2-事务日志处理

 重新启动数据库net start MySQL57,**发现又出现了“MySQL57 服务无法启动,服务没有报告任何错误。”**

再次执行mysqld console
记一次MySQL生产环境故障处理_第3张图片
百度“Ignoring the redo log”找到一篇文章https://blog.csdn.net/baidu_31030715/article/details/82350026里面说把ib_logfile0和ib_logfile1这两个文件删除就可以了。
由于不了解这两个文件的作用,谨慎起见继续百度“ib_logfile”找到一篇
https://www.cnblogs.com/z-books/p/4285375.html了解到
记一次MySQL生产环境故障处理_第4张图片
由此可见,出现这个错误的原因就是MySQL启动时尝试读ib_logfile0和ib_logfile1进行事务重做。至此原因已经搞明白了。
为尽快恢复系统的使用,我将这两个文件删除,然后重新启动数据库。一切都恢复正常了。

2.5 故障处理3-数据验证

数据库是修复了,但是我删除的是系统重做日志呀,一个天大的问题是:我的数据到底有没有丢失?
于是赶紧用客户端连接服务器,然后查询业务表的数据,查看最新的数据时间。数据时间戳停留在2020-05-14 23:57.00.000 。根据业务性质判断,我的数据是物联网传感器数据,这个时间点已经接近设备下线时间。因此即使从这个时间段往后有业务数据,这些业务数据即使丢失也是不会有影响的。

3、故障处理总结

  1. 此次故障能及时发现得益于系统监控及钉钉机器人消息推送。
  2. 由于缺乏对数据库的深度理解,最终只能采取放弃部分数据的方式使生产环境的应用能够尽快恢复使用。
  3. 本次生产故障处理是否有丢失数据?丢失了多少笔数据?如何从redo文件中提取数据?这是一系列需要思考和研究的问题!

你可能感兴趣的:(SQL,mysql)