mysql的备份和恢复

        对于某些企业来说,数据就是该企业的核心元素,一旦数据丢失都将会对该企业造成致命的打击,因此,作为一名DBA要定期的对数据做好备份工作,以便出现故障时,可以即时恢复,从而保证企业数据的完整性。根据不同的需求,我们可以划分如下备份类型:

 

mysql的备份类型

1、根据mysql服务器是否在线,备份类型可以这样划分:

热备分:使用这种方式mysql服务器可以在线,且读写操作不受影响

温备:这种方式mysql服务器也可以在线,读操作不受影响,但是写操作受影响,需要手动加读锁(共享锁)。

冷备:这是方式mysql服务器必须停止运行,即离线备份,因此,读写操作都不会受影响

 

2、根据备份的是表中的数据文件还是通过mysql导出的文件,可以这样划分:

物理备份:这种方式是直接复制或归档文件(即使用cp命令或tar命令)

逻辑备份:这种方式是将数据导出到文本文件中(利用数据重定向功能),因此可以直接利用编辑器编译。如果导出的文本文件有十几个G或者更大的话,那就千万不要使用vim编辑器来编译了。

 

3、根据备份是整个数据还是仅变化的数据,可以这样划分:

完全备份:就是备份所有的数据

增量备份:仅备份上次完全备份或增量备份以后变化的数据

差异备份:仅备份上次完全备份以后变化的数据,相对于增量备份该方式备份比较慢,但还原速度比较快。


4、根据备份的数据集范围,可以这样划分:

完全备份:也是备份这个数据库中的数据或者备份某个库的数据

部分备份:只备份某个库中的一分部数据,如仅备份库中的某一个表数据。


 

这几种备份类型彼此之间没有什么对应关系,可以根据需求相互结合使用。

 

为什么要备份?

之所以要备份,主要是防止数据丢失,给企业造成重大影响,对于信息时代,数据对于一个企业是至关主要的,因此,如果保护好数据也是非常重要的。

备份的目的主要有如下几个因素:

1、做灾难恢复。防止其他突发事件导致数据丢失或者不可用了,因此做好数据防灾工作是必须的。

2、审计。有些网站需要统计下某个栏目的访问量,那么就需要对数据进行审计了。

3、恢复测试。一般说来,当数据备份完成之后,还需要对备份的数据对一些测试工作,以检验这些备份的数据是否可以正常恢复。




物理备份和逻辑备份的特点

物理备份:该方式备份速度快,且还原也比较快,属于文件系统级别的

逻辑备份:该方式仅是备份数据,因此在还原过程中,需要手动建立表结构,且这种方式备份的速度慢、易丢失浮点数精度。备份出来的数据会占用更多的存储空间,其压缩后可大大节省空间。但是由于将数据直接存储在本文文件中,因此,可以利用文本工具直接处理,其移植能力强。但是不适合对大数据库做完全备份。

 

增量备份和差异备份的比较

在上面已经讲述了增量备份和差异备份的概念,如果还是看不懂,这里我给出一个比较直观的图形界面,大家可以直观的看出,这两种方式的差异在哪里。

mysql的备份与恢复

 

 

备份的对象

一般来说,我们需要对如下这些数据进行备份:

数据:这个就不多说了,这就是要备份的核心东西

二进制日志文件:如果mysql服务器上的存储数据的文件损坏了,那么二进制日志文件就可以用来恢复备份之后的数据。因此,这个一般我们也要备份,一般我们会对二进制日志使用增量备份或者差异备份的方式来备份。

事务日志文件:如果某个事务线程正在运行,且事务日志文件存放的数据满时,即时事务没有提交,事务日志会将数据同步到磁盘中去,因此,事务日志中很可能存在一半的事务(即只有一部分数据写入到磁盘中去)。一旦服务器宕机,就可以利用事务日志来进行撤销。使数据保持不受影响。因此,事务日志一般也要备份。

mysql的配置文件:由于mysql的配置文件可以定义各种服务器变量,因此,不同的mysql服务器可能定义的属性不一样,因此,一般我们也要对mysql的配置文件做备份。

代码:包括存储函数、存储过程、触发器等等。

 

备份策略

一般的我们需要一个月做一次完全备份,一周做一次增量备份或差异备份;或者一周做一次完全备份,每天做一次增量备份或差异备份。

因此,一般使用完全备份+增量备份或者完全备份+差异备份来结合备份数据和其他重要文件(上述提到)

 


备份时需要考虑的因素

使用何种备份方式

何时进行备份,一般的在服务器比较空闲的时候,备份数据比较好,如在凌晨进行备份。

备份时长,如果一个数据备份的时间太长的话,那么我们应该采用增量或者差异的方式进行备份。

备份负载,数据备份时也会占用很多的io和网络带宽,因此,在服务器不是很繁忙的时候进行备份比较好。


 

备份工具

我们所需要的备份工具有如下这些:

mysql的备份与恢复

