删库=跑路?不存在的,MySQL数据库数据恢复和回滚指南

411 阅读4分钟

本文已参与「新人创作礼」活动, 一起开启掘金创作之路。

前言

由于本地开发环境数据库在A市,现在要去B市出差。但是连不上A市的本地数据库,想着将开发数据库迁移到云上的自建数据库实例。同时自建数据库,没有做自动备份机制。自建数据库实例下,测试环境的数据库也在,并且数据库名字相同。同步数据的时候,开发数据库直接覆盖测试数据库。

需求

还原测试数据库的数据,避免污染。

备份当前测试数据库

在对测试数据库操作前,先进行数据备份,避免操作过程中失误,不可恢复。可通过转存SQL存储起来。

数据恢复

检查binlog开启状态

binlog是记录数据库操作中的增删改操作的日志。开启了binlog日志,数据库就会记录起来。可以通过binlog来恢复数据。

# 打开mysql的cmd界面,1234是数据库密码
mysql -uroot -p1234
# 查看binlog的开启状态,off是关闭,on是开启
show variables like 'log_bin';

image.png

show master logs;

image.png

# 查询binlog存储位置
show variables like '%datadir%';

image.png

然后退出mysql,找到mysqlbinlog命令的位置

which mysqlbinlog

image.png

切换到mysqlbinlog所在的目录

# 这一段是解析binlog里面的日志,变成可执行的sql
mysqlbinlog -v  /data/mysql/mysql-bin.000001  --start-position=302516810  --stop-position=344466416

# 如果要解析所有,就不需要start-pos,同理,也可以不需要stop-pos
mysqlbinlog -v  /data/mysql/mysql-bin.000001 

# 解析当前mysql-bin.000006里面的所有cloud数据库的日志,并在数据库中执行一次 。 -f 是强制覆盖
mysqlbinlog -v -d cloud /data/mysql/mysql-bin.000006 | mysql -uroot -p12345 -f

# 解析当前mysql-bin.000001里面的所有日志,并在数据库中重新执行一次
mysqlbinlog -v  /data/mysql/mysql-bin.000001  --start-position=302516810  --stop-position=344466416 | mysql -uroot -p12345 -f;

因为当前数据库是数据被覆盖,需求是回滚到某个时间点的数据即可。 但是未找到可回滚的数据库操作命令,因此,只能先把数据库导出备份。然后把数据库删除,从第一个binlog文件开始回放,从头开始再造一个数据库。 由于当前数据库没有做自动备份的机制,并且binlog中有大概50多个binlog文件。

先删除原有的数据库,再创建一个新的数据库和原来的数据库名字一样。但是表什么的都没有

从头开始跑binlog文件

# 从头开始跑binlog文件
mysqlbinlog -v -d cloud /data/mysql/mysql-bin.000001 | mysql -uroot -p12345 -f;

mysqlbinlog -v -d cloud /data/mysql/mysql-bin.000002 | mysql -uroot -p12345 -f;

mysqlbinlog -v -d cloud /data/mysql/mysql-bin.000003 | mysql -uroot -p12345 -f;
.......

一直跑到出问题的前一个binlog文件,数据量大也可以自己写一个脚本来跑。数据量小的,复制几次就可以了。 最后一个binlog,则要找到出问题前的一个sql的pos。 如何找到pos呢?用以下命令解析binlog文件并输出到一个binlog.txt文件,方便查看。

mysqlbinlog -v -d cloud /data/mysql/mysql-bin.000001 > binlog.txt

然后通过命令搜索导致数据库数据被覆盖或者删除的语句

# 搜索文件中删库的sql并且显示上下20条记录
cat binlog.txt | grep 'DROP DATABASE' -C 20

找到对应语句中的 edit_log_pos 就是pos的位置

最后执行下面的命令即可。

mysqlbinlog -v -d cloud /data/mysql/mysql-bin.000001  --start-position=302516810  --stop-position=344466416 | mysql -uroot -p12345 -f;

由此,数据恢复完成。

但是,有可能数据会有缺失,不保证百分百数据恢复

如果出现数据库授权出问题,由于数据是新的,原有账号的授权会自动删除 可先连上数据库cmd界面,查看账号信息的授权

# 查看账号授权信息
show grants for database_name@`%`;
# 重新授权
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, ALTER ON `database_name`.* TO '账号'@'%' identified by '密码'