mysqlbinlog恢复delete的数据

实验目的

delete数据后,用mysqlbinlog进行数据恢复

实验过程

原表

复制代码
mysql> select * from mytest;
+----+------+-------+
| id | name | score |
+----+------+-------+
|  1 | xw01 |    90 |
|  2 | xw02 |    92 |
|  3 | xw03 |    93 |
|  4 | xw04 |    94 |
|  5 | xw05 |    93 |
|  6 | xw06 |    96 |
|  7 | xw7  |    97 |
+----+------+-------+
7 rows in set (0.00 sec)

mysql>

# 查看binlog日志文件
root@dg02-xianwetitest-dy03:/var/log/mysql# ls
error.log  mysql-bin.000001  mysql-bin.000002  mysql-bin.index
root@dg02-xianwetitest-dy03:/var/log/mysql#



mysql> show binlog events in 'mysql-bin.000002' limit 10;
+------------------+-----+----------------+-----------+-------------+--------------------------------------------------------+
| Log_name         | Pos | Event_type     | Server_id | End_log_pos | Info                                                   |
+------------------+-----+----------------+-----------+-------------+--------------------------------------------------------+
| mysql-bin.000002 |   4 | Format_desc    |         1 |         123 | Server ver: 5.7.33-0ubuntu0.16.04.1-log, Binlog ver: 4 |
| mysql-bin.000002 | 123 | Previous_gtids |         1 |         154 |                                                        |
| mysql-bin.000002 | 154 | Anonymous_Gtid |         1 |         219 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'                   |
| mysql-bin.000002 | 219 | Query          |         1 |         291 | BEGIN                                                  |
| mysql-bin.000002 | 291 | Table_map      |         1 |         344 | table_id: 108 (test.mytest)                            |
| mysql-bin.000002 | 344 | Update_rows    |         1 |         408 | table_id: 108 flags: STMT_END_F                        |
| mysql-bin.000002 | 408 | Xid            |         1 |         439 | COMMIT /* xid=91 */                                    |
| mysql-bin.000002 | 439 | Anonymous_Gtid |         1 |         504 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'                   |
| mysql-bin.000002 | 504 | Query          |         1 |         576 | BEGIN                                                  |
| mysql-bin.000002 | 576 | Table_map      |         1 |         629 | table_id: 108 (test.mytest)                            |
+------------------+-----+----------------+-----------+-------------+--------------------------------------------------------+
10 rows in set (0.00 sec)





# 测试删除3行数据
mysql> delete from mytest where id=1 or id=2 or id=3;
Query OK, 3 rows affected (0.00 sec)

mysql> select * from mytest;
+----+------+-------+
| id | name | score |
+----+------+-------+
|  4 | xw04 |    94 |
|  5 | xw05 |    93 |
|  6 | xw06 |    96 |
|  7 | xw7  |    97 |
+----+------+-------+
4 rows in set (0.00 sec)

实验mysqlbin找到删除的命令

复制代码
mysql> show binlog events in 'mysql-bin.000002' ;
.... 此次省略部分输出
	| mysql-bin.000002 | 2811 | Query          |         1 |        2883 | BEGIN                                                                                                                                                                                                                     |
| mysql-bin.000002 | 2883 | Table_map      |         1 |        2936 | table_id: 115 (test.mytest)                                                                                                                                                                                               |
| mysql-bin.000002 | 2936 | Write_rows     |         1 |        2984 | table_id: 115 flags: STMT_END_F                                                                                                                                                                                           |
| mysql-bin.000002 | 2984 | Xid            |         1 |        3015 | COMMIT /* xid=331 */                                                                                                                                                                                                      |
| mysql-bin.000002 | 3015 | Anonymous_Gtid |         1 |        3080 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'                                                                                                                                                                                      |
| mysql-bin.000002 | 3080 | Query          |         1 |        3152 | BEGIN                                                                                                                                                                                                                     |
| mysql-bin.000002 | 3152 | Table_map      |         1 |        3205 | table_id: 115 (test.mytest)                                                                                                                                                                                               |
| mysql-bin.000002 | 3205 | Delete_rows    |         1 |        3282 | table_id: 115 flags: STMT_END_F                                                                                                                                                                                           |
| mysql-bin.000002 | 3282 | Xid            |         1 |        3313 | COMMIT /* xid=338 */                                                                                                                                                                                                      |
+------------------+------+----------------+-----------+-------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
47 rows in set (0.00 sec)


