在日常运维工作中,对于数据库的备份是至关重要的!数据库对于网站的重要性使得我们对 MySQL 数据库的管理不容有失!然而是人总难免会犯错误,说不定哪天大脑短路了,误操作把数据库给删除了,怎么办?

下面,就 MySQL 数据库误删除后的恢复方案进行说明。

一、工作场景

(1)MySQL数据库每晚12:00自动完全备份。

(2)某天早上上班,9点的时候,一同事犯晕drop了一个数据库!

(3)需要紧急恢复!可利用备份的数据文件以及增量的binlog文件进行数据恢复。

二、数据恢复思路

(1)利用全备的sql文件中记录的CHANGE MASTER语句,binlog文件及其位置点信息,找出binlog文件中增量的那部分。

(2)用mysqlbinlog命令将上述的binlog文件导出为sql文件,并剔除其中的drop语句。

(3)通过全备文件和增量binlog文件的导出sql文件,就可以恢复到完整的数据。

三、实例说明

首先,要确保mysql开启了binlog日志功能。在/etc/my.cnf文件里的[mysqld]区块添加:

log-bin=mysql-bin

然后重启mysql服务

(1)在ops库下创建一张表customers

  1. mysql> use ops;

  2. mysql> create table customers(

  3. -> id int not null auto_increment,

  4. -> name char(20) not null,

  5. -> age int not null,

  6. -> primary key(id)

  7. -> )engine=InnoDB;

  8. Query OK, 0 rows affected (0.09 sec)

  9. mysql> show tables;

  10. +---------------+

  11. | Tables_in_ops |

  12. +---------------+

  13. | customers |

  14. +---------------+

  15. 1 row in set (0.00 sec)

  16. mysql> desc customers;

  17. +-------+----------+------+-----+---------+----------------+

  18. | Field | Type | Null | Key | Default | Extra |

  19. +-------+----------+------+-----+---------+----------------+

  20. | id | int(11) | NO | PRI | NULL | auto_increment |

  21. | name | char(20) | NO | | NULL | |

  22. | age | int(11) | NO | | NULL | |

  23. +-------+----------+------+-----+---------+----------------+

  24. 3 rows in set (0.02 sec)

  25. mysql> insert into customers values(1,"wangbo","24");

  26. Query OK, 1 row affected (0.06 sec)

  27. mysql> insert into customers values(2,"guohui","22");

  28. Query OK, 1 row affected (0.06 sec)

  29. mysql> insert into customers values(3,"zhangheng","27");

  30. Query OK, 1 row affected (0.09 sec)

  31. mysql> select * from customers;

  32. +----+-----------+-----+

  33. | id | name | age |

  34. +----+-----------+-----+

  35. | 1 | wangbo | 24 |

  36. | 2 | guohui | 22 |

  37. | 3 | zhangheng | 27 |

  38. +----+-----------+-----+

  39. 3 rows in set (0.00 sec)

(2)现在进行全备份

  1. [root@vm-002 ~]# mysqldump -uroot -p -B -F -R -x --master-data=2 ops|gzip >/opt/backup/ops_$(date +%F).sql.gz

  2. Enter password:

  3. [root@vm-002 ~]# ls /opt/backup/

  4. ops_2016-09-25.sql.gz

参数说明:

-B:指定数据库

-F:刷新日志

-R:备份存储过程等

-x:锁表

–master-data:在备份语句里添加CHANGE MASTER语句以及binlog文件及位置点信息

(3)再次插入数据

  1. mysql> insert into customers values(4,"liupeng","21");

  2. Query OK, 1 row affected (0.06 sec)

  3. mysql> insert into customers values(5,"xiaoda","31");

  4. Query OK, 1 row affected (0.07 sec)

  5. mysql> insert into customers values(6,"fuaiai","26");

  6. Query OK, 1 row affected (0.06 sec)

  7. mysql> select * from customers;

  8. +----+-----------+-----+

  9. | id | name | age |

  10. +----+-----------+-----+

  11. | 1 | wangbo | 24 |

  12. | 2 | guohui | 22 |

  13. | 3 | zhangheng | 27 |

  14. | 4 | liupeng | 21 |

  15. | 5 | xiaoda | 31 |

  16. | 6 | fuaiai | 26 |

  17. +----+-----------+-----+

  18. 6 rows in set (0.00 sec)

(4)此时误操作,删除了test数据库

  1. mysql> drop database ops;

  2. Query OK, 1 row affected (0.04 sec)

此时,全备之后到误操作时刻之间,用户写入的数据在binlog中,需要恢复出来!

