由于执行更新update语句时,没有选中where语句,导致全表更新,万幸的是该表只是操作记录表,数据量也不大。
数据库日志格式
通过日志恢复数据的日志格式必须是Row。
下载binlog
通过阿里云管理界面下载binlog时间段内的文件
解析binlog
1 | mysqlbinlog -vv --base64-output=decode-rows mysql-bin.004489 | grep -B 15 '此处替换成要搜索的关键字' |
注:
如果通过mysqlbinlog解析binlog时遇到类似如下提示:
1 | ERROR: Error in Log_event::read_log_event(): 'Sanity check failed', data_len: 151, event_type: 35 |
请用户检查使用的mysqlbinlog是否版本较低,比如使用3.3版本会遇到上述错误提示无法正常解析binlog日志,使用较高版本,如3.4版本可以正常查看,这种情况下用户可以使用较高版本的mysqlbinlog
将binlog转换成SQL语句
1 | sed '/WHERE/{:a;N;/SET/!ba;s/\([^\n]*\)\n\(.*\)\n\(.*\)/\3\n\2\n\1/}' 3.log | sed 's/### //g;s/\/\*.*/,/g' | sed /@10/s/,//g | sed '/WHERE/{:a;N;/@10/!ba;s/,/AND/g};s/#.*//g;s/COMMIT,//g' | sed '/^$/d' > rollback.sql |
注:
@3 为最后一个变量。如果有20个变量,则此处为@20。
@2 此处#与@之前空格数为3个,不能多不能少。
分段解析
第一个sed 命令:
1 | sed '/WHERE/{:a;N;/SET/!ba;s/\([^\n]*\)\n\(.*\)\n\(.*\)/\3\n\2\n\1/}' update.sql |
第二个sed 命令:
1 | sed 's/### //g;s/\/\*.*/,/g' |
第三个sed 命令:
1 | sed /@10/s/,//g |
第四个sed 命令:
1 | sed '/WHERE/{:a;N;/@3/!ba;s/,/AND/g};s/#.*//g;s/COMMIT,//g' |
第五个sed 命令:
1 | sed '/^$/d' > rollback.sql |
将rollback.sql中的where语句后加(;)
如果后执行这句请将@10换成对应的列名即可
1 | sed -i -r '/WHERE/{:a;N;/@3/!ba;s/(@3=.*)/\1\;/g}' rollback.sql |
将@1,@2,@3…列转换为对应的列名
1 | sed -i 's/@1/f_id/g;s/@2/f_outing_id/g;s/@3/f_outing_date_id/;s/@4/f_order_id/;s/@5/f_order_member_id/;s/@6/f_operater_type/;s/@7/f_user_id/;s/@8/f_system_user_id/;s/@9/f_remark/;s/@10/f_create_time/g' rollback.sql |
数据格式化
将所有的换行替换成空格,此处用tr命令,因我的数据量比较大,tr执行效率相对较高,也可以用sed命令sed -i ‘:label;N;s/\n/ /;b label’ rollback.sql,效果都是一样的。
1 | cat rollback.sql | tr "\n" " " > new_rollback.sql |