MYSQL数据回滚

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

binlog2sql快速回滚

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

  [mysqld]  server-id = 1  log_bin = /var/log/mysql/mysql-bin.log  max_binlog_size = 1000M  binlog-format = row    

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

随后,安装开源工具binlog2sql。binlog2sql是一款简单易用的binlog解析工具,其中一个功能就是生成回滚SQL。

  git clone https://github.com/danfengcao/binlog2sql.git  pip install -r requirements.txt    

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

背景:误删了test库f表整张表的数据,需要紧急回滚。

原有数据

  mysql> select * from f;  +-----+-----+---------------------+  | uid | did | updateTime     |  +-----+-----+---------------------+  |  1 | 18 | 2016-12-06 12:28:18 |  |  2 | 19 | 2016-12-06 12:55:56 |  |  3 | 20 | 2016-12-07 14:00:58 |  |  4 | 21 | 2016-12-07 14:01:00 |  +-----+-----+---------------------+  误操作mysql> delete from f;Query OK, 4 rows affected (0.00 sec)  f表被清空  mysql> select * from f;  Empty set (0.00 sec)    

回滚步骤:

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

  mysql> show master logs;  +------------------+-----------+  | Log_name     | File_size |  +------------------+-----------+  | mysql-bin.000001 | 12262268 |  | mysql-bin.000002 |  132776 |  +------------------+-----------+    

最新的binlog文件是mysql-bin.000002,我们再定位误操作SQL的binlog位置

  $ python binlog2sql/binlog2sql.py -h127.0.0.1 -P3306 -uadmin -p'admin' -dtest -t f --start-file='mysql-bin.000002'    

输出:

  DELETE FROM `test`.`f` WHERE `did`=18 AND `updateTime`='2016-12-06 12:28:18' AND `uid`=1 LIMIT 1; #start 4 end 314  DELETE FROM `test`.`f` WHERE `did`=19 AND `updateTime`='2016-12-06 12:55:56' AND `uid`=2 LIMIT 1; #start 4 end 314  DELETE FROM `test`.`f` WHERE `did`=20 AND `updateTime`='2016-12-07 14:00:58' AND `uid`=3 LIMIT 1; #start 4 end 314  DELETE FROM `test`.`f` WHERE `did`=21 AND `updateTime`='2016-12-07 14:01:00' AND `uid`=4 LIMIT 1; #start 4 end 314    

生成回滚sql,并检查回滚sql是否正确

  $ python binlog2sql/binlog2sql.py -h127.0.0.1 -P3306 -uadmin -p'admin' -dtest -t f --start-file='mysql-bin.000002' --start-pos=4 --end-pos=314 -B    

输出:

  INSERT INTO `test`.`f`(`did`, `updateTime`, `uid`) VALUES (21, '2016-12-07 14:01:00', 4); #start 4 end 314  INSERT INTO `test`.`f`(`did`, `updateTime`, `uid`) VALUES (20, '2016-12-07 14:00:58', 3); #start 4 end 314  INSERT INTO `test`.`f`(`did`, `updateTime`, `uid`) VALUES (19, '2016-12-06 12:55:56', 2); #start 4 end 314  INSERT INTO `test`.`f`(`did`, `updateTime`, `uid`) VALUES (18, '2016-12-06 12:28:18', 1); #start 4 end 314    

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

  $ python binlog2sql.py -h127.0.0.1 -P3306 -uadmin -p'admin' -dtest -t f --start-file='mysql-bin.000002' --start-pos=4 --end-pos=314 -B | mysql -h127.0.0.1 -P3306 -uadmin -p'admin'  mysql> select * from f;  +-----+-----+---------------------+  | uid | did | updateTime     |  +-----+-----+---------------------+  |  1 | 18 | 2016-12-06 12:28:18 |  |  2 | 19 | 2016-12-06 12:55:56 |  |  3 | 20 | 2016-12-07 14:00:58 |  |  4 | 21 | 2016-12-07 14:01: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回滚表结构,数据是回滚不了滴~

摘自: https://wenda.so.com/q/1481623833726291

