浏览文章

文章信息

Mysql数据库恢复时间段数据 12991

1、查看数据库日志

mysql>show master logs;

2、查看数据库日志事件

mysql>show binlog events in 'mysql-bin.000153';

3、检查到日志破坏的点pos或者时间段

mysqlbinlog -d ods --skip-gtids=true 
--start-datetime=“2020-04-23 9:54:26” 
--stop-datetime=“2020-04-24 9:56:09” 
/home/mysql/log/mysql-bin.000004 |mysql -uroot -p

4、mysqlbinlog日志语法

恢复命令的语法格式:

mysqlbinlog mysql-bin.0000xx | mysql -u用户名 -p密码 数据库名

--------------------------------------------------------

常用参数选项解释:

--start-position=875 起始pos点

--stop-position=954 结束pos点

--start-datetime="2016-9-25 22:01:08" 起始时间点

--stop-datetime="2019-9-25 22:09:46" 结束时间点

--database=zyyshop 指定只恢复zyyshop数据库(一台主机上往往有多个数据库,只限本地log日志)

--------------------------------------------------------

不常用选项:

-u --user=name 连接到远程主机的用户名

-p --password[=name] 连接到远程主机的密码

-h --host=name 从远程主机上获取binlog日志

--read-from-remote-server 从某个MySQL服务器上读取binlog日志

--------------------------------------------------------

小结:实际是将读出的binlog日志内容,通过管道符传递给mysql命令。这些命令、文件尽量写成绝对路径;


a)完全恢复(需要手动vim编辑mysql-bin.000003,将那条drop语句剔除掉)

[root@vm-002 backup]# cp /var/lib/mysql/mysql-bin.000003 /opt/backup

[root@vm-002 backup]# mysqlbinlog /opt/backup/mysql-bin.000003 > /opt/backup/000003.sql

[root@vm-002 backup]# vim /opt/backup/000003.sql #删除里面的drop语句

[root@vm-002 backup]# mysql -uroot -p -v < /opt/backup/000003.sql

温馨提示:

在恢复全备数据之前必须将该binlog文件移出,否则恢复过程中,会继续写入语句到binlog,最终导致增量恢复数据部分变得比较混乱!

可参考:https://www.cnblogs.com/kevingrace/p/5904800.html

b)指定pos结束点恢复(部分恢复):

--stop-position=471 pos结束节点(按照事务区间算,是471)

注意:

此pos结束节点介于“member表原始数据”与更新“name='李四'”之前的数据,这样就可以恢复到更改“name='李四'”之前的数据了。

操作如下:

[root@vm-002 ~]# /usr/bin/mysqlbinlog --stop-position=471 --database=ops /var/lib/mysql/mysql-bin.000003 | /usr/bin/mysql -uroot -p123456 -v ops

mysql> select * from member;

+----+-----------+-----+-----+---------+

| id | name | sex | age | classid |

+----+-----------+-----+-----+---------+

| 1 | wangshibo | m | 27 | cls1 |

| 2 | guohuihui | w | 27 | cls2 |

| 3 | yiyi | w | 20 | cls1 |

| 4 | xiaoer | m | 22 | cls3 |

| 5 | zhangsan | w | 21 | cls5 |

| 6 | lisi | m | 20 | cls4 |

| 7 | wangwu | w | 26 | cls6 |

+----+-----------+-----+-----+---------+

7 rows in set (0.00 sec)

恢复截止到更改“name='李四'”之间的数据(按照事务区间算,是673)

[root@vm-002 ~]# /usr/bin/mysqlbinlog --stop-position=673 --database=ops /var/lib/mysql/mysql-bin.000003 | /usr/bin/mysql -uroot -p123456 -v ops

mysql> select * from member;

+----+-----------+-----+-----+---------+

| id | name | sex | age | classid |

+----+-----------+-----+-----+---------+

| 1 | wangshibo | m | 27 | cls1 |

| 2 | guohuihui | w | 27 | cls2 |

| 3 | yiyi | w | 20 | cls1 |

| 4 | 李四 | m | 22 | cls3 |

| 5 | zhangsan | w | 21 | cls5 |

| 6 | lisi | m | 20 | cls4 |

| 7 | wangwu | w | 26 | cls6 |

+----+-----------+-----+-----+---------+

7 rows in set (0.00 sec)

c)指定pso点区间恢复(部分恢复):

更新 name='李四' 这条数据,日志区间是Pos[538] --> End_log_pos[646],按事务区间是:Pos[471] --> End_log_pos[673]