其中mysqldump是一个mysql客户端的逻辑备份工具,备份数据和恢复数据比较慢,它对MyISAM存储引擎支持温备份;对Aria存储引擎支持温备;对Innodb存储引擎支持热备。mysqldump适用于备份数据集比较小的数据。

select  into outfile是一个逻辑备份工具,需要手动创建表结构。相比mysqldump来说,该工具备份速度和还原速度比mysqldump快,且占用空间小。

mysqlhotcopy是一个物理备份工具,它仅对MyISAM存储引擎支持温备份。

Snapshot:利用LVM的快照功能实现几乎热备功能,是一个物理备份工具。

第三方备份工具:

innobackup是由Innobase公司研发的,是一个商业备份工具。

xtrabackup是由Percona组织研发的,是一个开源备份工具。它对MyiSAM存储引擎只能做完全备份,即使是做增量备份,该增量备份也是属于完全备份。对于InnoDB存储引擎来将,他可以做完全备份、增量备份和差异备份。

 

 

利用mysqldump工具来实现数据的完全备份

由于mysqldump是一个逻辑备份工具,备份和恢复速度慢,因此使用该工具备份数据时,数据的体积不能太大。mysqldump备份方式是将表中的一些sql语句备份起来,还原时,将这些语句批量插入。

mysqldump的使用语法格式

1、备份单个数据库或者其他中的某个表

mysql> mysqldump -uUSERNAME -p  DB_NAME  [tb1_name]  [tb2_name]  >  /path/to/somefile.sql

说明:使用这种方式需要手动创建数据库名称或表结构

 

 

2、备份多个数据库

mysql> mysqldump -uUSERNAME -p  options...     >  /path/to/somefile.sql

options:

--all-databases:备份所有的数据库,不需要创建数据库名

--databases DB1_NAME,DB2_NAME..:备份多个指定数据库,不需要创建数据库名

--lock-all-tables:备份时锁定所有表。对MyiSAM、Aria、InnoDB存储引擎做温备时使用的选项。

--flush-logs:执行日志flush

--master-data={0|1|2}

             0:表示不记录二进制日志文件和路径

             1:以CHNAGE MASTER TO的方式记录位置,可用于恢复后直接启动从服务器;

             2:以CHANGE MASTER TO的方式记录位置,但该行默认为被注释掉了;        

--events:备份数据库中的创建事件的调度器代码

--routines:备份存储函数和存储过程

--triggers:备份触发器

--single-transaction:对InnoDB存储引擎实现热备。该选项不能和--lock-all-tables一起使用。




利用mysqldump来实现对hellodb这个数据库做温备

备份时的操作

1、备份时执行如下命令

# mysqldump -uroot -p --databases hellodb  --flush-logs --lock-all-tables > first_wb.sql

--databases hellodb:指定要备份的数据库。

--flush-logs:在备份前执行二进制日志滚动,这样做的好处在于,当以后有数据写入时,这些修改的操作会被记录到二进制日志文件中去,即使一不小心把数据删除了,也可以利用二进制日志文件来进行恢复,因此,我们需要准确的知道当前的二进制日志文件是哪一个,及其事件处于哪一个position。

--lock-all-tables:在备份前加锁,防止数据写入。


2、临时关闭二进制日志功能

由于mysqldump备份的数据都是一些insert、create语句,因此,当这些数据恢复时,其 实就是再把这些语句重新执行一次,因此,会改变数据库,所以这些修改操作都会记录到二进制日志文件中。由于我们已经有了备份文件数据,因此,这些数据不应 该再次写入到二进制日志文件中去。

mysql> set session sql_log_bin=off;
Query OK, 0 rows affected (0.00 sec)


3、记录当前的使用的二进制日志文件及其事件的position。

# mysql -uroot -p -e 'show master status;' > /mybackup/current-bin


显示current-bin文件的内容

# cat current-bin
File    Position    Binlog_Do_DB    Binlog_Ignore_DB
mysql-bin.000005    107

当前的二进制日志文件为mysql-bin.000005,下一个事件的起始位置为107。





恢复时的操作(恢复时服务器需要处于离线状态)

4、模拟数据库hellodb一不小心被删除了

mysql> drop database hellodb;
Query OK, 7 rows affected (0.03 sec)

删除成功后,显示所有的库,发现hellodb,已经被删除了。
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| good               |
| he                 |
| mysql              |
| nginxdb            |
| performance_schema |
| test               |
+--------------------+
7 rows in set (0.00 sec)





5、将备份数据倒入到数据库中

由于刚刚修改的服务器变量sql_log_bin只是会话级别的,因此,他只会在当前会发生效,所以,此时将备份文件倒入到数据库中,需要在mysql中执行source命令来完成。如:

mysql> source /mybackup/first_wb.sql
Query OK, 0 rows affected (0.00 sec)

执行成功过后,这个Query OK行会显示很多条的。


6、查看hellodb库是否已经恢复额

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| good               |
| he                 |
| hellodb            |
| mysql              |
| nginxdb            |
| performance_schema |
| test               |
+--------------------+
8 rows in set (0.00 sec)


7、验证上述写操作是否记录到了二进制日志文件中

