MySQL的备份与恢复详解

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

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

需要注意的是,不是备份就万事大吉了,最好确认备份是否可用,所以备份之后的恢复测试是非常有必要的。同时备份时间也要灵活调整,如:

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

数据库备份类型可以从两个角度来看待:

1、从物理与逻辑的角度:

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

物理备份有可以分为以下几种类型:

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

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

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

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

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

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

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

来几个备份实例:

1、物理冷备份与恢复:

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

2、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

3、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=0use `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 = 54COMMIT/*!*/; #该字样表示为提交# at 353#190516 14:39:57 server id 1 end_log_pos 432 CRC32 0xcd2543f7 Query thread_id=5 exec_time=0 error_code=0SET 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=0SET 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 = 55COMMIT/*!*/;......................[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‘:表示仅恢复该时间之前的数据;

切记,所有类型的增量恢复之前,都必须先执行最近一次的完全恢复。

相关文章