2020-heibaiying- 数据备份与恢复
数据备份与恢复
一、备份简介
2.1 备份分类
按照不同的维度,通常将数据库的备份分为以下几类:
物理备份 与 逻辑备份
- 物理备份:备份的是完整的数据库目录和数据文件。采用该模式会进行大量的
IO 操作,但不含任何逻辑转换,因此备份和恢复速度通常都比较快。 - 逻辑备份:通过数据库结构和内容信息来进行备份。因为要执行逻辑转换,因此其速度较慢,并且在以文本格式保存时,其输出文件的大小大于物理备份。逻辑备份的还原的粒度可以从服务器级别(所有数据库)精确到具体表,但备份不会包括日志文件、配置文件等与数据库无关的内容。
全量备份 与 增量备份
- 全量备份:备份服务器在给定时间点上的所有数据。
- 增量备份:备份在给定时间跨度内(从一个时间点到另一个时间点)对数据所做的更改。
在线备份 与 离线备份
- 在线备份:数据库服务在运行状态下进行备份。此时其他客户端依旧可以连接到数据库,但为了保证数据的一致性,在备份期间可能会对数据进行加锁,此时客户端的访问依然会受限。
- 离线备份:在数据库服务停机状态下进行备份。此备份过程简单,但由于无法提供对外服务,通常会对业务造成比较大的影响。
2.2 备份工具
- mysqldump:这是
MySQL 自带的备份工具,其采用的备份方式是逻辑备份,支持全库备份、单库备份、单表备份。由于其采用的是逻辑备份,所以生成的备份文件比物理备份的大,且所需恢复时间也比较长。 - mysqlpump:这是
MySQL 5.7 之后新增的备份工具,在mysqldump 的基础上进行了功能的扩展,支持多线程备份,支持对备份文件进行压缩,能够提高备份的速度和降低备份文件所需的储存空间。 - Xtrabackup:这是
Percona 公司开发的实时热备工具,能够在不停机的情况下进行快速可靠的热备份,并且备份期间不会间断数据库事务的处理。它支持数据的全备和增备,并且由于其采用的是物理备份的方式,所以恢复速度比较快。
二、mysqldump
2.1 常用参数
# 备份数据库或数据库中的指定表
mysqldump [options] db_name [tbl_name ...]
# 备份多个指定的数据库
mysqldump [options] --databases db_name ...
# 备份当前数据库实例中的所有表
mysqldump [options] --all-databases
-
–host=host_name, -h host_name
指定服务器地址。
-
–user=user_name, -u user_name
指定用户名。
-
–password[=password], -p[password]
指定密码。通常无需在命令行中明文指定,按照提示输入即可。
-
–default-character-set=charset_name
导出文本使用的字符集,默认为
utf8 。 -
–events, -E
备份包含数据库中的事件。
-
–ignore-table=db_name.tbl_name
不需要进行备份的表,必须使用数据库和表名来共同指定。也可以作用于视图。
-
–routines, -R
备份包含数据库中的存储过程和自定义函数。
-
–triggers
备份包含数据库中的触发器。
-
–where=‘where_condition’, -w ‘where_condition’
在对单表进行导出时候,可以指定过滤条件,例如指定用户名
--where="user='jimf'"
或用户范围-w"userid>1"
。 -
–lock-all-tables, -x
锁定所有数据库中的所有表,从而保证备份数据的一致性。此选项自动关闭
--single-transaction
和--lock-tables
。 -
–lock-tables, -l
锁定当前数据库中所有表,能够保证当前数据库中表的一致性,但不能保证全局的一致性。
-
–single-transaction
此选项会将事务隔离模式设置为
REPEATABLE READ 并开启一个事务,从而保证备份数据的一致性。主要用于事务表,如InnoDB 表。 但是此时仍然不能在备份表上执行ALTER TABLE , CREATE TABLE, DROP TABLE, RENAME TABLE,TRUNCATE TABLE 等操作,因为REPEATABLE READ 并不能隔离这些操作。另外需要注意的是
--single-transaction
选项与--lock-tables
选项是互斥的,因为LOCK TABLES 会导致任何正在挂起的事务被隐式提交。转储大表时,可以将--single-transaction
选项与--quick
选项组合使用 。 -
–quick, -q
主要用于备份大表。它强制
mysqldump 一次只从服务器检索一行数据,避免一次检索所有行而导致缓存溢出。 -
–flush-logs, -F
在开始备份前刷新
MySQL 的日志文件。此选项需要RELOAD 权限。如果此选项与--all-databases
配合使用,则会在每个数据库开始备份前都刷新一次日志。如果配合--lock-all-tables
,--master-data
或--single-transaction
使用,则只会在锁定所有表或者开启事务时刷新一次。 -
–master-data[=value]
可以通过配置此参数来控制生成的备份文件是否包含
CHANGE MASTER 语句,该语句中包含了当前时间点二进制日志的信息。该选项有两个可选值:1 和2 ,设置为1 时CHANGE MASTER 语句正常生成,设置为2 时以注释的方式生成。--master-data
选项还会自动关闭--lock-tables
选项,而且如果你没有指定--single-transaction
选项,那么它还会启用--lock-all-tables
选项,在这种情况下,会在备份开始时短暂内获取全局读锁。
2.2 全量备份
# 备份雇员库
mysqldump -uroot -p --databases employees > employees_bak.sql
# 恢复雇员库
mysql -uroot -p < employees_bak.sql
单表备份:
# 备份雇员库中的职位表
mysqldump -uroot -p --single-transaction employees titles > titles_bak.sql
# 恢复雇员库中的职位表
mysql> use employees;
mysql> source /root/mysqldata/titles_bak.sql;
2.3 增量备份
1. 基础全备
--master-data
参数,语句如下:
mysqldump -uroot -p --master-data=2 --flush-logs employees titles > titles_bak.sql
使用
-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000004', MASTER_LOG_POS=155;
2. 增量恢复
对表内容进行任意修改,然后通过分析二进制日志文件来生成增量备份的脚本文件,示例如下:
mysqlbinlog --start-position=155 \
--database=employees ${MYSQL_HOME}/data/mysql-bin.000004 > titles_inr_bak_01.sql
需要注意的是,在实际生产环境中,可能在全量备份后与增量备份前的时间间隔里生成了多份二进制文件,此时需要对每一个二进制文件都执行相同的命令:
mysqlbinlog --database=employees ${MYSQL_HOME}/data/mysql-bin.000005 > titles_inr_bak_02.sql
mysqlbinlog --database=employees ${MYSQL_HOME}/data/mysql-bin.000006 > titles_inr_bak_03.sql
.....
之后将全备脚本
三、mysqlpump
3.1 功能优势
-
能够并行处理数据库及其中的对象,从而可以加快备份进程;
-
能够更好地控制数据库及数据库对象(表,存储过程,用户帐户等
) ; -
能够直接对备份文件进行压缩;
-
备份时能够显示进度指标(估计值
) ; -
备份用户时生成的是
CREATE USER 与GRANT 语句,而不是像mysqldump 一样备份成数据,可以方便用户按需恢复。
3.2 常用参数
-
–default-parallelism=N
每个并行处理队列的默认线程数。默认值为
2 。 -
–parallel-schemas=[N:]db_list
用于并行备份多个数据库:
db_list 是一个或多个以逗号分隔的数据库名称列表;N 为使用的线程数,如果没有设置,则使用--default-parallelism
参数的值。 -
–users
将用户信息备份为
CREATE USER 语句和GRANT 语句 。如果想要只备份用户信息,则可以使用下面的命令:mysqlpump --exclude-databases=% --users
-
–compress-output=algorithm
默认情况下,
mysqlpump 不对备份文件进行压缩。可以使用该选项指定压缩格式,当前支持LZ4 和ZLIB 两种格式。需要注意的是压缩后的文件可以占用更少的存储空间,但是却不能直接用于备份恢复,需要先进行解压,具体如下:# 采用lz4算法进行压缩 mysqlpump --compress-output=LZ4 > dump.lz4 # 恢复前需要先进行解压 lz4_decompress input_file output_file # 采用ZLIB算法进行压缩 mysqlpump --compress-output=ZLIB > dump.zlib zlib_decompress input_file output_file
MySQL 发行版自带了上面两个压缩工具,不需要进行额外安装。以上就是mysqlpump 新增的部分常用参数,完整参数可以参考官方文档:mysqlpump — A Database Backup Program
四、Xtrabackup
4.1 在线安装
# 安装Percona yum 源
yum install https://repo.percona.com/yum/percona-release-latest.noarch.rpm
# 安装
yum install percona-xtrabackup-80
4.2 全量备份
全量备份的具体步骤如下:
1. 创建备份
xtrabackup --backup --user=root --password --parallel=3 --target-dir=/data/backups/
以上进行的是整个数据库实例的备份,如果需要备份指定数据库,则可以使用 –
另外一个容易出现的异常是:/var/lib/mysql/mysql.sock
文件里获取数据库的
2. 准备备份
由于备份是将所有物理库表等文件复制到备份目录,而整个过程需要持续一段时间,此时备份的数据中就可能会包含尚未提交的事务或已经提交但尚未同步至数据文件中的事务,最终导致备份结果处于不一致状态。此时需要进行
xtrabackup --prepare --target-dir=/data/backups/
需要特别注意的在该阶段不要随意中断
3. 恢复备份
由于
# 模拟数据异常丢失
rm -rf /usr/app/mysql-8.0.17/data/*
# 将备份文件拷贝到 data 目录下
xtrabackup --copy-back --target-dir=/data/backups/
/etc/my.cnf
上获取--move-back
命令,代表直接将备份文件移动到数据目录下。此时数据目录的所有者通常为执行命令的用户,需要更改为
chown -R mysql:mysql /usr/app/mysql-8.0.17/data
再次启动即可完成备份恢复。
4.3 增量备份
使用
1. 创建备份
这里首先创建一个全备作为基础:
xtrabackup --user=root --password --backup --target-dir=/data/backups/base/
之后修改库中任意数据,然后进行第一次增量备份,此时需要使用 incremental-basedir
指定基础目录为全备目录:
xtrabackup --user=root --password --backup --target-dir=/data/backups/inc1 \
--incremental-basedir=/data/backups/base
再修改库中任意数据,然后进行第二次增量备份,此时需要使用 incremental-basedir
指定基础目录为上一次增备目录:
xtrabackup --user=root --password --backup --target-dir=/data/backups/inc2 \
--incremental-basedir=/data/backups/inc1
2. 准备备份
准备基础备份:
xtrabackup --prepare --apply-log-only --target-dir=/data/backups/base
将第一次备份作用于全备数据:
xtrabackup --prepare --apply-log-only --target-dir=/data/backups/base \
--incremental-dir=/data/backups/inc1
将第二次备份作用于全备数据:
xtrabackup --prepare --target-dir=/data/backups/base \
--incremental-dir=/data/backups/inc2
在准备备份时候,除了最后一次增备外,其余的准备命令都需要加上 --apply-log-only
选项来阻止事务的回滚,因为备份时未提交的事务可能正在进行,并可能在下一次增量备份中提交,如果不进行阻止,那么增量备份将没有任何意义。
3. 恢复备份
恢复备份和全量备份时相同,只需要最终准备好的全备数据复制到
xtrabackup --copy-back --target-dir=/data/backups/base
# 必须修改文件权限,否则无法启动
chown -R mysql:mysql /usr/app/mysql-8.0.17/data
此时增量备份就已经完成。需要说明的是:按照上面的情况,如果第二次备份之后发生了宕机,那么第二次备份后到宕机前的数据依然没法通过
五、二进制日志的备份
想要备份二进制日志文件,可以通过定时执行
mysqlbinlog --read-from-remote-server --raw --stop-never \
--host=主机名 --port=3306 \
--user=用户名 --password=密码 初始复制时的日志文件名
需要注意的是这里的用户必须具有