(5)查看全备之后新增的binlog文件

  1. [root@vm-002 ~]# cd /opt/backup/

  2. [root@vm-002 backup]# ls

  3. ops_2016-09-25.sql.gz

  4. [root@vm-002 backup]# gzip -d ops_2016-09-25.sql.gz

  5. [root@vm-002 backup]# ls

  6. ops_2016-09-25.sql

  7. [root@vm-002 backup]# grep CHANGE ops_2016-09-25.sql

  8. -- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000002', MASTER_LOG_POS=106;

这是全备时刻的binlog文件位置,即mysql-bin.000002的106行,因此在该文件之前的binlog文件中的数据都已经包含在这个全备的sql文件中了

(6)移动binlog文件,并导出为sql文件,剔除其中的drop语句,查看mysql的数据存放目录,有下面可知是在/var/lib/mysql下

  1. [root@vm-002 backup]# ps -ef|grep mysql

  2. root 9272 1 0 01:43 pts/1 00:00:00 /bin/sh /usr/bin/mysqld_safe --datadir=/var/lib/mysql --socket=/var/lib/mysql/mysql.sock --pid-file=/var/run/mysqld/mysqld.pid --basedir=/usr --user=mysql

  3. mysql 9377 9272 0 01:43 pts/1 00:00:00 /usr/libexec/mysqld --basedir=/usr --datadir=/var/lib/mysql --user=mysql --log-error=/var/log/mysqld.log --pid-file=/var/run/mysqld/mysqld.pid --socket=/var/lib/mysql/mysql.sock

  4. [root@vm-002 backup]# cd /var/lib/mysql/

  5. [root@vm-002 mysql]# ls

  6. ibdata1 ib_logfile0 ib_logfile1 mysql mysql-bin.000001 mysql-bin.000002 mysql-bin.index mysql.sock test

  7. [root@vm-002 mysql]# cp mysql-bin.000002 /opt/backup/

将binlog文件导出sql文件,并vim编辑它删除其中的drop语句

  1. [root@vm-002 backup]# mysqlbinlog -d ops mysql-bin.000002 >002bin.sql

  2. [root@vm-002 backup]# ls

  3. 002bin.sql mysql-bin.000002 ops_2016-09-25.sql

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

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

(7)恢复数据

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

  2. Enter password:

  3. [root@vm-002 backup]#

查看数据库,看看ops库在不在

  1. mysql> show databases;

  2. +--------------------+

  3. | Database |

  4. +--------------------+

  5. | information_schema |

  6. | mysql |

  7. | ops |

  8. | test |

  9. +--------------------+

  10. 4 rows in set (0.00 sec)

  11. mysql> use ops;

  12. Reading table information for completion of table and column names

  13. You can turn off this feature to get a quicker startup with -A

  14. Database changed

  15. mysql> select * from customers;

  16. +----+-----------+-----+

  17. | id | name | age |

  18. +----+-----------+-----+

  19. | 1 | wangbo | 0 |

  20. | 2 | guohui | 0 |

  21. | 3 | zhangheng | 0 |

  22. +----+-----------+-----+

  23. 3 rows in set (0.00 sec)

此时恢复了全备时刻的数据。接着,使用002bin.sql文件恢复全备时刻到删除数据库之间,新增的数据

  1. [root@vm-002 backup]# mysql -uroot -p ops <002bin.sql

  2. Enter password:

  3. [root@vm-002 backup]#

再次查看数据库,发现全备份到删除数据库之间的那部分数据也恢复了!!

  1. mysql> select * from customers;

  2. +----+-----------+-----+

  3. | id | name | age |

  4. +----+-----------+-----+

  5. | 1 | wangbo | 24 |

  6. | 2 | guohui | 22 |

  7. | 3 | zhangheng | 27 |

  8. | 4 | liupeng | 21 |

  9. | 5 | xiaoda | 31 |

  10. | 6 | fuaiai | 26 |

  11. +----+-----------+-----+

  12. 6 rows in set (0.00 sec)

以上就是mysql数据库增量数据恢复的实例过程!

最后,总结几点:

1)本案例适用于人为SQL语句造成的误操作或者没有主从复制等的热备情况宕机时的修复

2)恢复条件为mysql要开启binlog日志功能,并且要全备和增量的所有数据

3)恢复时建议对外停止更新,即禁止更新数据库

4)先恢复全量,然后把全备时刻点以后的增量日志,按顺序恢复成SQL文件,然后把文件中有问题的SQL语句删除(也可通过时间和位置点),再恢复到数据库。

