恢复MySQL数据到误删的表之前的数据

一、演示环境说明:

系统CentOS Linux release 7.2.1511 (Core) X_86 64位最小化安装
mysql版本是官方二进制版本5.7.22-22,mysql采用的是二进制安装,单机上开启2个mysql实例,mysql实例要开启定时器event_scheduler=ON. 而且2个mysql实例都要开启Gtid
xtrabackup 采用的是rpm包安装,版本是version 2.4.13

MySQL备份方式采用每天一次全量备份和binlog增量备份

二、模拟删除库,进行数据恢复演示:

提示:当然此处只是演示,严禁生成环境删库,删表模拟,后果你懂得

故障模拟:
线上误删除一个testdb库下的test1_event表,利用当天的mysql的全量备份+当天生成的mysql的binlog文件来恢复数据到误删的表test1_event之前的数据
恢复方式介绍:
官方推荐采用利用mysql binlog方式恢复,生产实践验证官方的这个方式已经是不严谨的做法了(下面的方法是官方推荐的)

故障恢复过程如下:
2.1接收到误删除之前,第一时间确认大概误操作时间
2.2 登录主库查看当前的binlog位置点(要记住此时的binlog文件,后面恢复时会用到)

([email protected]‘mgr01‘:mysql3306.sock)[testdb]>show master status\G
*************************** 1. row ***************************
             File: mysql-bin.000005
         Position: 15211
     Binlog_Do_DB:
 Binlog_Ignore_DB:
Executed_Gtid_Set: bde7b592-b966-11e9-8c64-000c294f3e61:1-10445
1 row in set (0.00 sec)

2.3最好是flush logs下,让接下来的sql写入到新的binlog文件
2.4定位drop 表语句所在binglog文件的位置点:

[[email protected] binlog]#  mysqlbinlog -v --base64-output=decode-rows   /data/mysql/mysql3306/binlog/mysql-bin.000005|grep -i -C 15 drop
###   @1=10422
###   @2=‘tomcat‘
###   @3=‘xiaohuahua‘
###   @4=‘2019-08-08 14:22:18‘
# at 14987
#190808 14:22:18 server id 63306  end_log_pos 15018 CRC32 0x873943dd    Xid = 20695
COMMIT/*!*/;
#at15018###################################
#190808 14:22:19 server id 63306  end_log_pos 15083 CRC32 0xcc8773ce    GTID    last_committed=34   sequence_number=35  rbr_only=no
SET @@SESSION.GTID_NEXT= ‘bde7b592-b966-11e9-8c64-000c294f3e61:10445‘/*!*/;
#at 15083
#190808 14:22:19 server id 63306  end_log_pos 15211 CRC32 0x8d445019    Query   thread_id=7213  exec_time=0 error_code=0
use `testdb`/*!*/;
SET TIMESTAMP=1565245339/*!*/;
SET @@session.sql_auto_is_null=0/*!*/;
DROP TABLE `test1_event` /* generated by server */
/*!*/;
SET @@SESSION.GTID_NEXT= ‘AUTOMATIC‘ /* added by mysqlbinlog */ /*!*/;
DELIMITER ;
#End of log file
/*!50003 SET [email protected]_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;

定位到15018 这个位置点就是利用binlog的文件恢复时的结束点

2.5恢复xtrabackup备份到 mysql3308 实例上:
提示:mysql 3308实例要开启Gtid的

恢复备份的命令:

innobackupex --apply-log /data/backup/db_3306_20190808/
innobackupex  --defaults-file=/data/mysql/mysql3308/my3308.cnf --copy-back /data/backup/db_3306_20190808/

给数据目录data mysql 权限:

 chown -R mysql.mysql /data/mysql/mysql3308/data/

启动mysql3308 实例:

/usr/local/mysql/bin/mysqld --defaults-file=/data/mysql/mysql3308/my3308.cnf   &

查看到恢复到3308实例的数据,但是在备份3306库到删除表test1_event 这时间段还存在很多缺失的数据未找回,要从增量的binlog文件中找回:

| 10273 | tomcat   | xiaohuahua | 2019-08-08 14:17:16 |
| 10274 | tomcat   | xiaohuahua | 2019-08-08 14:17:18 |
+-------+----------+------------+---------------------+

([email protected]‘mgr01‘:mysql3308.sock)[testdb]>select count(*) from test1_event;
+----------+
| count(*) |
+----------+
|    10273 |
+----------+
1 row in set (0.00 sec)

xtrabackup 备份是开启Gtid的,所以下面使用mysqlbinlog命令 进行增量binglog文件恢复数据时,要添加参数--skip-gtids 忽略掉binlog文件的中的Gtid信息,要是不加参数--skip-gtids 进行恢复的话,导致数据恢复不到3308库

正确的恢复命令如下:


mysqlbinlog    /data/mysql/mysql3306/binlog/mysql-bin.000001 --skip-gtids  |mysql -f --binary-mode  -S /tmp/mysql3308.sock
mysqlbinlog    /data/mysql/mysql3306/binlog/mysql-bin.000002 --skip-gtids  |mysql -f --binary-mode  -S /tmp/mysql3308.sock
mysqlbinlog    /data/mysql/mysql3306/binlog/mysql-bin.000003 --skip-gtids  |mysql -f --binary-mode  -S /tmp/mysql3308.sock
mysqlbinlog    /data/mysql/mysql3306/binlog/mysql-bin.000004 --skip-gtids  |mysql -f --binary-mode  -S /tmp/mysql3308.sock
mysqlbinlog    /data/mysql/mysql3306/binlog/mysql-bin.000005 --stop-position="15018"  --skip-gtids  |mysql -f --binary-mode  -S /tmp/mysql3308.sock 

参数说明:
--skip-gtids 忽略binlog文件中的Gtid的信息
--binary-mode 主要是为了解决中文乱码或者是特殊字符串乱码的问题
-f 强制恢复,忽略报错

执行完以上命令,数据就恢复到删除表test1_event之前的了

下面的恢复命令会导致数据恢复不到mysql 3308 实例上:(原因是my3308实例开启了Gtid参数导致的)


mysqlbinlog   /data/mysql/mysql3306/binlog/mysql-bin.000001 |mysql -f --binary-mode  -S /tmp/mysql3308.sock
mysqlbinlog   /data/mysql/mysql3306/binlog/mysql-bin.000002 |mysql -f --binary-mode  -S /tmp/mysql3308.sock
mysqlbinlog   /data/mysql/mysql3306/binlog/mysql-bin.000003 |mysql -f --binary-mode  -S /tmp/mysql3308.sock
mysqlbinlog   /data/mysql/mysql3306/binlog/mysql-bin.000004 |mysql -f --binary-mode  -S /tmp/mysql3308.sock
mysqlbinlog --stop-position="15018"  /data/mysql/mysql3306/binlog/mysql-bin.000005|mysql -f --binary-mode  -S /tmp/mysql3308.sock

2.6如果新的实例mysql3308 启动前从my3308.cnf中关闭掉Gtid参数:
3.
这样的话采用mysqlbinlog /data/mysql/mysql3306/binlog/mysql-bin.00000* |mysql -f --binary-mode -S /tmp/mysql3308.sock 是可以将数据恢复到mysql 3308实例上的,但是恢复过程中报错。这样恢复到3308的数据,
生成的binlog文件是不记录Gtid信息的


[[email protected] backup]# mysqlbinlog --stop-position="15018"  /data/mysql/mysql3306/binlog/mysql-bin.000005|mysql -f --binary-mode  -S /tmp/mysql3308.sock
ERROR 1781 (HY000) at line 17: @@SESSION.GTID_NEXT cannot be set to UUID:NUMBER when @@GLOBAL.GTID_MODE = OFF.
ERROR 1781 (HY000) at line 50: @@SESSION.GTID_NEXT cannot be set to UUID:NUMBER when @@GLOBAL.GTID_MODE = OFF.
ERROR 1781 (HY000) at line 74: @@SESSION.GTID_NEXT cannot be set to UUID:NUMBER when @@GLOBAL.GTID_MODE = OFF.
ERROR 1781 (HY000) at line 98: @@SESSION.GTID_NEXT cannot be set to UUID:NUMBER when @@GLOBAL.GTID_MODE = OFF.

当然也可以采用下面的方式来恢复,同样3308的实例的binglog文件是不记录Gtid信息的,这种方法在恢复的过程中可能会出现报错,不能完全保证数据的完整性和正确性,所以生产上最好不要使用这种方法来恢复找回数据

[[email protected] backup]# mysqlbinlog --skip-gtids  /data/mysql/mysql3306/binlog/mysql-bin.000001|mysql -f --binary-mode  -S /tmp/mysql3308.sock
ERROR 1050 (42S01) at line 27: Table ‘test1_event‘ already exists
ERROR 1062 (23000) at line 92: Duplicate entry ‘1‘ for key ‘PRIMARY‘
ERROR 1537 (HY000) at line 132: Event ‘e_test‘ already exists
mysqlbinlog --skip-gtids  /data/mysql/mysql3306/binlog/mysql-bin.000002|mysql -f --binary-mode  -S /tmp/mysql3308.sock
mysqlbinlog --skip-gtids  /data/mysql/mysql3306/binlog/mysql-bin.000003|mysql -f --binary-mode  -S /tmp/mysql3308.sock
mysqlbinlog --skip-gtids  /data/mysql/mysql3306/binlog/mysql-bin.000004|mysql -f --binary-mode  -S /tmp/mysql3308.sock
mysqlbinlog --skip-gtids --stop-position="15018" /data/mysql/mysql3306/binlog/mysql-bin.000005|mysql -f --binary-mode  -S /tmp/mysql3308.sock

友情提示:生产上还是最好开启Gtid. 这样在恢复数据和数据库同步,以及解决同步错误是非常方便的

总结:

对于DDL语句像 drop database ,drop tables , drop tables , truncate table 这样的语句就可以采用mysqlbinlog 来恢复。同时也可以采用binlog2sql工具来闪回

对于这样的语句,不管binglog 格式为row 格式,还是statement 格式,还是Mixed 格式,记录的binlog格式都为 statement 格式为row
利用mysqlbinlog 只能支持到database级别的提取

全备+利用mysqlbinlog恢复到某个时间点
利用mysqlbinlog --skip-gtids 存在很大风险点

原文地址:https://blog.51cto.com/wujianwei/2430312

时间: 2024-10-12 11:23:01

恢复MySQL数据到误删的表之前的数据的相关文章

详解:如何恢复MySQL数据库下误删的数据

2017-03-27 09:25 阅读 178 评论 0 作者:马哥Linux运维-Robin 血的教训,事发经过就不详述了.直接上操作步骤及恢复思路(友情提示:数据库的任何操作都要提前做好备份),以下是Mysql数据后的恢复过程: 1. 找到binlog 恢复数据的前提是必须开启Mysql的binlog日志,如果binlog日志没开启,请忽略此篇文档.binlog日志是否开启可以查看Mysql配置文件.日志位置一般在/var/lib/mysql目录或者编译安装的date目录下.也可登录Mysq

MYSQL使用mysqldump导出某个表的部分数据

MySQLdump是MySQL自带的导出数据工具,通常我们用它来导出MySQL中,但是有时候我们需要导出MySQL数据库中某个表的部分数据,这时该怎么办呢? mysqldump命令中带有一个 --where/-w 参数,它用来设定数据导出的条件,使用方式和SQL查询命令中中的where基本上相同,有了它,我们就可以从数据库中导出你需要的那部分数据了. 命令格式如下: mysqldump -u用户名 -p密码 数据库名 表名 --where="筛选条件" > 导出文件路径 例子:

向Mysql主键自增长表中添加数据并返回主键

表level,其主键为lid 1.select max(id) from table 查询语句:SELECT MAX(lid) FROM LEVEL 返回插入主键 2.select LAST_INSERT_ID(id) from table 查询语句:SELECT LAST_INSERT_ID(lid) FROM LEVEL; 返回主键列表,最后一个值为插入主键 3.select @@identity from table 查询语句:SELECT @@identity FROM level 返回

向后台提交数据:通过form表单提交数据需刷新网页 但通过Ajax提交数据不用刷新网页可通过原生态Ajax或jqueryAjax。Ajax代码部分

原生态Ajax提交表单:需要借助XMLHttpRequest对象的open,要收通过post发送请求还要setRequsetHeader,然后把数据发送给后端,代码如下 目录结构 index.py代码 1 #index.py 2 #!/usr/bin/env python 3 #-*- coding:utf-8 -*- 4 import tornado.web 5 import tornado.ioloop 6 class indexHandler(tornado.web.RequestHand

mysql第四篇:数据操作之多表查询

mysql第四篇:数据操作之多表查询 一.多表联合查询 #创建部门 CREATE TABLE IF NOT EXISTS dept ( did int not null auto_increment PRIMARY KEY, dname VARCHAR(50) not null COMMENT '部门名称' )ENGINE=INNODB DEFAULT charset utf8; #添加部门数据 INSERT INTO `dept` VALUES ('1', '教学部'); INSERT INT

struts_表单得到数据

在大家学习struts表达式语言的时候经常会遇到,从表单的提交上面得到数据, 而如何将表单的数据得到呢? 下面就介绍其中的一种方式: :以类的方式进行注入我们以login为例子 首先可以在struts的配置中写入下面的这些代码: 1:struts.xml <package name="login" extends="struts-default"> <action name="login" method="login&

MSSQL之三 在表中操纵数据

创建了数据库和表之后,下一步是在数据库中存储数据.作为一个数据库开发人员,你将需要修改或删除数据.你可以通过使用Transact-SQL的数据操纵语言(DML)语句来完成这些数据操纵. 本章讨论如何使用DML语句来操纵表中的数据. 重点 ?      插入数据 ?      更新数据 ?      删除表中数据 预习功课 ?        插入部分数据 ?        批量插入数据 ?        在表中更新数据 ?        从表中删除数据 使用DML语句操纵数据 在表中存储数据 表创

Oracle误删一个表数据的恢复方案

同事找回时操作的数据库为oracle 10g , 之前删除方式为delete 不晓得trancate好使不 SCN(系统改变号),它的英文全拼为:System Change Number ,它是数据库中非常重要的一个数据结构. SCN提供了Oracle的内部时钟机制,可被看作逻辑时钟,这对于恢复操作是至关重要的 注释:Oracle 仅根据 SCN 执行恢复. 它定义了数据库在某个确切时刻提交的版本.在事物提交时,它被赋予一个唯一的标示事物的SCN .一些人认为 SCN 是指, System Co

mysql 5.6 使用传输表空间迁移表或恢复误删除的表

mysql 5.6 使用传输表空间迁移表或恢复误删除的表 http://blog.csdn.net/lidan3959/article/details/25152623 以前在网上也看过一些对5.6传输表空间的介绍,不过都写的不够具体详细,今天有空就具体操作了一把,并详细记录了一下算留个档 一,简单说明:1),传输表空间的限制:   1,mysql 版本 5.6.6 及其以上,并且版本建议源和目标版本建议都是GA版并且大版本一样   2,表引擎为innodb并且开启独立表空间  innodb_f