MySQL误操作后怎么恢复数据?MySQL误操作后快速恢复数据的教程

摘要: 利用binlog闪回误操作数据。
基本上每个跟数据库打交道的程序员(当然也可能是你同事)都会碰一个问题,MySQL误操作后如何快速回滚?比如,delete一张表,忘加限制条件,整张表没了。假如这还是线上环境核心业务数据,那这事就闹大了。误操作后,能快速回滚数据是非常重要的。

传统解法

用全量备份重搭实例,再利用增量binlog备份,恢复到误操作之前的状态。然后跳过误操作的SQL,再继续应用binlog。此法费时费力,不值得再推荐。

利用binlog2sql快速闪回

首先,确认你的MySQL server开启了binlog,设置了以下参数:

[mysqld]

server-id = 1

log_bin = /var/log/mysql/mysql-bin.log

max_binlog_size = 100M

binlog-format = row

如果没有开启binlog,也没有预先生成回滚SQL,那真的无法快速回滚了。对存放重要业务数据的MySQL,强烈建议开启binlog。

随后,安装开源工具ps://github.com/danfengcao/binlog2sql">binlog2sql。binlog2sql是一款简单易用的binlog解析工具,其中一个功能就是生成回滚SQL。

shell> git clone https://github.com/danfengcao/binlog2sql.git

shell> pip install -r requirements.txt

然后,我们就可以生成回滚SQL了。

背景:小明在20点多时误删了test库tbl表整张表的数据,需要紧急回滚。

test库tbl表原有数据

mysql>select*fromtbl;

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

| id |name | addtime       |

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

| 1 | 小赵  | 2016-12-10 00:04:33 |

| 2 | 小钱  | 2016-12-10 00:04:48 |

| 3 | 小孙  | 2016-12-13 20:25:00 |

| 4 | 小李  | 2016-12-12 00:00:00 |

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

4rowsinset(0.00 sec)

 

mysql>deletefromtbl;

Query OK, 4rowsaffected (0.00 sec)

 

20:28时,tbl表误操作被清空

mysql>select*fromtbl;

Emptyset(0.00 sec)

恢复数据步骤:

1、登录mysql,查看目前的binlog文件


1

2

3

4

5

6

7

mysql> show master status;

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

| Log_name     | File_size |

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

| mysql-bin.000051 |    967 |

| mysql-bin.000052 |    965 |

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

2、最新的binlog文件是mysql-bin.000052,我们再定位误操作SQL的binlog位置。误操作人只能知道大致的误操作时间,我们根据大致时间过滤数据。

shell> python binlog2sql/binlog2sql.py -h127.0.0.1 -P3306 -uadmin -p'admin'-dtest -ttbl--start-file='mysql-bin.000052' --start-datetime='2016-12-13 20:25:00' --stop-datetime='2016-12-13 20:30:00'

输出:

INSERTINTO`test`.`tbl`(`addtime`, `id`, `name`)VALUES('2016-12-13 20:25:00', 3,'小孙'); #start 4end290time2016-12-13 20:25:46

INSERTINTO`test`.`tbl`(`addtime`, `id`, `name`)VALUES('2016-12-13 20:26:00', 4,'小李'); #start 317end487time2016-12-13 20:26:26

UPDATE`test`.`tbl`SET`addtime`='2016-12-12 00:00:00', `id`=4, `name`='小李'WHERE`addtime`='2016-12-13 20:26:00'AND`id`=4AND`name`='小李'LIMIT 1; #start 514end701time2016-12-13 20:27:07

DELETEFROM`test`.`tbl`WHERE`addtime`='2016-12-10 00:04:33'AND`id`=1AND`name`='小赵'LIMIT 1; #start 728end938time2016-12-13 20:28:05

DELETEFROM`test`.`tbl`WHERE`addtime`='2016-12-10 00:04:48'AND`id`=2AND`name`='小钱'LIMIT 1; #start 728end938time2016-12-13 20:28:05

DELETEFROM`test`.`tbl`WHERE`addtime`='2016-12-13 20:25:00'AND`id`=3AND`name`='小孙'LIMIT 1; #start 728end938time2016-12-13 20:28:05

DELETEFROM`test`.`tbl`WHERE`addtime`='2016-12-12 00:00:00'AND`id`=4AND`name`='小李'LIMIT 1; #start 728end938time2016-12-13 20:28:05

3、我们得到了误操作sql的准确位置在728-938之间,再根据位置进一步过滤,使用flashback模式生成回滚sql,检查回滚sql是否正确

