MySQL之——灾难恢复

转载请注明出处:http://blog.csdn.net/l1028386804/article/details/79638562

1 mysql增量恢复必备条件

1)  开启mysql的log-bin参数记录binlog日志功能

[root@master mysql]$ vim my.cnf
log_bin=/data/mysql/data/mysql-bin

2)执行备份命令

[root@master mysql]$ mysqldump -uroot -p***  -F dataname > $PATH/dataname.sql
  -F, --flush-logs    Flush logs file in server before starting dump. Note that
                      if you dump many databases at once (using the option
                      --databases= or --all-databases), the logs will be
                      flushed for each database dumped. The exception is when
                      using --lock-all-tables or --master-data: in this case
                      the logs will be flushed only once, corresponding to the
                      moment all tables are locked. So if you want your dump
                      and the log flush to happen at the same exact moment you
                      should use --lock-all-tables or --master-data with
                      --flush-logs.

mysqldump参数详细说明参见博文《MySQL之——mysqldump参数详细说明》。

2 建立测试环境

1)建库,建表,插数据

mysql> create database student default character set utf8 collate utf8_general_ci;
mysql> use student;
mysql> create table student(sno int(10) NOT NULL COMMENT '学号',sname varchar(16) NOT NULL COMMENT '姓名',ssex char(2) NOT NULL COMMENT '性别', sage tinyint(2) NOT NULL default '0' COMMENT '学生年龄',sdept varchar(16) default NULL COMMENT '学生所在系别',PRIMARY KEY (sno)) ENGINE=Innodb AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
Query OK, 0 rows affected (0.07 sec)
COMMENT是注释的意思
mysql> insert into student values(0001,'路亚','男','24','计算机网络');
mysql> insert into student values(0002,'elain','男','26','computer');
mysql> insert into student values(0003,'zhangxiao','男','28','物流');
mysql> insert into student values(0004,'jeacen','男','28','compter');
mysql> insert into student values(0005,'张扬','男','29','计算机科学');

2)备份数据库

[root@master ~]# mysqldump -F -uroot -proot --lock-all-tables -B  student> /tmp/student.sql
加了-F参数,备份后binlog会生成新文件
-rw-rw---- 1 mysql mysql      143 Feb 23 13:42 mysql-bin.000001
-rw-rw---- 1 mysql mysql     2655 Feb 23 14:36 mysql-bin.000002
-rw-rw---- 1 mysql mysql      167 Feb 23 14:37 mysql-bin.000003
-rw-rw---- 1 mysql mysql      120 Feb 23 14:37 mysql-bin.000004

3)模拟更新,删除数据

mysql> insert into student values(0006,'jason','男','20','compter');
mysql> insert into student values(0007,'tomsion','男','27','人力资源');
mysql> select * from student;
+-----+-----------+------+------+-----------------+
| sno | sname     | ssex | sage | sdept           |
+-----+-----------+------+------+-----------------+
|   1 | 路亚      | 男   |   24 | 计算机网络      |
|   2 | elain     | 男   |   26 | computer        |
|   3 | zhangxiao | 男   |   28 | 物流            |
|   4 | jeacen    | 男   |   28 | compter         |
|   5 | 张扬      | 男   |   29 | 计算机科学      |
|   6 | jason     | 男   |   20 | compter         |
|   7 | tomsion   | 男   |   27 | 人力资源        |
+-----+-----------+------+------+-----------------+
7 rows in set (0.00 sec)
删除数据库:
mysql> drop database student;
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| test               |
+--------------------+
student库已经不存在了。
因为之前做好了日备份,以及增量的binlog日志,那么数据库丢了也不怕。

3 增量恢复全过程(重点)

1)检查全备份

2)检查备份的binlog

检查备份后所有的binlog 根据binlog的日期来判断备份后的flush,找到最近一次备份后的一个或多个binlog日志。

3)立即刷新并备份出需要的binlog日志文件

[root@master data]# mysqladmin -uroot -proot flush-logs
-rw-rw---- 1 mysql mysql      143 Feb 23 13:42 mysql-bin.000001
-rw-rw---- 1 mysql mysql     2655 Feb 23 14:36 mysql-bin.000002
-rw-rw---- 1 mysql mysql      167 Feb 23 14:37 mysql-bin.000003
-rw-rw---- 1 mysql mysql      789 Feb 23 14:59 mysql-bin.000004
-rw-rw---- 1 mysql mysql      120 Feb 23 14:59 mysql-bin.000005
多出一个005的日志即刷新后生成的日志,那么004就是含有我们需要数据的日志文件   [root@master data]# cp mysql-bin.000004 /tmp/  把这个文件考到一个目录中

4)恢复binlog生成sql语句

[root@master data]# mysqlbinlog /tmp/mysql-bin.000004 > /tmp/binlog.sql
[root@master data]# ll /tmp/
total 12
-rw-r--r-- 1 root root 2422 Feb 23 15:02 binlog.sql
-rw-r----- 1 root root  789 Feb 23 15:00 mysql-bin.000004
过滤掉binlog.sql里面的注释
[root@master data]# egrep -v "^#|^$|\*" /tmp/binlog.sql 
BINLOG '
jsrqVA8BAAAAdAAAAHgAAAAAAAQANS42LjEyLWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAEzgNAAgAEgAEBAQEEgAAXAAEGggAAAAICAgCAAAACgoKGRkAATHj
JJY=
BEGIN
insert into student values(0006,'jason','男','20','compter')
BEGIN
insert into student values(0007,'tomsion','男','27','人力资源')
drop database student
DELIMITER ;
我们已经清晰的看到数据库全备后的数据了