<think>好的,用户想了解如何在MySQL中执行数据回滚操作。首先,我需要回忆一下MySQL中事务和回滚的相关知识。根据提供的引用内容,回滚操作主要涉及事务的使用,包括显式和隐式事务。 首先,要使用回滚,必须确保数据库引擎支持事务,比如InnoDB。用户可能需要确认他们使用的存储引擎是否正确。接下来,显式事务的基本步骤是开始事务(START TRANSACTION),执行操作,然后提交或回滚。这应该作为基本操作方法介绍。 然后,引用中提到保存点(SAVEPOINT)可以实现部分回滚。这个功能对用户来说可能很有用,特别是当他们在事务中执行多个操作时,可以回滚到某个特定的点,而不是全部回滚。需要详细说明如何设置保存点并使用ROLLBACK TO来回滚到该点。 隐式事务也是一个点,用户可能在使用自动提交模式时,每个语句都是一个事务。但需要指出在显式事务中,自动提交会被暂时禁用,直到事务结束。这可能涉及到用户对事务模式的理解,需要简单解释。 另外,用户可能关心回滚后的自增ID处理。引用3提到事务回滚后自增ID仍然自增,这是因为自增计数器的管理方式。需要提醒用户这一点,避免他们对此产生困惑。 还需要注意DDL语句的问题,比如在事务中执行ALTER TABLE这样的操作会导致隐式提交,可能影响事务的回滚。这一点需要强调,避免用户误操作。 最后,结合引用中的代码示例,可以给出具体的SQL命令示例,比如START TRANSACTION、ROLLBACK、SAVEPOINT的使用方法,帮助用户更直观地理解操作步骤。 总结下来,回答的结构应该是先介绍基本的事务操作流程,然后分点详细说明显式事务、保存点、隐式事务、注意事项等。同时,生成相关问题时要覆盖事务控制的其他方面,比如隔离级别、自增ID问题、性能影响等,以帮助用户全面了解。</think>### MySQL数据回滚操作方法 #### 一、事务的基本操作流程 在MySQL中实现数据回滚需通过事务控制,具体步骤如下: 1. **开启事务**:使用`START TRANSACTION`或`BEGIN`显式开启事务 2. **执行DML操作**:进行增删改操作(INSERT/UPDATE/DELETE) 3. **提交或回滚**: - **提交**:`COMMIT`永久保存修改 - **回滚**:`ROLLBACK`撤销未提交的操作 示例: ```sql START TRANSACTION; UPDATE accounts SET balance = balance - 100 WHERE user_id = 1; UPDATE accounts SET balance = balance + 100 WHERE user_id = 2; -- 若发现错误时 ROLLBACK; -- 或确认无误后提交 COMMIT; ``` #### 二、部分回滚(保存点机制) 通过`SAVEPOINT`可实现事务中的部分回滚[^2]: ```sql START TRANSACTION; INSERT INTO orders VALUES (...); SAVEPOINT savepoint1; UPDATE inventory SET stock = stock - 1 WHERE item_id = 5; -- 若库存更新失败 ROLLBACK TO savepoint1; -- 仅回滚UPDATE操作 COMMIT; -- 保留INSERT操作 ``` #### 三、隐式事务处理 当启用`AUTOCOMMIT=1`(默认模式)时,每个SQL语句自动成为独立事务。可通过以下命令切换模式: ```sql SET AUTOCOMMIT = 0; -- 关闭自动提交 ``` #### 四、重要注意事项 1. **存储引擎限制**:仅InnoDB引擎支持完整事务,MyISAM不支持回滚[^1] 2. **DDL语句影响**:执行`CREATE TABLE`等DDL语句会自动提交事务[^4] 3. **自增ID处理**:事务回滚后自增计数器不会重置[^3] 4. **锁机制**:长时间未提交的事务可能导致锁等待 #### 五、事务状态查询 通过以下命令查看事务状态: ```sql SHOW ENGINE INNODB STATUS; -- 查看当前事务 SELECT * FROM information_schema.INNODB_TRX; -- 查询活跃事务 ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值