shell> python binlog2sql/binlog2sql.py -h127.0.0.1 -P3306 -uadmin -p'admin'-dtest -ttbl--start-file='mysql-bin.000052' --start-pos=3346 --end-pos=3556 -B

输出:

INSERTINTO`test`.`tbl`(`addtime`, `id`, `name`)VALUES('2016-12-12 00:00:00', 4,'小李'); #start 728end938time2016-12-13 20:28:05

INSERTINTO`test`.`tbl`(`addtime`, `id`, `name`)VALUES('2016-12-13 20:25:00', 3,'小孙'); #start 728end938time2016-12-13 20:28:05

INSERTINTO`test`.`tbl`(`addtime`, `id`, `name`)VALUES('2016-12-10 00:04:48', 2,'小钱'); #start 728end938time2016-12-13 20:28:05

INSERTINTO`test`.`tbl`(`addtime`, `id`, `name`)VALUES('2016-12-10 00:04:33', 1,'小赵'); #start 728end938time2016-12-13 20:28:05

确认回滚sql正确,执行回滚语句。登录mysql确认,数据回滚成功。

shell> python binlog2sql.py -h127.0.0.1 -P3306 -uadmin -p'admin'-dtest -ttbl--start-file='mysql-bin.000052' --start-pos=3346 --end-pos=3556 -B | mysql -h127.0.0.1 -P3306 -uadmin -p'admin'

 

mysql>select*fromtbl;

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

| id |name | addtime       |

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

| 1 | 小赵  | 2016-12-10 00:04:33 |

| 2 | 小钱  | 2016-12-10 00:04:48 |

| 3 | 小孙  | 2016-12-13 20:25:00 |

| 4 | 小李  | 2016-12-12 00:00:00 |

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

至此,不用再担心被炒鱿鱼了。

常见问题

有人会问,我DDL误操作了怎么快速回滚?比如drop了一张大表。

很难做到。因为即使在在row模式下,DDL操作也不会把每行数据的变化记录到binlog,所以DDL无法通过binlog回滚。实现DDL回滚,必须要在执行DDL前先备份老数据。确实有人通过修改mysql server源码实现了DDL的快速回滚,我找到阿里的xiaobin lin提交了一个patch。但据我所知,国内很少有互联网公司应用了这个特性。原因的话,我认为最主要还是懒的去折腾,没必要搞这个低频功能,次要原因是会增加一些额外存储。

所以,DDL误操作的话一般只能通过备份来恢复。如果公司连备份也不能用了,那真的建议去买张飞机票了。干啥?跑呗

mysql除了binlog2sql,是否还有其他回滚工具?

当然有。阿里彭立勋对mysqlbinlog增加了flashback的特性,这应该是mysql最早有的flashback功能,彭解决的是DML的回滚,并说明了利用binlog进行DML闪回的设计思路。DDL回滚特性也是由阿里团队提出并实现的。这两个功能是有创新精神的,此后出现的闪回工具基本都是对上面两者的模仿。另外,去哪儿开源的Inception是一套MySQL自动化运维工具,这个就比较重了,支持DML回滚,还不是从binlog回滚的,是从备份回滚的,也支持DDL回滚表结构,数据是回滚不了滴~ 还有一种做法叫slave延时备份,搞台不加业务流量的slave,故意延迟一段时间,这其实是在传统办法的基础上去除了实例恢复这步。此法会额外消耗一台机器,我们不推荐这么做。

时间: 2024-08-03 07:43:00

MySQL误操作后怎么恢复数据?MySQL误操作后快速恢复数据的教程的相关文章

MySQL误操作后快速恢复数据的方法_Mysql

摘要: 利用binlog闪回误操作数据. 基本上每个跟数据库打交道的程序员(当然也可能是你同事)都会碰一个问题,MySQL误操作后如何快速回滚?比如,delete一张表,忘加限制条件,整张表没了.假如这还是线上环境核心业务数据,那这事就闹大了.误操作后,能快速回滚数据是非常重要的. 传统解法 用全量备份重搭实例,再利用增量binlog备份,恢复到误操作之前的状态.然后跳过误操作的SQL,再继续应用binlog.此法费时费力,不值得再推荐. 利用binlog2sql快速闪回 首先,确认你的MySQ

MySQL数据库的自动备份与数据库被破坏后的恢复

当数据库服务器建立好以后,我们首先要做的不是考虑要在这个支持数据库的服务器运行哪些受MySQL提携的程序,而是当数据库遭到破坏后,怎样安然恢复到最后一次正常的状态,使得数据的损失达到最小. 或者说,仅仅是数据库服务器的建立,只能说明它能做些什么,并不代表它能稳定的做些什么.灾难恢复的效率及全面性,也是系统的稳定性的一个准因素,尤其对于一个服务器系统. 这一节,介绍数据库自动备份以及数据库被破坏后的恢复的方法.在这里,我们使用mysqlhotcopy,并且定义一段Shell脚本来实现数据库的自动备