恢复MySQL数据库删除的数据的更多相关文章

  1. Mysql数据库删除重复数据

    最近因为发现数据库中的表有脏数据,需要维护.这些脏数据就是重复数据,需要将其删除. 现假设有一张test表,主键字段为num,还有id,one,two三个字段.假设id规定只能有一条记录(即需要为id ...

  2. 如何在删除ibdata1和ib_logfile的情况下恢复MySQL数据库

    昨天,有个朋友对公司内部使用的一个MySQL实例开启binlog,但是在启动的过程中失败了(他也没提,为何会失败),在启动失败后,他删除了ibdata1和ib_logfile,后来,能正常启动了,但所 ...

  3. 删除mysql数据库中表分区数据

    删除mysql数据库中表分区数据 zabbix 几个大表创建了分区,由于磁盘空间告警,特将3月前的分区给予删除. 1.查看表的数据占用磁盘空间情况 2.登录mysql中,查看表的分区情况. 3.删除表 ...

  4. MySQL数据库表的数据插入、修改、删除、查询操作及实例应用

    一.MySQL数据库表的数据插入.修改.删除和查询 CREATE DATABASE db0504; USE db0504; CREATE TABLE student ( sno ) NOT NULL ...

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

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

  6. 烂泥:通过binlog恢复mysql数据库

    本文由秀依林枫提供友情赞助,首发于烂泥行天下. 在上一篇文章,我们讲解了有关mysql的binlog日志的基础知识.这篇文章,我们来讲解如何通过mysql的binlog日志来恢复数据库. 在使用bin ...

  7. MYSQL启用日志,查看日志,利用mysqlbinlog工具恢复MySQL数据库【转载】

    转自 MYSQL启用日志,查看日志,利用mysqlbinlog工具恢复MySQL数据库 - _安静 - 博客园http://www.cnblogs.com/xionghui/archive/2012/ ...

  8. mysql进阶(十五) mysql批量删除大量数据

    mysql批量删除大量数据 假设有一个表(syslogs)有1000万条记录,需要在业务不停止的情况下删除其中statusid=1的所有记录,差不多有600万条, 直接执行 DELETE FROM s ...

  9. .NET 5/.NET Core使用EF Core 5连接MySQL数据库写入/读取数据示例教程

    本文首发于<.NET 5/.NET Core使用EF Core 5(Entity Framework Core)连接MySQL数据库写入/读取数据示例教程> 前言 在.NET Core/. ...

随机推荐

  1. 算法复习——trie树(poj2001)

    题目: 题目描述 给出 n 个单词(1<=n<=1000),求出每个单词的非公共前缀,如果没有,则输出自己. 输入格式 输入 N 个单词,每行一个,每个单词都是由 1-20 个小写字母构成 ...

  2. Codeforces 894.A QAQ

    A. QAQ time limit per test 1 second memory limit per test 256 megabytes input standard input output ...

  3. cf493E Vasya and Polynomial

    Vasya is studying in the last class of school and soon he will take exams. He decided to study polyn ...

  4. AtCoder Grand Contest 005F - Many Easy Problems

    $n \leq 200000$的树,从树上选$k$个点的一个方案会对$Ans_k$产生大小为“最小的包括这$k$个点的连通块大小”的贡献.求每个$Ans_k$.膜924844033. 看每个点对$An ...

  5. css3 画三角形

    /*箭头向上*/ .arrow-up { width:0; height:0; border-left:20px solid transparent; border-right:20px solid ...

  6. jqeury设置元素屏幕居中

    jQuery.fn.center = function () { this.css(“position”,”absolute”); this.css(“top”, ( $(window).height ...

  7. Eclipse FindBugs的安装

    原文:http://blog.sina.com.cn/s/blog_62186b460100l3mx.html 1安装:首先到官方网站下载最新版本FindBugs    http://findbugs ...

  8. nuxt.js 加百度统计

    Mark一下: 在 Nuxt.js应用中使用Google统计分析服务,或者百度统计分析服务,推荐在 plugins 目录下创建 plugins/ga.js 文件.统计统计分析我们可以获取网站pv,uv ...

  9. oracle学习 第二章 限制性查询和数据的排序 ——03

    这里.我们接着上一小节2.6留下的问题:假设要查询的字符串中含有"_"或"%".又该如何处理呢? 開始今天的学习. 2.7  怎样使用转义(escape)操作符 ...

  10. OC - 读歌词

    类的头文件: #import <Foundation/Foundation.h> //FILE_PATH是文件名称. #define FILE_PATH @"/Users/qia ...