删除误操作有时会意外出现,如果你有备份表数据的好习惯,那么至少你可以追回备份前的那些数据。如果我们打开了mysql的binlog,那么可以通过它的增量操作日志来恢复数据。怎么打开binlog前篇已有说明(参见windows下打开binlog),这里举例说明如何通过binlog进行恢复:

  1、看下当前的binlog位置,这里称为位置1:

mysql> show master status;
+---------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+---------------------+----------+--------------+------------------+-------------------+
| mysql-binlog.000001 | 529 | | | |
+---------------------+----------+--------------+------------------+-------------------+
1 row in set (0.01 sec)

  2、执行DML操作,创建一个测试表,插入2条数据后误操作删除了其中一条:

mysql> create table t_test(
-> name varchar(50) default null);
Query OK, 0 rows affected (0.06 sec) mysql> insert into t_test values('wlf');
Query OK, 1 row affected (0.01 sec) mysql> insert into t_test values('wms');
Query OK, 1 row affected (0.01 sec) mysql> delete from t_test where name = 'wlf';
Query OK, 1 row affected (0.01 sec)

  3、再看现在binlog的位置,这里称为位置2:

mysql> show master status;
+---------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+---------------------+----------+--------------+------------------+-------------------+
| mysql-binlog.000001 | 1496 | | | |
+---------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

  4、我们如果要恢复那条删除的数据,那么应该知道截至到删除前的那一刻所在的位置是多少,而这个位置必然位于位置1(即529)和2(即1496)之间:

mysql> show binlog events in 'mysql-binlog.000001' from 529;
+---------------------+------+----------------+-----------+-------------+-----------------------------------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+---------------------+------+----------------+-----------+-------------+-----------------------------------------------------------------+
| mysql-binlog.000001 | 529 | Anonymous_Gtid | 1 | 594 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| mysql-binlog.000001 | 594 | Query | 1 | 719 | use `test`; create table t_test(
name varchar(50) default null) |
| mysql-binlog.000001 | 719 | Anonymous_Gtid | 1 | 784 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| mysql-binlog.000001 | 784 | Query | 1 | 856 | BEGIN |
| mysql-binlog.000001 | 856 | Table_map | 1 | 907 | table_id: 109 (test.t_test) |
| mysql-binlog.000001 | 907 | Write_rows | 1 | 947 | table_id: 109 flags: STMT_END_F |
| mysql-binlog.000001 | 947 | Xid | 1 | 978 | COMMIT /* xid=11 */ |
| mysql-binlog.000001 | 978 | Anonymous_Gtid | 1 | 1043 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| mysql-binlog.000001 | 1043 | Query | 1 | 1115 | BEGIN |
| mysql-binlog.000001 | 1115 | Table_map | 1 | 1166 | table_id: 109 (test.t_test) |
| mysql-binlog.000001 | 1166 | Write_rows | 1 | 1206 | table_id: 109 flags: STMT_END_F |
| mysql-binlog.000001 | 1206 | Xid | 1 | 1237 | COMMIT /* xid=12 */ |
| mysql-binlog.000001 | 1237 | Anonymous_Gtid | 1 | 1302 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| mysql-binlog.000001 | 1302 | Query | 1 | 1374 | BEGIN |
| mysql-binlog.000001 | 1374 | Table_map | 1 | 1425 | table_id: 109 (test.t_test) |
| mysql-binlog.000001 | 1425 | Delete_rows | 1 | 1465 | table_id: 109 flags: STMT_END_F |
| mysql-binlog.000001 | 1465 | Xid | 1 | 1496 | COMMIT /* xid=13 */ |
+---------------------+------+----------------+-----------+-------------+-----------------------------------------------------------------+
17 rows in set (0.02 sec)

  我们看到594到719是建表,719到978是第一条插入语句,978到1237是第二条插入语句,1237到1465是误操作删除第一条插入数据的语句。那这会儿我们已经知道增量日志用于恢复删除操作的截至位置了,很明显就是1237,那么开始位置呢?执行恢复前,我们确认下目前t_test只有一条数据:

mysql> select * from t_test;
+------+
| name |
+------+
| wms |
+------+
1 row in set (0.01 sec)

  然后我们先看从594开始恢复会是啥结果:

D:\Dev\mysql\mysql-5.7.26-winx64\data>mysqlbinlog mysql-binlog.000001 --start-position 594 --stop-position 1237 | mysql -u root -p test
Enter password: *********
ERROR 1050 (42S01) at line 25: Table 't_test' already exists

  报错了,因为t_test表我们已经存在了,重复建表当然报错了。那么恢复的开始位置我们应该跳过建表语句,可以从719开始,再来一次:

D:\Dev\mysql\mysql-5.7.26-winx64\data>mysqlbinlog mysql-binlog.000001 --start-position 719 --stop-position 1237 | mysql -u root -p test
Enter password: ********* D:\Dev\mysql\mysql-5.7.26-winx64\data>

  这次没有报错了,我们去数据库看下数据是否恢复了:

mysql> select * from t_test;
+------+
| name |
+------+
| wms |
| wlf |
| wms |
+------+
3 rows in set (0.00 sec)

  呵呵,不仅恢复了被误删的第一条数据,还重复插入了第二条数据。怎么解决呢?有两个办法:第一个是直接把t_test也drop掉,然后执行我们的一次恢复,将执行从建表到第一、第二次插入;第二个办法是我们只恢复第一次插入,也就是只执行719到978。但如果是大量数据被我们误删了,那么就无法精确的知道该恢复从哪个位置开始到哪个位置结束的操作,没关系,我们可以根据时间来恢复,把--start-position和--stop-positon改成--start-datetime和--stop-datetime。

  上述mysqlbinlog命令是在binlog日志(如例子中的mysql-binlog.000001)所在目录执行的,后面的test是我的数据库名。最后我们再来按办法一操作一次:

  先drop表

mysql> drop table t_test;
Query OK, 0 rows affected (0.05 sec)

  再从头594到1237恢复:

D:\Dev\mysql\mysql-5.7.26-winx64\data>mysqlbinlog mysql-binlog.000001 --start-position 594 --stop-position 1237 | mysql -u root -p test
Enter password: ********* D:\Dev\mysql\mysql-5.7.26-winx64\data>

  现在数据已经恢复正常:

mysql> select * from t_test;
+------+
| name |
+------+
| wlf |
| wms |
+------+
2 rows in set (0.00 sec)

