mysql数据库误删除后的数据恢复方法

在日常运维工作中,对于mysql数据库的备份是至关重要的!数据库对于网站的重要性使得我们对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)在RUNOOB库下创建一张表runoob_tbl

mysql> create DATABASE RUNOOB;

Query OK, 1 row affected (0.01 sec)

mysql> use RUNOOB;

Database changed

mysql> CREATE TABLE IF NOT EXISTS `runoob_tbl`(

    -> `runoob_id` INT UNSIGNED AUTO_INCREMENT,

    ->  `runoob_title` VARCHAR(100) NOT NULL,

    ->  `runoob_author` VARCHAR(40) NOT NULL,

    -> `submission_date` DATE,

    -> PRIMARY KEY ( `runoob_id` )

    -> )ENGINE=InnoDB DEFAULT CHARSET=utf8;

Query OK, 0 rows affected, 1 warning (0.05 sec)

mysql> desc runoob_tbl;

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

| Field           | Type             | Null | Key | Default | Extra          |

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

| runoob_id       | int(10) unsigned | NO   | PRI | NULL    | auto_increment |

| runoob_title    | varchar(100)     | NO   |     | NULL    |                |

| runoob_author   | varchar(40)      | NO   |     | NULL    |                |

| submission_date | date             | YES  |     | NULL    |                |

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

4 rows in set (0.00 sec)

在数据表插入数据:

mysql> INSERT INTO runoob_tbl 

    -> VALUES

    -> (0, "JAVA ", "RUNOOB.COM", '2016-05-06');

Query OK, 1 row affected (0.01 sec)

mysql> INSERT INTO runoob_tbl  VALUES (0, "PHP ", "RUNOOB.COM", '2017-05-06');

Query OK, 1 row affected (0.01 sec)

mysql> INSERT INTO runoob_tbl  VALUES (0, "Ruby ", "RUNOOB.COM", '2019-05-06');

Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO runoob_tbl  VALUES (0, "Ruby ", "RUNOOB.COM", '2019-05-06');

Query OK, 1 row affected (0.01 sec)

mysql> INSERT INTO runoob_tbl  VALUES (0, "Ruby ", "RUNOOB.COM", '2019-05-06');

Query OK, 1 row affected (0.01 sec)

mysql> INSERT INTO runoob_tbl  VALUES (0, "Ruby ", "RUNOOB.COM", '2019-05-06');

Query OK, 1 row affected (0.01 sec)

mysql> select * from runoob_tbl;

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

| runoob_id | runoob_title | runoob_author | submission_date |

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

|         1 | JAVA         | RUNOOB.COM    | 2016-05-06      |

|         2 | PHP          | RUNOOB.COM    | 2017-05-06      |

|         3 | Ruby         | RUNOOB.COM    | 2019-05-06      |

|         4 | Ruby         | RUNOOB.COM    | 2019-05-06      |

|         5 | Ruby         | RUNOOB.COM    | 2019-05-06      |

|         6 | Ruby         | RUNOOB.COM    | 2019-05-06      |

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

6 rows in set (0.00 sec)

(2)现在进行全备份

root@aeba94ef3aa6:/tmp# mysqldump -uroot -p -B -F -R -x --master-data=2 RUNOOB|gzip > /tmp/backup/RUNOOB_$(date +%F).sql.gz
Enter password: 

root@aeba94ef3aa6:/tmp/backup# ls -al

total 12

drwxr-xr-x 2 root root 4096 Mar  2 14:44 .

drwxrwxrwt 1 root root 4096 Mar  2 14:35 ..

-rw-r--r-- 1 root root  980 Mar  2 14:44 RUNOOB_2019-03-02.sql.gz

-----------------
参数说明:
-B:指定数据库
-F:刷新日志
-R:备份存储过程等
-x:锁表
--master-data:在备份语句里添加CHANGE MASTER语句以及binlog文件及位置点信息
-----------------

(3)再次插入数据

mysql> use RUNOOB;

Reading table information for completion of table and column names

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

Database changed

mysql> INSERT INTO runoob_tbl VALUES (0, "GO", "BADU.COM", '2019-05-06');

Query OK, 1 row affected (0.01 sec)

mysql> INSERT INTO runoob_tbl VALUES (0, "GO", "BADU.COM", '2019-05-06');

Query OK, 1 row affected (0.01 sec)

mysql> INSERT INTO runoob_tbl VALUES (0, "GO", "BADU.COM", '2019-05-06');

Query OK, 1 row affected (0.01 sec)

mysql> INSERT INTO runoob_tbl VALUES (0, "GO", "BADU.COM", '2019-05-06');

Query OK, 1 row affected (0.01 sec)

mysql> select * from runoob_tbl;

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

| runoob_id | runoob_title | runoob_author | submission_date |

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

|         1 | JAVA         | RUNOOB.COM    | 2016-05-06      |

|         2 | PHP          | RUNOOB.COM    | 2017-05-06      |

