MySQL的备份与恢复详解

在公司中备份的策略并非千篇一概的,而是根据每一个企业 的实际生产环境与业务需求制定合适的备份策略。不管是选择彻底备份仍是增量备份,都须要考虑它们的优缺点,是否适合当前的生产环境。同时为了保证恢复的完整性,建议开启二进制日志功能,二进制日志文件给恢复工做带来了很大的灵活性,能够基于时间点或位置进行恢复,考虑到数据库性能,能够将二进制日志文件保存在其余安全的硬盘中。mysql

在进行热备时,备份操做和应用服务在同时运行,这样十分消耗系统资源,致使数据库服务性能降低,这就要求咱们选择一个合适的时间(通常在应用负担很小的时候)再来进行备份操做。sql

须要注意的是,不是备份就万事大吉了,最好确认备份是否可用,因此备份以后的恢复测试是很是有必要的。同时备份时间也要灵活调整,如:数据库

  1. 数据更新频繁,则应该频繁地备份。
  2. 数据的重要性,在有适当更新时进行备份。
  3. 在数据库压力小的时间段进行备份,如一周一次彻底备份,天天进行增量备份。
  4. 中小公司,彻底备份通常一天一次便可。
  5. 大公司可每周进行一次彻底备份,天天进行一次增量备份。
  6. 尽可能为企业实现主从复制架构,以增长数据的可用性。

数据库备份类型能够从两个角度来看待:vim

一、从物理与逻辑的角度:安全

物理备份是对数据库操做系统的物理文件(如数据文件、日志文件等)的备份。这种类型的备份适用于在出现问题时须要快速恢复的大型重要数据库。架构

物理备份有能够分为如下几种类型:ide

①、冷备份:在数据库关闭状态下进行备份操做;工具

②、热备份:在数据库处于运行状态时进行备份操做,该备份方法依赖数据库的日志文件;性能

③、温备份:数据库锁定表格(不可写入,但可读取)的状态下进行备份;测试

逻辑备份是对数据库逻辑组件(如表等数据库对象)的备份,表示为逻辑数据库结构(create database、create table语句)和内容(insert语句或分隔文本文件)的信息。这种类型的备份使用于能够编辑数据值或表结构较小的数据量,或者在不一样的机器体系上从新建立数据。

二、从数据库的备份策略角度:

从数据库的备份策略角度,数据库的备份可分为彻底备份、差别备份和增量备份。其中呢,完整备份是实现差别、增量备份的基础。

  1. 完整备份:每次对数据进行完整的备份,即对整个数据库的备份。备份与恢复的操做很是简单,可是数据存在大量的重复,会占用大量的磁盘空间,备份的时间也很长。
  2. 差别备份:备份那些自从上次彻底备份以后被修改过的全部文件,备份的时间点是从上次完整备份起,备份数据会愈来愈大,恢复数据时,只需恢复上次的彻底备份和最近的一次差别备份。
  3. 增量备份:只有在那些在上次彻底备份或增量备份后被修改的文件才会被备份,以上次完整备份或上次增量备份的时间为时间点,仅仅备份这之间的数据变化,于是备份的数据量也小,占用空间小,备份速度快,但恢复时,须要从上一次的完整备份开始到最后一次增量备份之间的全部增量依次恢复,一旦中间的数据发生损坏,将致使数据的丢失。

来几个备份实例:

一、物理冷备份与恢复:

[root@localhost ~]# tar zcf /backup/mysql_$(date +%F).tar.gz /usr/local/mysql/data  #直接tar打包数据库文件
[root@localhost ~]# cd /backup/
[root@localhost backup]# ls
mysql_2019-05-16.tar.gz              #备份后的文件
[root@localhost backup]#

二、mysqldump备份与恢复:

1)备份某一个表:

[root@localhost backup]# mysqldump -u root -p mysql user > mysql-user.sql          #备份mysql库中的user表
Enter password:              #输入密码
[root@localhost backup]# ls                  #查看备份文件
mysql-user.sql