mysql通过binlog恢复删除数据的更多相关文章

  1. 【转】【MySQL】mysql 通过bin-log恢复数据方法详解

    mysql中bin-log在mysql默认状态下是没有打开的,我们要先打开mysql 开启bin-log功能,然后再通过备份的bin-log进行数据库恢复了. 具体的操作是通过mysqlbinlog这 ...

  2. 不小心删除数据--利用MySQL的binlog恢复数据

    MySQL Binary Log也就是常说的bin-log, ,是mysql执行改动产生的二进制日志文件,其主要作用有两个: * 数据回复 * 主从数据库.用于slave端执行增删改,保持与maste ...

  3. Mysql使用binlog恢复数据解决误操作问题的两种方法

    为保证没有其他参数配置影响,重新安装配置了一台最小化安装的CentOS7虚拟机 1. 基础知识
 安装mysql5.6数据库Mysql binlog初步理解 2. 配置mysql 开启binlog.修 ...

  4. 利用mysql的binlog恢复数据

    MySQL Binary Log也就是常说的bin-log, ,是mysql执行改动产生的二进制日志文件,其主要作用有两个: * 数据回复 * 主从数据库.用于slave端执行增删改,保持与maste ...

  5. mysql利用binlog恢复数据详细例子

    模拟数据恢复的案例 有些时候脑瓜就会短路,难免会出错 场景:在生产环境中,我们搭建了mysql主从,备份操作都是在从备份数据库上 前提:有最近一天或者最近的全备 或者最近一天相关数据库的备份 最重要的 ...

  6. mysql通过binlog恢复数据

    如果mysql不小心操作失误导致数据错误或者丢失这时候binlog起到了很大的作用 恢复有几种方式 1.按时间恢复--start-datetime   如果确定了时间点,那么按时间恢复是一个再好不过的 ...

  7. mysql利用binlog恢复数据

    需求:需要给开发提供一个2018年9月30号的数据,按照我们公司正常备份策略来说,直接找到对应时间的备份数据,解压导入即可,恰好这个时间节点的数据没有,只备份到2018年9月25号的,糟糕了吧 咋办呢 ...

  8. MySQL通过Binlog恢复删除的表

    查看log-bin是否开启:mysql> show variables like '%log%bin%';+---------------------------------+-------+| ...

  9. 烂泥:通过binlog恢复mysql备份之前的数据

    本文由秀依林枫提供友情赞助,首发于烂泥行天下. 上一篇文章,我们讲解了如何通过mysql的binlog日志恢复mysql数据库,文章连接为<烂泥:通过binlog恢复mysql数据库>.其 ...

随机推荐

  1. Vue实现一个图片懒加载插件(转载)

    Vue是可以自定义指令的,最近学习过程中遇见了一个需要图片懒加载的功能,最后参考了别人的代码和思路自己重新写了一遍.以下将详细介绍如何实现自定义指令v-lazyload. 先看如何使用这个指令: &l ...

  2. addEventListener和attachEvent的区别(转载)

    attachEvent 与addEventListener到底有什么区别呢?总结如下: 一.适应的浏览器版本不同 attachEvent——兼容:IE7.IE8:不兼容firefox.chrome.I ...

  3. jquery检测屏幕宽度并跳转页面

    jquery检测屏幕宽度并刷新页面 var owidth = ($(window).width()); //浏览器当前窗口可视区域宽度 if(owidth<640){//小于640跳转一个网址, ...

  4. HDU-1398-Square Coins(母函数)

    链接: https://vjudge.net/problem/HDU-1398 题意: People in Silverland use square coins. Not only they hav ...

  5. qml 3d 纪念那些曾经爬过的坑

    1.使用多position画图时,图形不受控制的问题? 在变量属性设置时Attribute中的attributeBaseType 数据类型一定要和 Buffer中data 数据类型一定要相同. 例如  ...

  6. QoS in RoCE (zz)

    QoS in RoCE 首页分类标签留言关于订阅2018-03-22 | 分类 Network  | 标签 RDMA  RoCE  ECN  PFC Overview TCP/IP协议栈满足不了现代I ...

  7. python 元组 【基本使用功能】

    元组是括号,列表是方括号,都可以通用的有好多,比如判断一个元素是否存在可以直接用 in ,复制或者合并可以直接用乘或者加. 下面是在菜鸟教程截得的: 示例: #!/usr/bin/python # - ...

  8. Python的十种常见算法

    十种排序算法 1. 常见算法分类 十种常见排序算法一般分为以下几种: (1)非线性时间比较类排序: ​ a. 交换类排序(快速排序.冒泡排序) ​ b. 插入类排序(简单插入排序.希尔排序) ​ c. ...

  9. angularJs driective指令小实例

    做一个下拉菜单,体会指令各参数的作用 html代码 <script type="text/ng-template" id="mydropdown.html" ...

  10. ORACLE批量导入图片到BLOB字段

    要插入图片的表不是固定的,而且是批量插入很多张,还要考虑到因为图片的文件名错误,修改后要再次插入,此时应避免已经插入的重复执行操作, 浪费时间. 所以就选择先用一张临时表来暂时保存从文件系统读取的照片 ...