关于mysql:记一次断电导致的mysql数据恢复问题

5次阅读

共计 3133 个字符,预计需要花费 8 分钟才能阅读完成。

最近在做监控零碎选型,咱们将监控零碎分为两类:监控和追踪,本篇次要讲断电导致的服务器呈现的问题以及解决方案,对于监控零碎就不多做介绍了。市面上支流的监控零碎次要是 zabbix、open-falcon、promethues,明天的配角是 zabbix,也就是这次是在搭建 zabbix 并监控 jvm 以及服务器信息之后呈现的断电。
问题
1、服务器启动失败;
2、mysql 启动失败;

通过

周五的时候搭建好了 zabbix 并且在继续运行,所有都失常,周日的时候忽然断电导致服务器关机了,本想着重启一下服务器,登上去之后重新启动所有利用即可,后果却连服务器零碎都进不去,间接提醒进入紧急模式(过后没有截图截图,只能自行脑补了。。),依据提醒输出 journal 查看到日志中提醒 sda3 磁盘分区挂了。

服务器启动失败解决

晓得是磁盘分区挂了,就很容易想到是磁盘在继续写入的时候忽然断电导致的,那咱们要做的就是对磁盘分区进行修复。对于 xsf 文件系统的修复很简略,出错的时候 linux 也会提醒倡议计划,咱们只须要依据提醒进行修复即可:
xfs_repair /dev/sda3

mysql 启动失败

零碎终于可能失常进入了,下一步就是启动利用了,对于 zabbix,我装置的时候是基于 mysql 数据库去装置的,所以先启动 mysql 数据库,原本认为会一步到位,后果 mysql 又给了我当头一棒,间接启动失败,谬误如下:

这个看不出来具体什么起因导致的,下一步去日志里看看,关上日志后果如下:

从日志中能够看出,断电的时候因为数据还在继续写入,所以数据损坏了,日志里也提到了解决方案:

于是关上该网址试试:

加这一行即可,通过材料查到这个是要加在 mysql 启动的配置文件 my.cnf 中,然而我找遍了各种门路也找不到 my.cnf 文件 (查看命令:mysqld –verbose –help |grep -A 1 ‘Default options’),找 dba 帮我建了一个在 etc 目录下,加了如下内容:

通过搜寻发现 mysql 不必 my.cnf 也能启动,只是会用默认值进行启动,而如果你想要笼罩 mysql 的默认行为,则能够通过 my.cnf 进行配置。这里把 innodb_force_recovery 改为 1 之后还是启动不了,一直往上加,始终到 3 才终于启动胜利。然而这个参数可不是设置越大越好,他只是为了让你能先启动数据库,进行数据备份之类的操作,对于该参数的阐明,我也截了一张图:

看到最初一行备注了吗,大于 0 的时候就无奈进行更改类操作了,所以相当于还是没有用。
网上找了一圈,大体是无奈失常应用了,只能先进行数据备份,而后删除坏表或者重建数据库。
在断电的时候,只有 zabbix 数据库是始终在应用的,所以第一个想到的是删除 zabbix 数据库(当然失常状况下咱们也能够应用 check table tableName 来查看坏表),这样就删除了坏表了。执行删除操作

完了,删都删不掉,那只能采纳重建数据库的操作了。

重建数据库

首先咱们须要将所有数据导出来,这里写了一个脚本不便导出:

backupdir=/usr/local/mysql/dumpdir
cd ${backupdir}
cur_date=`date '+%Y%m%d'`
if [! -d ${cur_date}  ];then
   mkdir ${cur_date}
fi
cd ${cur_date}
cur_time=`date '+%H%M%S'`
db_names=(dbName1 dbName2 dbName3)
for db_name in ${db_names[*]}
do
    mkdir ${db_name}
    for table in `mysql -uroot -pyourpassword -e "show tables from ${db_name}" | sed '1d'`
    do
        mysqldump -uroot -pyourpassword ${db_name} ${table} >./"${db_name}"/${table}."${cur_time}".sql
    done
done

通过运行以上 shell 脚本就能实现所有数据导出了。前面开始重建数据库:
1、手动删除 mysql 的 data 目录;
2、如果 mysqld 服务启着,则 mysqld -remove MySQL 进行移除;
3、mysqld –initialize-insecure,这一步 mysql 会主动创立新的 data 目录;
4、如果第二步移除掉,则这里须要再增加,mysqld –install;
5、如果启动的时候提醒 sock 地址被占用,则先删除已存在的 sock 文件,比方我的 sock 文件是 tmp/mysql.sock 文件,当然把对应的 sock.lock 也一并删除了;
以上几步全副做完之后,启动 mysql 就胜利了

上面开始创立用户
先用 root 用户间接登录(mysql -uroot),看一下目前的用户

4 个用户,mysql8 对于明码的认证形式默认应用 caching_sha2_password,给 root 创立一个近程登录权限(我本人用的就是 root 近程登录),mysql8 的话创立用户时记得加 with mysql_native_password,如果你的客户端用的是 mysql5 的驱动。

ok,开始导入数据,同样也写了一个 shell 脚本进行导入。

for db in `ls /usr/local/dumpdir/20210324/`;
do
    echo "source /usr/local/dumpdir/import/${db}.sql;" >> /usr/local/dumpdir/import.sql
    echo "CREATE DATABASE IF NOT EXISTS $db DEFAULT CHARSET utf8 COLLATE utf8_general_ci;" >> /usr/local/dumpdir/import/${db}.sql;
    echo "use ${db};" >> /usr/local/dumpdir/import/${db}.sql;
    for i in `ls /usr/local/dumpdir/20210324/${db}/` ;
    do
        echo "source /usr/local/dumpdir/20210324/${db}/$i;" >> /usr/local/dumpdir/import/${db}.sql;
    done
done

登录 mysql 之后,运行以下命令执行导入操作:
source /usr/local/dumpdir/import.sql

到此为止,所有数据都复原了,当然断电的时候失落的那局部坏数据是没法复原了。
最初给对应的用户调配指定数据库的权限就能够了。

附 mysql 相干脚本:

创立用户:create user ‘user’@’host’ with mysql_native_password identity by ‘password’;(8.0 客户端不须要加 with mysql_native_password)
给用户指定某表所有权限:grant all privileges on databaseName.* to targetUserName@”%”;

总结

咱们平时的生产环境还是要做好数据备份和数据库高可用,因为一旦呈现断电这类问题,复原时遇到的问题比拟多而且造成的损失也很大。

参考资料

https://blog.csdn.net/theolds…
https://blog.csdn.net/edyf123…
https://blog.csdn.net/weixin_…
https://blog.csdn.net/qq_3659…
https://blog.csdn.net/zengxue…
https://www.bootwiki.com/note…

正文完
 0