更新 name='小二' 这条数据,日志区间是Pos[740] --> End_log_pos[848],按事务区间是:Pos[673] --> End_log_pos[875]

c1)

单独恢复 name='李四' 这步操作,可这样:

按照binlog日志区间单独恢复:

[root@vm-002 ~]# /usr/bin/mysqlbinlog --start-position=538 --stop-position=646 --database=ops /var/lib/mysql/mysql-bin.000003 | /usr/bin/mysql -uroot -p123456 -v ops

按照事务区间单独恢复

[root@vm-002 ~]# /usr/bin/mysqlbinlog --start-position=471 --stop-position=673 --database=ops /var/lib/mysql/mysql-bin.000003 | /usr/bin/mysql -uroot -p123456 -v ops

c2)

单独恢复 name='小二' 这步操作,可这样:

按照binlog日志区间单独恢复:

[root@vm-002 ~]# /usr/bin/mysqlbinlog --start-position=740 --stop-position=848 --database=ops /var/lib/mysql/mysql-bin.000003 | /usr/bin/mysql -uroot -p123456 -v ops

按照事务区间单独恢复

[root@vm-002 ~]# /usr/bin/mysqlbinlog --start-position=673 --stop-position=875 --database=ops /var/lib/mysql/mysql-bin.000003 | /usr/bin/mysql -uroot -p123456 -v ops

c3)

将 name='李四'、name='小二' 多步操作一起恢复,需要按事务区间,可这样:

[root@vm-002 ~]# /usr/bin/mysqlbinlog --start-position=471 --stop-position=875 --database=ops /var/lib/mysql/mysql-bin.000003 | /usr/bin/mysql -uroot -p123456 -v ops

查看数据库:

mysql> select * from member;

+----+-----------+-----+-----+---------+

| id | name | sex | age | classid |

+----+-----------+-----+-----+---------+

| 1 | wangshibo | m | 27 | cls1 |

| 2 | 小二 | w | 27 | cls2 |

| 3 | yiyi | w | 20 | cls1 |

| 4 | 李四 | m | 22 | cls3 |

| 5 | zhangsan | w | 21 | cls5 |

| 6 | lisi | m | 20 | cls4 |

| 7 | wangwu | w | 26 | cls6 |

+----+-----------+-----+-----+---------+

7 rows in set (0.00 sec)

这样,就恢复了删除前的数据状态了!!

=====================================================

另外:也可以指定时间节点区间恢复(部分恢复),就是说除了用pos节点的办法进行恢复,也可以通过指定时间节点区间进行恢复,

按时间恢复需要用mysqlbinlog命令读取binlog日志内容,找时间节点。

如上,误删除ops库后:

先进行全备份恢复

[root@vm-002 backup]# mysql -uroot -p -v < ops_2016-09-25.sql

查看ops数据库

mysql> select * from member;

+----+-----------+-----+-----+---------+

| id | name | sex | age | classid |

+----+-----------+-----+-----+---------+

| 1 | wangshibo | m | 27 | cls1 |

| 2 | guohuihui | w | 27 | cls2 |

+----+-----------+-----+-----+---------+

2 rows in set (0.00 sec)

mysql>

查看mysq-bin00003日志,找出时间节点

[root@vm-002 ~]# cd /var/lib/mysql

[root@vm-002 mysql]# mysqlbinlog mysql-bin.000003

.............

.............

BEGIN

/*!*/;

# at 173

#160925 21:57:19 server id 1 end_log_pos 201 Intvar

SET INSERT_ID=3/*!*/;

# at 201

#160925 21:57:19 server id 1 end_log_pos 444 Query thread_id=3 exec_time=0 error_code=0

use `ops`/*!*/;

SET TIMESTAMP=1474811839/*!*/;

insert into ops.member(`name`,`sex`,`age`,`classid`) values('yiyi','w',20,'cls1'),('xiaoer','m',22,'cls3'),('zhangsan','w',21,'cls5'),('lisi','m',20,'cls4'),('wangwu','w',26,'cls6')                               #执行的sql语句

/*!*/;

# at 444

#160925 21:57:19 server id 1 end_log_pos 471 Xid = 66    #开始执行的时间

COMMIT/*!*/;

# at 471

#160925 21:58:41 server id 1 end_log_pos 538 Query thread_id=3 exec_time=0 error_code=0    #结束时间

SET TIMESTAMP=1474811921/*!*/;

BEGIN

/*!*/;