5)恢复数据

全备有了,增量也有了,下面进行恢复数据

同样也对全备库进行注释过滤
[root@master data]# egrep -v "^#|^$|\*" /tmp/student.sql 
-- MySQL dump 10.13  Distrib 5.6.12, for Linux (x86_64)
--
-- Host: localhost    Database: student
-- ------------------------------------------------------
-- Server version       5.6.12-log
--
-- Table structure for table `student`
--
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
  `sno` int(10) NOT NULL COMMENT '学号',
  `sname` varchar(16) NOT NULL COMMENT '姓名',
  `ssex` char(2) NOT NULL COMMENT '性别',
  `sage` tinyint(2) NOT NULL DEFAULT '0' COMMENT '学生年龄',
  `sdept` varchar(16) DEFAULT NULL COMMENT '学生所在系别',
  PRIMARY KEY (`sno`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Dumping data for table `student`
--
LOCK TABLES `student` WRITE;
INSERT INTO `student` VALUES (1,'路亚','男',24,'计算机网络'),(2,'elain','男',26,'computer'),(3,'zhangxiao','男',28,'物流'),(4,'jeacen','男',28,'compter'),(5,'张扬','男',29,'计算机科学');
UNLOCK TABLES;
-- Dump completed on 2018-03-20 14:37:10
开始恢复全备
[root@master data]# mysql -uroot -proot  < /tmp/student.sql 
[root@master data]# mysql -uroot -proot -e "select * from student.student;"
+-----+-----------+------+------+-----------------+
| sno | sname     | ssex | sage | sdept           |
+-----+-----------+------+------+-----------------+
|   1 | 路亚      | 男   |   24 | 计算机网络      |
|   2 | elain     | 男   |   26 | computer        |
|   3 | zhangxiao | 男   |   28 | 物流            |
|   4 | jeacen    | 男   |   28 | compter         |
|   5 | 张扬      | 男   |   29 | 计算机科学      |
+-----+-----------+------+------+-----------------+
全备数据库已经恢复,接下来恢复增量数据
[root@master data]# mysql -uroot -proot < /tmp/binlog.sql  #恢复binlog里面的数据
[root@master data]# mysql -uroot -proot -e "select * from student.student;"
ERROR 1146 (42S02) at line 1: Table 'student.student' doesn't exist

刚刚明明恢复好的数据库,又没有了,原来,binlog里面也记录了刚刚删除数据库的命令,恢复了,也就又删除了。

[root@master data]# tail /tmp/binlog.sql 
SET TIMESTAMP=1424674273/*!*/;
drop database student
/*!*/;
# at 742
#150223 14:59:01 server id 1  end_log_pos 789 CRC32 0xd834cffa  Rotate to mysql-bin.000005  pos: 4
DELIMITER ;
查询后,发现删库命令仍然存在,那么需要重新恢复刚刚的全备并且手工处理一下这个备份文件
[root@master data]# vim /tmp/binlog.sql
干掉drop语句,保存退出
[root@master data]# mysql -uroot -proot  < /tmp/student.sql 
[root@master data]# mysql -uroot -proot -e "select * from student.student;"
+-----+-----------+------+------+-----------------+
| sno | sname     | ssex | sage | sdept           |
+-----+-----------+------+------+-----------------+
|   1 | 路亚      | 男   |   24 | 计算机网络      |
|   2 | elain     | 男   |   26 | computer        |
|   3 | zhangxiao | 男   |   28 | 物流            |
|   4 | jeacen    | 男   |   28 | compter         |
|   5 | 张扬      | 男   |   29 | 计算机科学      |
+-----+-----------+------+------+-----------------+
[root@master data]# mysql -uroot -proot < /tmp/binlog.sql         
[root@master data]# mysql -uroot -proot -e "select * from student.student;"
+-----+-----------+------+------+-----------------+
| sno | sname     | ssex | sage | sdept           |
+-----+-----------+------+------+-----------------+
|   1 | 路亚      | 男   |   24 | 计算机网络      |
|   2 | elain     | 男   |   26 | computer        |
|   3 | zhangxiao | 男   |   28 | 物流            |
|   4 | jeacen    | 男   |   28 | compter         |
|   5 | 张扬      | 男   |   29 | 计算机科学      |
|   6 | jason     | 男   |   20 | compter         |
|   7 | tomsion   | 男   |   27 | 人力资源        |
+-----+-----------+------+------+-----------------+

ok了 数据都回来了。

4 基于时间点的增量恢复

1)指定开始时间和结束时间恢复
[root@master data]# mysqlbinlog /tmp/mysql-bin.000004 --start-datetime='2018-03-20 00:00:07' --stop-datetime='2018-03-20 00:10:07' -r /tmp/time.sql
开始结束时间,time.sql为输出到这个文件中,不指定结束时间表示到结尾。不指定开始时间表示从文件开头开始

5 基于位置点的增量恢复

[root@master data]# mysqlbinlog /tmp/mysql-bin.000004 --start-position=510 --stop-position=1312 -r /tmp/pos.sql
没指定开始或结束和上面时间的定义一样
无论是基于时间或基于位置,目的都是跳过误删的sql语句,哪种种更好,要根据实际情况来定。


你可能感兴趣的:(mysql,MySQL)