mysql> show master status;
+-------------------+----------+--------------+------------------+
| File              | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+-------------------+----------+--------------+------------------+
| master-bin.000005 |      107 |              |                  |
+-------------------+----------+--------------+------------------+
1 row in set (0.00 sec)

之前已经将二进制日志功能临时关闭了,因此这些写操作都没有记录进二进制日志文件中。


此致,对hellodb做温备份过程已经完成了。虽然恢复过程已经完成,但是不要忘记了 开启二进制日志功能。因此,还需要执行如下命令:

mysql> set session sql_log_bin=on;
Query OK, 0 rows affected (0.00 sec)


模拟使用二进制日志文件来恢复数据

8、在hellodb库中创建表wb

mysql> use hellodb
Database changed
mysql> create table wb(name char(20),age tinyint unsigned not null);
Query OK, 0 rows affected (0.02 sec)

然后在插入几行数据

mysql> insert into wb (name,age) values ('tom',30),('boy',19);
Query OK, 2 rows affected (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 0

显示表wb的内容
mysql> select * from wb;
+------+-----+
| name | age |
+------+-----+
| tom  |  30 |
| boy  |  19 |
+------+-----+
2 rows in set (0.00 sec)

此时如果该表没有备份,一不小心表wb被删除了话,该如何恢复。此时就需要借助二进制日志来完成数据恢复功能。


9、模拟表table被删除

mysql> drop table wb;
Query OK, 0 rows affected (0.00 sec)

此时发现二进制日志文件中的position位置发生改变的了,这是因为它将drop table wb该操作写入到了二进制日志文件中去了。那么待会还原的时候,不要将这部分数据倒入到文件中。


mysql> show master status;
+-------------------+----------+--------------+------------------+
| File              | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+-------------------+----------+--------------+------------------+
| master-bin.000005 |      558 |              |                  |
+-------------------+----------+--------------+------------------+
1 row in set (0.00 sec)


10、利用二进制日志文件导出刚刚创建表的过程。

# mysqlbinlog --start-position   --stop-position=451 /mydata/binary/master-bin.000005 > /mybackup/table_wb.sql


11、临时关闭二进制日志功能

mysql> set session sql_log_bin=0;
Query OK, 0 rows affected (0.00 sec)


12、将/mybackup/table_wb.sql文件导入到数据库中

mysql> source /root/table_wb.sql;


13、查看表table文件是否存在

mysql> use hellodb;
Database changed
mysql> show tables;
+-------------------+
| Tables_in_hellodb |
+-------------------+
| classes           |
| coc               |
| courses           |
| scores            |
| students          |
| teachers          |
| toc               |
| wb                |
+-------------------+
8 rows in set (0.01 sec)

显示结果表示表wb已经恢复完成。


查询表table

mysql> select * from wb;
+------+-----+
| name | age |
+------+-----+
| tom  |  30 |
| boy  |  19 |
+------+-----+
2 rows in set (0.00 sec)


14、最后开启二进制日志功能

mysql> set session sql_log_bin=1;
Query OK, 0 rows affected (0.00 sec)



总结:

使用mysqldump做温备份或热备前需要注意的事项:

1、如果做温备,在备份前加读锁,避免有数据写入,但不影响读操作,执行flush tables with read lock命令即可。或者在mysqldump后面加上--lock-all-tables选项即可。

如果做热备,前提是存储引擎为InnoDB,且备份时不需要手动加锁,需要在mysqldump后面加上--single-transaction选项即可。

2、执行flush  logs命令,或者在mysqldump命令后加上--flush-logs选项,用来滚动二进制日志文件,这样下一次的操作都会记录在后面生产的二进制文件中,以便于数据恢复。

3、记录下当前正在使用的二进制日志文件及其下一个事件的position。

4、如果是使用flush tables with read lock来加锁的话,那么备份完成后,执行unlock tables;命令来解锁

5、由于mysqldump备份后的文件都是一些insert、drop等DDL、DML语句,因此,在还原数据过程中,会将该操作记录到二进制日志文件中。因此,在数据恢复过程中,临时关闭二进制日志功能。即使用该命令即可实现set session sql_log_bin=0;

6、恢复完成后还需要开启二进制日志功能。set session sql_log_bin=1;

7、利用二进制文件做恢复时,先使用mysqlbinlog来查看文件并筛选符合的事件条目,然后在重定向到SOMEFILE.sql文件中,然后临时关闭二进制日志功能,最后利用mysql> source  SOMEFILE.sql来恢复数据。

8、利用二进制还原完成后,开启二进制功能set session  sql_log_bin=1;



                                                       

逻辑备份工具select  into   outfile

该工具备份后是一个文本文件,且备份数据和还原速度比较快,占用空间小,不适合对数据库做备份。一般用来做某个表或表中的某个语句做备份。                  

备份语法格式:

SELECT * INTO OUTFILE '/path/to/somefile.txt' FROM tb_name [WHERE clause];

 

 还原语法格式:

LOAD DATA INFILE '/path/to/somefile.txt'  INTO TABLE tb_name;

还原前需要手动创建表结构。