MySQL数据误删或者误更新怎样规复(具体步调,一看就会)
本篇文章适用场景①、测试环境少量近期误删除或者误更新的数据规复。
②、测试环境少量从库数据不一致题目。
备注:大量数据的规复或者复制还是需要使用备份数据,比方使用mysqldump或者Mydumper、mysqlshell。(本篇文章对此不做讨论)
告诫:数据规复为DBA专业人员负责处理的事变,本文章仅为开发人员测试环境规复近期误操纵的少量数据提供参考。
请对生产环境数据心存敬畏~
一、下载MyFlash工具
# 创建文件夹
mkdir/web
cd /web
# 下载压缩包
wget https://codeload.github.com/Meituan-Dianping/MyFlash/zip/master
# 安装编译相关软件
yum install gcc -y
yum install glib2 glib2-devel -y
# 解压缩包
unzip master
# 进入软件目录
cd /web/MyFlash-master
# 编译
sh build.sh
编译完成后:
https://i-blog.csdnimg.cn/direct/127696bbb5e94eb080e78c57507f9385.png
验证:
cd /web/MyFlash-master/binary
./flashback --help
输入:
https://i-blog.csdnimg.cn/direct/deabd5865567477a86d7c373321e3f4d.png
MyFlash工具 安装完成
二、误删数据规复
先查抄MySQL有没有开启binlog日志
SHOW VARIABLES LIKE 'log_%';
https://i-blog.csdnimg.cn/direct/d9133fc2ca8e4ba18fe17295b461af8b.png
如果发现数据库未开启binlog,那么这次规复数据的旅程到此结束~
下面进入亡羊补牢时候 (如果已经开启了 跳过这个步调)。
打开MySQL的binlog日志:
# 找到MySQL的配置文件(一般情况下这样都能找到,找不到就要去问DBA或者运维了)
find / -name my.cnf
一样平常环境下都是在 下面这个目次
https://i-blog.csdnimg.cn/direct/01cbe6be7bee405eb4bde7fa7eca9ee0.png
添加配置:
vi /etc/my.cnf
添加一下配置
# 如果有集群这个id不用重复
server_id =6
# binlog日志位置
log_bin =/web/mysql/binlog/mysql-bin
# binlog日志格式
binlog_format =row
重启MysQL
# 如果 systemctl 无法重启就直接进入mysqld所在的目录重启
systemctl restart mysqld
演示误删除数据
先了解一些下令 后续要用到
# 查看所有binglog日志
SHOW MASTER LOGS;
# 当前使用的日志
show master status;
# 查看日志记录
show binlog events in '日志文件名';
下面开始演示:
先看下当前使用的binlog日志是哪个
# 当前使用的日志
show master status;
https://i-blog.csdnimg.cn/direct/416fc07fa31b4ac88ad8eed6e74f28bf.png
可以看到我现在的数据库使用的是 mysql-bin.000003 这个binlog日志
现在我有一张表 t_ph_uc_login
https://i-blog.csdnimg.cn/direct/f8a7a488e42c4b23b610ecf57f6d6b76.png
假如我误删了 t_ph_uc_login 表中的某条数据
这里我删除 id为 10f7a6c619e14b228df0e226bd84db5c 的数据
https://i-blog.csdnimg.cn/direct/7d1e216e7f6a486a9d5237ceda3be3be.png
DELETE FROM `t_ph_uc_login` WHERE id = '10f7a6c619e14b228df0e226bd84db5c';
此时再查已经查不到这条数据了:
https://i-blog.csdnimg.cn/direct/e32b8b63d54a40b7be0f8ef28c6ed84b.png
一样平常环境下我们并不知道到底删除的是哪条数据,更不知道删除数据的id。
我一开始说的前提是这种方法得当最近误操纵的数据规复。
下面我们去查看binlog日志。
# 查看日志记录
SHOW BINLOG EVENTS IN 'mysql-bin.000003';
我查到了3258行,经常更新的表一定比这个数值大得多。所以我们要查看最后几十行就行。
https://i-blog.csdnimg.cn/direct/66a9159536ba496f9f6665d0b9ce6f67.png
这里使用分页查看最后几百条数据:
SHOW BINLOG EVENTS IN 'mysql-bin.000003' LIMIT 300 OFFSET 3000;
https://i-blog.csdnimg.cn/direct/37b6999ce8a04e2ea07cc674569c5a38.png
我们可以在最后几行中找到 删除相关的语句,并记载下事件开始设置时的位置 (Pos列的数字),和事件提交时的位置(End_log_pos列的数字)。
**注意图中蓝色标注框 **
开始: 11138303
结束: 11138917
使用MyFlash工具 反写SQL
把delete语句反写成insert语句
cd /web/MyFlash-master/binary
./flashback --databaseNames="phoenix-saas" --tableNames="t_ph_uc_login" --sqlTypes="delete" --start-position=11138303 --stop-position=11138917 --binlogFileNames=/web/mysql/binlog/mysql-bin.000003--outBinlogFileNameBase=/web/recover.log
注意:上面数据库名称,表名称,sql范例 要根据自身需求改动,输出的文件也可以根据需求改动,我这里就输出在/web目次下了
尤其需要注意 --start-position 和 -stop-position 的数值 如果填的不对 很大概会报下面的错
如果报了下面的错就要好好查抄下 --start-position 和 -stop-position 的数值 取的对不对了
Segmentation fault (core dumped)
如果执行成功 就能看到下面红框的文件:
https://i-blog.csdnimg.cn/direct/427957f42121486fbb14037d5e015170.png
由于MyFlash工具反写的数据也是二进制文件,所以还需要使用MySQL自带的 mysqlbinlog工具来执行
这里还可以用mysqlbinlog把二进制文件recover.log.flashback 解析成文本文件看下(这一步仅仅是看看 规复数据可跳过这步)
# 先找一下mysqlbinlog在哪
find / -name mysqlbinlog
# 我的mysqlbinlog在/web/mysql/bin/mysqlbinlog文件夹中
cd /web/mysql/bin
# 解析查看二进制文件recover.log.flashback
mysqlbinlog -v /web/recover.log.flashback
可以看到MyFlash工具 已经把
上面我执行的delete语句反写成INSERT语句了
DELETE FROM `t_ph_uc_login` WHERE id = '10f7a6c619e14b228df0e226bd84db5c';
https://i-blog.csdnimg.cn/direct/773504379c004d83921328b238981777.png
使用mysqlbinlog 执行反写的sql二进制文件
最后一步使用mysqlbinlog 工具执行 反写的二进制文件 recover.log.flashback
# 先到 mysqlbinlog 所在的文件夹
cd /web/mysql/bin
# 恢复数据
mysqlbinlog-v /web/recover.log.flashback | mysql -u用户名 -p密码
注意上面要输入自己数据库的用户名和密码
如果不报错 就说明数据规复完成了。
如果报错下面的错:
ERROR 1782 (HY000) at line 17: @@SESSION.GTID_NEXT cannot be set to ANONYMOUS when @@GLOBAL.GTID_MODE = ON.
使用下面的语句查看是否开启了 全局事件ID (GTID) 功能
SELECT @@GLOBAL.GTID_MODE;
下图就是开启了。
https://i-blog.csdnimg.cn/direct/2b4baf3205054739aec94b9773b4cf71.png
可以 通过参数 --skip-gtids 跳过,不把gtid信息写到binlog中。不外如果数据库是多主或者一主多从的环境大概从库会出现数据一致。
#--skip-gtids跳过gtid信息
mysqlbinlog-v /web/recover.log.flashback--skip-gtids| mysql -u用户名 -p密码
规复完成
执行完成后 再查询被删除的数据,可以发现已经规复了。
https://i-blog.csdnimg.cn/direct/00fb58070ec94958bc59d2751b53a39f.png
三、误更新数据规复
基本流程和上面误删除的规复流程一致
演示误更新数据
还是拿id为 10f7a6c619e14b228df0e226bd84db5c 这条数据测试:
误更新前 user_id = 04f1fd53a4554e3fb5c9a40463a4ea4c
https://i-blog.csdnimg.cn/direct/9689a31537c3472bbec7680535de57d1.png
开始误更新
UPDATE `t_ph_uc_login` SET user_id = '小明' WHERE id = '10f7a6c619e14b228df0e226bd84db5c';
误更新后:
https://i-blog.csdnimg.cn/direct/46212cb67cb04d82b53ba06915cb0e50.png
假如我们不知道 误更新之前的user_id 是什么
查看binlog最近的更新记载 ,确定起始、结束位置
SHOW MASTER STATUS;
https://i-blog.csdnimg.cn/direct/55de108b4d424e48ab0d769479f3986b.png
SHOW BINLOG EVENTS IN 'mysql-bin.000004'
https://i-blog.csdnimg.cn/direct/b8ee80d78a1a40edbcd353e810320377.png
这里再细说下 找position的技巧吧
这次是更新 那就先找 Update_rows ,找到后 往上找 INFO列的 BEGIN,再往上一行, SET @@SESSION.GTID_NEXT 设置全局事件ID的这行就是这次更新事件的始位置。开始position就确定了。
开始: 1159
顺着Update_rows 再往下找,找到INFO列的 最近的一个COMMIT,这行的 End_log_pos列就是 结束position
结束: 1929
使用MyFlash工具 反写SQL
这里update 还是会被反写成update
cd /web/MyFlash-master/binary
./flashback --databaseNames="phoenix-saas" --tableNames="t_ph_uc_login" --sqlTypes="update" --start-position=1159 --stop-position=1929 --binlogFileNames=/web/mysql/binlog/mysql-bin.000004--outBinlogFileNameBase=/web/recover.log
使用mysqlbinlog 执行反写的sql二进制文件
#--skip-gtids跳过gtid信息
mysqlbinlog-v /web/recover.log.flashback--skip-gtids| mysql -u用户名 -p密码
规复完成
再查一下 可以看到 user_id 已经规复了
https://i-blog.csdnimg.cn/direct/17192c66c6774bf0ac985aa773095787.png
补充点 flush logs
如果当前数据库 还有大量连接正在更新 可以执行flush logs 重新天生新的binlog日志
比如现在的日志名是001 执行 flush logs 后 ,会天生一个002的文件 ,而且当前会使用002文件记载
那你再去找001文件的position时 就不会受到干扰了
四、告诫
非专业DBA请勿在生产环境操纵上述过程~
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]