# at 538

#160925 21:58:41 server id 1 end_log_pos 646 Query thread_id=3 exec_time=0 error_code=0

SET TIMESTAMP=1474811921/*!*/;

update ops.member set name='李四' where id=4     #执行的sql语句

/*!*/;

# at 646

#160925 21:58:41 server id 1 end_log_pos 673 Xid = 68    #开始执行的时间

COMMIT/*!*/;

# at 673

#160925 21:58:56 server id 1 end_log_pos 740 Query thread_id=3 exec_time=0 error_code=0   #结束时间

SET TIMESTAMP=1474811936/*!*/;

BEGIN

/*!*/;

# at 740

#160925 21:58:56 server id 1 end_log_pos 848 Query thread_id=3 exec_time=0 error_code=0

SET TIMESTAMP=1474811936/*!*/;

update ops.member set name='小二' where id=2      #执行的sql语句

/*!*/;

# at 848

#160925 21:58:56 server id 1 end_log_pos 875 Xid = 69   #开始执行的时间

COMMIT/*!*/;

# at 875

#160925 22:01:08 server id 1 end_log_pos 954 Query thread_id=3 exec_time=0 error_code=0    #结束时间

SET TIMESTAMP=1474812068/*!*/;

drop database ops

/*!*/;

# at 954

#160925 22:09:46 server id 1 end_log_pos 997 Rotate to mysql-bin.000004 pos: 4

DELIMITER ;

# End of log file

ROLLBACK /* added by mysqlbinlog */;

/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;

恢复到更改“name='李四'”之前的数据

[root@vm-002 ~]# /usr/bin/mysqlbinlog --start-datetime="2016-09-25 21:57:19" --stop-datetime="2016-09-25 21:58:41" --database=ops /var/lib/mysql/mysql-bin.000003 | /usr/bin/mysql -uroot -p123456 -v ops

mysql> select * from member;

+----+-----------+-----+-----+---------+

| id | name | sex | age | classid |

+----+-----------+-----+-----+---------+

| 1 | wangshibo | m | 27 | cls1 |

| 2 | guohuihui | w | 27 | cls2 |

| 3 | yiyi | w | 20 | cls1 |

| 4 | xiaoer | m | 22 | cls3 |

| 5 | zhangsan | w | 21 | cls5 |

| 6 | lisi | m | 20 | cls4 |

| 7 | wangwu | w | 26 | cls6 |

+----+-----------+-----+-----+---------+

7 rows in set (0.00 sec)

[root@vm-002 ~]# /usr/bin/mysqlbinlog --start-datetime="2016-09-25 21:58:41" --stop-datetime="2016-09-25 21:58:56" --database=ops /var/lib/mysql/mysql-bin.000003 | /usr/bin/mysql -uroot -p123456 -v ops

mysql> select * from member;

+----+-----------+-----+-----+---------+

| id | name | sex | age | classid |

+----+-----------+-----+-----+---------+

| 1 | wangshibo | m | 27 | cls1 |

| 2 | guohuihui | w | 27 | cls2 |

| 3 | yiyi | w | 20 | cls1 |

| 4 | 李四 | m | 22 | cls3 |

| 5 | zhangsan | w | 21 | cls5 |

| 6 | lisi | m | 20 | cls4 |

| 7 | wangwu | w | 26 | cls6 |

+----+-----------+-----+-----+---------+

7 rows in set (0.00 sec)

[root@vm-002 ~]# /usr/bin/mysqlbinlog --start-datetime="2016-09-25 21:58:56" --stop-datetime="2016-09-25 22:01:08" --database=ops /var/lib/mysql/mysql-bin.000003 | /usr/bin/mysql -uroot -p123456 -v ops

mysql> select * from member;

+----+-----------+-----+-----+---------+

| id | name | sex | age | classid |

+----+-----------+-----+-----+---------+

| 1 | wangshibo | m | 27 | cls1 |

| 2 | 小二 | w | 27 | cls2 |

| 3 | yiyi | w | 20 | cls1 |

| 4 | 李四 | m | 22 | cls3 |

| 5 | zhangsan | w | 21 | cls5 |

| 6 | lisi | m | 20 | cls4 |

| 7 | wangwu | w | 26 | cls6 |

+----+-----------+-----+-----+---------+

7 rows in set (0.00 sec)

这样,就恢复了删除前的状态了!

总结:所谓恢复,就是让mysql将保存在binlog日志中指定段落区间的sql语句逐个重新执行一次而已。


原创