|         3 | Ruby         | RUNOOB.COM    | 2019-05-06      |

|         4 | Ruby         | RUNOOB.COM    | 2019-05-06      |

|         5 | Ruby         | RUNOOB.COM    | 2019-05-06      |

|         6 | Ruby         | RUNOOB.COM    | 2019-05-06      |

|         7 | GO           | BADU.COM      | 2019-05-06      |

|         8 | GO           | BADU.COM      | 2019-05-06      |

|         9 | GO           | BADU.COM      | 2019-05-06      |

|        10 | GO           | BADU.COM      | 2019-05-06      |

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

10 rows in set (0.00 sec)

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

mysql> drop database RUNOOB;

Query OK, 1 row affected (0.03 sec)

mysql> show databases;

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

| Database           |

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

| information_schema |

| mysql              |

| mytest             |

| performance_schema |

| sys                |

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

5 rows in set (0.00 sec)

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

root@aeba94ef3aa6:/tmp/backup# gzip -d RUNOOB_2019-03-02.sql.gz 

root@aeba94ef3aa6:/tmp/backup# ls -al

total 12

drwxr-xr-x 2 root root 4096 Mar  2 14:48 .

drwxrwxrwt 1 root root 4096 Mar  2 14:35 ..

-rw-r--r-- 1 root root 2594 Mar  2 14:44 RUNOOB_2019-03-02.sql

root@aeba94ef3aa6:/tmp/backup# grep CHANGE RUNOOB_2019-03-02.sql

-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000004', MASTER_LOG_POS=155;

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

(6)移动binlog文件,并导出为sql文件,剔除其中的drop语句
查看mysql的数据存放目录,有下面可知是在/var/lib/mysql下
# ps -ef|grep mysql
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
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

root@aeba94ef3aa6:/tmp/backup# cd /var/lib/mysql

root@aeba94ef3aa6:/var/lib/mysql# ls -al

total 180436

drwxr-x--- 2 mysql mysql     4096 Mar  2 08:21 #innodb_temp

drwxr-xr-x 7 mysql mysql     4096 Mar  2 14:47 .

drwxr-xr-x 1 root  root      4096 Mar  1 02:21 ..

-rw-r----- 1 mysql mysql       56 Feb 21 10:04 auto.cnf

-rw-r----- 1 mysql mysql  3090087 Feb 21 10:04 binlog.000001

-rw-r----- 1 mysql mysql      178 Feb 21 10:29 binlog.000002

-rw-r----- 1 mysql mysql      178 Feb 25 05:25 binlog.000003

-rw-r----- 1 mysql mysql   132935 Feb 25 13:53 binlog.000004

-rw-r----- 1 mysql mysql     7375 Feb 26 15:57 binlog.000005

-rw-r----- 1 mysql mysql     2211 Feb 27 07:12 binlog.000006

-rw-r----- 1 mysql mysql      178 Feb 28 01:36 binlog.000007

-rw-r----- 1 mysql mysql      178 Mar  1 02:46 binlog.000008

-rw-r----- 1 mysql mysql      128 Mar  1 02:11 binlog.index

-rw------- 1 mysql mysql     1680 Feb 21 10:04 ca-key.pem

-rw-r--r-- 1 mysql mysql     1112 Feb 21 10:04 ca.pem

-rw-r--r-- 1 mysql mysql     1112 Feb 21 10:04 client-cert.pem

-rw------- 1 mysql mysql     1676 Feb 21 10:04 client-key.pem

-rw-r----- 1 mysql mysql     3724 Mar  1 05:44 ib_buffer_pool

-rw-r----- 1 mysql mysql 50331648 Mar  2 14:47 ib_logfile0

-rw-r----- 1 mysql mysql 50331648 Feb 21 10:04 ib_logfile1

-rw-r----- 1 mysql mysql 12582912 Mar  2 14:47 ibdata1

-rw-r----- 1 mysql mysql 12582912 Mar  2 08:21 ibtmp1

drwxr-x--- 2 mysql mysql     4096 Feb 21 10:04 mysql

-rw-r----- 1 mysql mysql      178 Mar  1 03:19 mysql-bin.000001

-rw-r----- 1 mysql mysql      733 Mar  1 05:44 mysql-bin.000002

-rw-r----- 1 mysql mysql     6852 Mar  2 14:44 mysql-bin.000003

-rw-r----- 1 mysql mysql     1586 Mar  2 14:47 mysql-bin.000004

-rw-r----- 1 mysql mysql       76 Mar  2 14:44 mysql-bin.index

-rw-r----- 1 mysql mysql 31457280 Mar  2 14:47 mysql.ibd

drwxr-x--- 2 mysql mysql     4096 Feb 27 03:07 mytest

drwxr-x--- 2 mysql mysql     4096 Feb 21 10:04 performance_schema

-rw------- 1 mysql mysql     1676 Feb 21 10:04 private_key.pem