#找到"Delete_rows"对应所在的pos,是3080到3282
# 实验mysqlbin从binlog文件查找到删除对应的语句
root@dg02-xianwetitest-dy03:/var/log/mysql# mysqlbinlog  --start-position=3080  --stop-position=3282 --database=test mysql-bin.000002 -vv |grep ^"###"
### DELETE FROM `test`.`mytest`
### WHERE
###   @1=1 /* INT meta=0 nullable=0 is_null=0 */
###   @2='xw01' /* VARSTRING(60) meta=60 nullable=1 is_null=0 */
###   @3=90 /* INT meta=0 nullable=1 is_null=0 */
### DELETE FROM `test`.`mytest`
### WHERE
###   @1=2 /* INT meta=0 nullable=0 is_null=0 */
###   @2='xw02' /* VARSTRING(60) meta=60 nullable=1 is_null=0 */
###   @3=92 /* INT meta=0 nullable=1 is_null=0 */
### DELETE FROM `test`.`mytest`
### WHERE
###   @1=3 /* INT meta=0 nullable=0 is_null=0 */
###   @2='xw03' /* VARSTRING(60) meta=60 nullable=1 is_null=0 */
###   @3=93 /* INT meta=0 nullable=1 is_null=0 */



mysqlbinlog --start-position=3080 --stop-position=3282 --database=test mysql-bin.000002 -vv  | sed -n '/###/p' | sed 's/### //g;s/\/\*.*/,/g;s/DELETE FROM/INSERT INTO/g;s/WHERE/SELECT/g;' |sed -r 's/(@6.*),/\1;/g' | sed 's/@[1-9]=//g' | sed 's/@[1-9][0-9]=//g'
INSERT INTO `test`.`mytest`
SELECT
  1 ,
  'xw01' ,
  90 ,
INSERT INTO `test`.`mytest`
SELECT
  2 ,
  'xw02' ,
  92 ,
INSERT INTO `test`.`mytest`
SELECT
  3 ,
  'xw03' ,
  93 ,
  • 再用文本工具编译为恢复的sql语句,如果太多可以用bin2sql工具处理

    INSERT INTO test.mytest
    SELECT
    1 ,
    'xw01' ,
    90 ;
    INSERT INTO test.mytest
    SELECT
    2 ,
    'xw02' ,
    92 ;
    INSERT INTO test.mytest
    SELECT
    3 ,
    'xw03' ,
    93

  • 恢复数据

    mysql> INSERT INTO test.mytest
    -> SELECT
    -> 1 ,
    -> 'xw01' ,
    -> 90 ;
    Query OK, 1 row affected (0.00 sec)
    Records: 1 Duplicates: 0 Warnings: 0

    mysql> INSERT INTO test.mytest
    -> SELECT
    -> 2 ,
    -> 'xw02' ,
    -> 92 ;
    Query OK, 1 row affected (0.00 sec)
    Records: 1 Duplicates: 0 Warnings: 0

    mysql> INSERT INTO test.mytest
    -> SELECT
    -> 3 ,
    -> 'xw03' ,
    -> 93 ;
    Query OK, 1 row affected (0.00 sec)
    Records: 1 Duplicates: 0 Warnings: 0

  • 恢复后检查

    mysql> select * from mytest;
    +----+------+-------+
    | id | name | score |
    +----+------+-------+
    | 1 | xw01 | 90 |
    | 2 | xw02 | 92 |
    | 3 | xw03 | 93 |
    | 4 | xw04 | 94 |
    | 5 | xw05 | 93 |
    | 6 | xw06 | 96 |
    | 7 | xw7 | 97 |
    +----+------+-------+
    7 rows in set (0.00 sec)