2)恢复mysql数据库中的user表(注意路径问题):

[root@localhost backup]# mysql -u root -p mysql < mysql-user.sql 
Enter password:

3)备份mysql库:

[root@localhost backup]# mysqldump -u root -p --databases mysql > mysql.sql            #备份mysql库
Enter password:              #输入密码
[root@localhost backup]# ls             #查看备份文件
mysql.sql

4)恢复mysql库:

[root@localhost backup]# mysql -u root -p < mysql.sql 
Enter password:

5)备份全部的库(当导出的数据量较大时,能够添加“--opt”选项以优化执行速度):

[root@localhost backup]# mysqldump -u root -p --opt --all-databases > all-data.sql         #备份全部库
Enter password:            #输入密码
[root@localhost backup]# ls              #查看备份文件
all-data.sql

三、MySQL增量备份与恢复:

与彻底备份不一样,增量备份没有重复数据,备分量不大,时间段,但其恢复比较麻烦,须要上次彻底备份及彻底备份以后的全部增量备份以后才能恢复,并且要对全部增量备份逐个反推恢复。MySQL没有提供直接的增量备份办法,因此通常是经过MySQL提供的二进制日志来间接实现增量备份。

要进行MySQL的增量备份,那么首先须要开启二进制日志功能:

[root@localhost ~]# mkdir /usr/local/mysql/logs      #建立专门存放二进制日志文件的目录
[root@localhost ~]# chown mysql:mysql /usr/local/mysql/logs           #更改目录归属,使其拥有写入权限
[root@localhost ~]# vim /etc/my.cnf        #编辑MySQL的主配文件
[mysqld]
log-bin=/usr/local/mysql/logs/mysql-bin            #写入该行,指定二进制日志的存放位置
[root@localhost ~]# systemctl restart mysqld             #重启服务
[root@localhost ~]# ls -l /usr/local/mysql/logs                #而后便可看到目录下自动生成的日志文件
-rw-rw----. 1 mysql mysql 120 5月  16 14:16 mysql-bin.000001
-rw-rw----. 1 mysql mysql  39 5月  16 14:16 mysql-bin.index

如今全部对数据库的修改,都将记录mysql-bin.000001文件中,当执行“mysqladmin -u root -p flush-logs”刷新二进制日志后,将会继续生成一个名为mysql-bin.000002的文件,以后全部的更改又将存在mysql-bin.000002文件中,以此类推.......

接下来对下面test库中的user_info这个表进行备份:

mysql> select * from user_info;
+---------+----------+---------+
| gonghao | xingming | xingbie |
+---------+----------+---------+
|       1 | zhangsan | nan     |
|       2 | lisi     | nan     |
|       3 | wangwu   | nan     |
+---------+----------+---------+

1)先进行一次彻底备份:

[root@localhost ~]# mysqldump -u root -p test user_info >/backup/user_info_$(date +%F).sql;    #彻底备份
Enter password:                 #输入密码
[root@localhost ~]# ls /backup/              #查看备份生成的文件
user_info_2019-05-16.sql

2)刷新二进制文件:

[root@localhost ~]# mysqladmin -u root -p flush-logs             #刷新日志文件
Enter password: 
[root@localhost ~]# ls -l /usr/local/mysql/logs/           查看,每次刷新后,都会多出一个日志文件,
以后全部的修改,都将保存在这个日志文件中
-rw-rw----. 1 mysql mysql 1007 5月  16 14:36 mysql-bin.000001
-rw-rw----. 1 mysql mysql  120 5月  16 14:36 mysql-bin.000002
-rw-rw----. 1 mysql mysql   78 5月  16 14:36 mysql-bin.index

3)如今数据库中又多了两条数据:

mysql> select * from user_info;
+---------+----------+---------+
| gonghao | xingming | xingbie |
+---------+----------+---------+
|       1 | zhangsan | nan     |
|       2 | lisi     | nan     |
|       3 | wangwu   | nan     |
|       4 | zhaoliu  | nan     |
|       5 | sunqi    | nan     |
+---------+----------+---------+

4)若是如今这个表被误删了,那么能够这样恢复:

[root@localhost ~]# mysqladmin -u root -p flush-logs    #刷新日志
Enter password: 

[root@localhost ~]# mysql -u root -p test < /backup/user_info_2019-05-16.sql          #先恢复彻底备份
Enter password: 
[root@localhost ~]# mysql -u root -p -e ' select * from test.user_info;'             #彻底备份的内容恢复成功
Enter password: 
+---------+----------+---------+
| gonghao | xingming | xingbie |
+---------+----------+---------+
|       1 | zhangsan | nan     |
|       2 | lisi     | nan     |
|       3 | wangwu   | nan     |
+---------+----------+---------+

在恢复增量备份时,--no-defaults选项必需要有,不然会报错:

[root@localhost ~]# mysqlbinlog --no-defaults /usr/local/mysql/logs/mysql-bin.000002 | mysql -u root -p    #恢复增量备份
Enter password: 
[root@localhost ~]# mysql -u root -p -e ' select * from test.user_info;'         #查看是否恢复成功
Enter password: 
+---------+----------+---------+
| gonghao | xingming | xingbie |
+---------+----------+---------+
|       1 | zhangsan | nan     |
|       2 | lisi     | nan     |
|       3 | wangwu   | nan     |
|       4 | zhaoliu  | nan     |
|       5 | sunqi    | nan     |
+---------+----------+---------+

恢复成功了,那么还有基于位置、时间的恢复,命令格式以下:

[root@localhost ~]# mysqlbinlog --no-defaults /usr/local/mysql/logs/mysql-bin.000002    #使用工具查看日志文件

........................
# at 199       #199即为一个动做的位置,接下来就是这个动做的时间
#190516 14:39:47 server id 1  end_log_pos 322 CRC32 0x5339b5bd  Query   thread_id=5 exec_time=0 error_code=0
use `test`/*!*/;
SET TIMESTAMP=1557988787/*!*/;
insert into user_info values('4','zhaoliu','nan')
/*!*/;
# at 322
#190516 14:39:47 server id 1  end_log_pos 353 CRC32 0x873df67e  Xid = 54
COMMIT/*!*/;               #该字样表示为提交
# at 353
#190516 14:39:57 server id 1  end_log_pos 432 CRC32 0xcd2543f7  Query   thread_id=5 exec_time=0 error_code=0
SET TIMESTAMP=1557988797/*!*/;
BEGIN
/*!*/;
# at 432
#190516 14:39:57 server id 1  end_log_pos 553 CRC32 0xc1300526  Query   thread_id=5 exec_time=0 error_code=0
SET TIMESTAMP=1557988797/*!*/;
insert into user_info values('5','sunqi','nan')
/*!*/;
# at 553
#190516 14:39:57 server id 1  end_log_pos 584 CRC32 0xebb496fb  Xid = 55
COMMIT/*!*/;

......................

[root@localhost ~]# mysqlbinlog --no-defaults --start-position='353' /usr/local/mysql/logs/mysql-bin.000002 | mysql -u root -p      
Enter password:

--start-position='353':表示为从位置353开始恢复,该日志文件353以前的数据不会恢复;

以上选项可更改成下面类型:

--stop-position='353':表示恢复到位置353就中止,该日志文件353以后的数据不会恢复;

基于时间点的恢复:

--start-datetime='2019-05-16 14:39:47':表示恢复该时间以后的数据;

--stop-datetime='2019-05-16 14:39:47':表示仅恢复该时间以前的数据;

切记,全部类型的增量恢复以前,都必须先执行最近一次的彻底恢复。

相关文章
相关标签/搜索