-rw-r--r-- 1 mysql mysql      452 Feb 21 10:04 public_key.pem

-rw-r--r-- 1 mysql mysql     1112 Feb 21 10:04 server-cert.pem

-rw------- 1 mysql mysql     1680 Feb 21 10:04 server-key.pem

drwxr-x--- 2 mysql mysql     4096 Feb 21 10:04 sys

-rw-r----- 1 mysql mysql 12582912 Mar  2 14:47 undo_001

-rw-r----- 1 mysql mysql 11534336 Mar  2 14:47 undo_002

root@aeba94ef3aa6:/var/lib/mysql# cp mysql-bin.000004 /tmp/backup/

root@aeba94ef3aa6:/var/lib/mysql# mv mysql-bin.000004 /tmp

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

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

root@aeba94ef3aa6:/tmp/backup# mysqlbinlog -d RUNOOB mysql-bin.000004 > 004bin.sql

WARNING: The option --database has been used. It may filter parts of transactions, but will include the GTIDs in any case. If you want to exclude or include transactions, you should use the options --exclude-gtids or --include-gtids, respectively, instead.

root@aeba94ef3aa6:/tmp/backup# mysqlbinlog -d RUNOOB mysql-bi^C04 > 004bin.sql

root@aeba94ef3aa6:/tmp/backup# ls -al

total 24

drwxr-xr-x 2 root root 4096 Mar  2 14:53 .

drwxrwxrwt 1 root root 4096 Mar  2 14:52 ..

-rw-r--r-- 1 root root 7859 Mar  2 14:53 004bin.sql

-rw-r--r-- 1 root root 2594 Mar  2 14:44 RUNOOB_2019-03-02.sql

-rw-r----- 1 root root 1586 Mar  2 14:51 mysql-bin.000004

root@aeba94ef3aa6:/tmp/backup# vim 004bin.sql

#删除里面的drop语句

#drop database RUNOOB;

(7)恢复数据

查看数据库,看看ops库在不在
mysql> show databases;

mysql> create database RUNOOB;

Query OK, 1 row affected (0.01 sec)

mysql> exit

Bye

root@aeba94ef3aa6:/tmp/backup# mysqldump -uroot -p RUNOOB < RUNOOB_2019-03-02.sql

Enter password: 

mysql> use RUNOOB;

Database changed

mysql> source RUNOOB_2019-03-02.sql;

mysql> show tables;

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

| Tables_in_RUNOOB |

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

| runoob_tbl       |

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

1 row in set (0.00 sec)

mysql> select * from runoob_tbl;

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

| runoob_id | runoob_title | runoob_author | submission_date |

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

|         1 | JAVA         | RUNOOB.COM    | 2016-05-06      |

|         2 | PHP          | RUNOOB.COM    | 2017-05-06      |

|         3 | Ruby         | RUNOOB.COM    | 2019-05-06      |

|         4 | Ruby         | RUNOOB.COM    | 2019-05-06      |

|         5 | Ruby         | RUNOOB.COM    | 2019-05-06      |

|         6 | Ruby         | RUNOOB.COM    | 2019-05-06      |

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

6 rows in set (0.00 sec)

此时恢复了全备时刻的数据


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

mysql> exit

Bye

root@aeba94ef3aa6:/tmp/backup# mysqldump -uroot -p RUNOOB < 004bin.sql 

Enter password: 

mysql> use RUNOOB;

Reading table information for completion of table and column names

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

Database changed

mysql> source 004bin.sql;

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

mysql> select * from runoob_tbl   ;

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

| runoob_id | runoob_title | runoob_author | submission_date |

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

|         1 | JAVA         | RUNOOB.COM    | 2016-05-06      |

|         2 | PHP          | RUNOOB.COM    | 2017-05-06      |

|         3 | Ruby         | RUNOOB.COM    | 2019-05-06      |

|         4 | Ruby         | RUNOOB.COM    | 2019-05-06      |

|         5 | Ruby         | RUNOOB.COM    | 2019-05-06      |

|         6 | Ruby         | RUNOOB.COM    | 2019-05-06      |

|         7 | GO           | BADU.COM      | 2019-05-06      |

|         8 | GO           | BADU.COM      | 2019-05-06      |

|         9 | GO           | BADU.COM      | 2019-05-06      |

|        10 | GO           | BADU.COM      | 2019-05-06      |

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

10 rows in set (0.00 sec)


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

**********************************************
最后,总结几点:
1)本案例适用于人为SQL语句造成的误操作或者没有主从复制等的热备情况宕机时的修复
2)恢复条件为mysql要开启binlog日志功能,并且要全备和增量的所有数据
3)恢复时建议对外停止更新,即禁止更新数据库
4)先恢复全量,然后把全备时刻点以后的增量日志,按顺序恢复成SQL文件,然后把文件中有问题的SQL语句删除(也可通过时间和位置点),再恢复到数据库。

猜你喜欢

转载自blog.csdn.net/Kim_Weir/article/details/88083057