MySQL 自动备份与数据库被破坏后的恢复方法第1/2页_Mysql

一.前言: 当数据库服务器建立好以后,我们首先要做的不是考虑要在这个支持数据库的服务器运行哪些受MySQL提携的程序,而是当数据库遭到破坏后,怎样安然恢复到最后一次正常的状态,使得数据的损失达到最小. 或者说,仅仅是数据库服务器的建立,只能说明它能做些什么,并不代表它能稳定的做些什么.灾难恢复的效率及全面性,也是系统的稳定性的一个准因素,尤其对于一个服务器系统. 这一节,介绍数据库自动备份以及数据库被破坏后的恢复的方法.在这里,我们使用mysqlhotcopy,并且定义一段Shell脚本来实现数

MySQL使用二进制日志来恢复数据二种方法

MySQL使用二进制日志来恢复数据二种方法 如果MySQL服务器启用了二进制日志,你可以使用mysql教程binlog工具来恢复从指定的时间点开始 (例如,从你最后一次备份)直到现在或另一个指定的时间点的数据.关于启用二进制日志的信息,参见5.11.3节,"二进制日志".对于 mysqlbinlog的详细信息,"mysqlbinlog:用于处理二进制日志文件的实用工具". 要想从二进制日志恢复数据,你需要知道当前二进制日志文件的路径和文件名.一般可以从选项文件(即m

关于log4net连接数据问题,开启日志服务器超过24小时后无法连接到mysql数据库

问题描述 远程日志服务器启动超过24小时后将无法向mysql数据库插入数据,是什么原因呢?是数据库设置还是log4net设置问题呢?我用的最新版本的mysql.dll配置参数<configuration><!--Registerasectionhandlerforthelog4netsection--><configSections><sectionname="log4net"type="log4net.Config.Log4NetC

MySQL单表ibd文件恢复方法详解_Mysql

前言: 随着innodb的普及,innobackup也成为了主流备份方式.物理备份对于新建slave,全库恢复的需求都能从容应对. 但当面临单表数据误删,或者单表误drop的情况,如果使用物理全备进行恢复呢? 下文将进行详细分析. 恢复过程中需要用到的工具,percona data recover tool : https://launchpad.net/percona-innodb-recovery-tool 情况一:误删部分数据,需要用最近一次备份覆盖 来自同一台机器的ibd恢复覆盖,且备份

MySQL · 引擎特性 · InnoDB 崩溃恢复过程

在前面两篇文章中,我们详细介绍了 InnoDB redo log 和 undo log 的相关知识,本文将介绍 InnoDB 在崩溃恢复时的主要流程. 本文代码分析基于 MySQL 5.7.7-RC 版本,函数入口为 innobase_start_or_create_for_mysql,这是一个非常冗长的函数,本文只涉及和崩溃恢复相关的代码. 在阅读本文前,强烈建议翻阅下面两篇文章: 1. MySQL · 引擎特性 · InnoDB undo log 漫游 2. MySQL · 引擎特性 · I

MySQL 数据库的备份和恢复

1.mysqldump 1.1 备份 mysqldump 是采用SQL级别的备份机制,它将数据表导成 SQL 脚本文件,在不同的 MySQL 版本之间升级时相对比较合适,这也是最常用的备份方法.现在来讲一下 mysqldump 的一些主要参数: --compatible=name 它告诉 mysqldump,导出的数据将和哪种数据库或哪个旧版本的 MySQL 服务器相兼容.值可以为 ansi.mysql323.mysql40.postgresql.oracle.mssql.db2.maxdb.n

MySQL · 引擎特性 · InnoDB崩溃恢复

前言 数据库系统与文件系统最大的区别在于数据库能保证操作的原子性,一个操作要么不做要么都做,即使在数据库宕机的情况下,也不会出现操作一半的情况,这个就需要数据库的日志和一套完善的崩溃恢复机制来保证.本文仔细剖析了InnoDB的崩溃恢复流程,代码基于5.6分支. 基础知识 lsn: 可以理解为数据库从创建以来产生的redo日志量,这个值越大,说明数据库的更新越多,也可以理解为更新的时刻.此外,每个数据页上也有一个lsn,表示最后被修改时的lsn,值越大表示越晚被修改.比如,数据页A的lsn为100