另外如何用mysqlbinlog语言转换太麻烦可以用binlog2sql工具,使用方法如下

参考文档:https://juejin.cn/post/7150801079196712967

复制代码
root@dg02-xianwetitest-dy03:~/bin2sql/bin2sql/binlog2sql# /usr/bin/python2.7 binlog2sql/binlog2sql.py --start-position=3080 --stop-position=3282  --start-file='mysql-bin.000002' -h127.0.0.1  -uroot -proot@123 -dtest -tmytest
DELETE FROM `test`.`mytest` WHERE `score`=90 AND `id`=1 AND `name`='xw01' LIMIT 1; #start 3080 end 3282 time 2024-04-29 18:01:43
DELETE FROM `test`.`mytest` WHERE `score`=92 AND `id`=2 AND `name`='xw02' LIMIT 1; #start 3080 end 3282 time 2024-04-29 18:01:43
DELETE FROM `test`.`mytest` WHERE `score`=93 AND `id`=3 AND `name`='xw03' LIMIT 1; #start 3080 end 3282 time 2024-04-29 18:01:43
root@dg02-xianwetitest-dy03:~/bin2sql/bin2sql/binlog2sql#
root@dg02-xianwetitest-dy03:~/bin2sql/bin2sql/binlog2sql#
root@dg02-xianwetitest-dy03:~/bin2sql/bin2sql/binlog2sql#
root@dg02-xianwetitest-dy03:~/bin2sql/bin2sql/binlog2sql# /usr/bin/python2.7 binlog2sql/binlog2sql.py --start-position=3080 --stop-position=3282  --start-file='mysql-bin.000002' -h127.0.0.1  -uroot -proot@123 -dtest -tmytest -B
INSERT INTO `test`.`mytest`(`score`, `id`, `name`) VALUES (93, 3, 'xw03'); #start 3080 end 3282 time 2024-04-29 18:01:43
INSERT INTO `test`.`mytest`(`score`, `id`, `name`) VALUES (92, 2, 'xw02'); #start 3080 end 3282 time 2024-04-29 18:01:43
INSERT INTO `test`.`mytest`(`score`, `id`, `name`) VALUES (90, 1, 'xw01'); #start 3080 end 3282 time 2024-04-29 18:01:43


上面就是需要恢复数据的sql语句

实验总结

达到实验目的

相关推荐
longerxin202013 分钟前
MongoDB 在线安装-一键安装脚本(CentOS 7.9)
数据库·mongodb·centos
水无痕simon27 分钟前
3 水平分表
java·数据库
恣艺35 分钟前
探索数据库世界:从基础类型到实际应用
数据库
小钻风33661 小时前
IDEA连接redis数据库时出现Failed to connect to any host resolved for DNS name.
数据库
ulias2121 小时前
单元最短路问题
数据库·c++·算法·动态规划
安卓开发者1 小时前
鸿蒙NEXT中SQLite数据库全面实战指南
数据库·sqlite·harmonyos
xuejianxinokok2 小时前
PostgreSQL 18 新功能:虚拟生成列
数据库·后端
知其然亦知其所以然2 小时前
MySQL8.x 面试高频题:为什么一定要有主键?99%的人答不全
后端·mysql·面试
DemonAvenger2 小时前
MySQL索引失效全解析:从分析到优化,10年经验实战分享
数据库·mysql·性能优化
咖啡Beans2 小时前
踩坑无数!MySQL UNION和ORDER BY混用的血泪教训,看完不再翻车
数据库·mysql