按照不一样的思考维度,一般将数据库的备份分为如下几类:html
物理备份 与 逻辑备份mysql
全量备份 与 增量备份git
在线备份 与 离线备份github
MySQL 支持的备份工具备不少种,这里列出经常使用的三种:算法
mysqldump 的基本语法以下:sql
# 备份数据库或数据库中的指定表
mysqldump [options] db_name [tbl_name ...]
# 备份多个指定的数据库
mysqldump [options] --databases db_name ...
# 备份当前数据库实例中的全部表
mysqldump [options] --all-databases
复制代码
options 表明可选操做,经常使用的可选参数以下:shell
--host=host_name, -h host_name数据库
指定服务器地址。缓存
--user=user_name, -u user_namebash
指定用户名。
--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
选项,在这种状况下,会在备份开始时短暂内获取全局读锁。
mysqldump 的全量备份与恢复的操做比较简单,示例以下:
# 备份雇员库
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;
复制代码
mysqldump 自己并不能直接进行增量备份,须要经过分析二进制日志的方式来完成。具体示例以下:
1.先执行一次全备做为基础,这里以单表备份为例,须要用到上文提到的 --master-data
参数,语句以下:
mysqldump -uroot -p --master-data=2 --flush-logs employees titles > titles_bak.sql
复制代码
使用 more 命令查看备份文件,此时能够在文件开头看到 CHANGE MASTER 语句,语句中包含了二进制日志的名称和偏移量信息,具体以下:
-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000004', MASTER_LOG_POS=155;
复制代码
对表内容进行任意修改,而后经过分析二进制日志文件来生成增量备份的脚本文件,示例以下:
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
.....
复制代码
以后将全备脚本 ( titles_bak.sql ),以及全部的增备脚本 ( inr_01.sql,inr_02.sql .... ) 经过 source 命令导入便可,这样就完成了全量 + 增量的恢复。
mysqlpump 在 mysqldump 的基础上进行了扩展加强,其主要的优势以下:
可以并行处理数据库及其中的对象,从而能够加快备份进程;
可以更好地控制数据库及数据库对象(表,存储过程,用户账户等);
可以直接对备份文件进行压缩;
备份时可以显示进度指标(估计值);
备份用户时生成的是 CREATE USER 与 GRANT 语句,而不是像 mysqldump 同样备份成数据,能够方便用户按需恢复。
mysqlpump 的使用和 mysqldump 基本一致,这里再也不进行赘述。如下主要介绍部分新增的可选项,具体以下:
--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 能够直接使用 yum 命令进行安装,这里个人 MySQL 为 8.0 ,对应安装的 Xtrabackup 也为 8.0,命令以下:
# 安装Percona yum 源
yum install https://repo.percona.com/yum/percona-release-latest.noarch.rpm
# 安装
yum install percona-xtrabackup-80
复制代码
全量备份的具体步骤以下:
Xtrabackup 全量备份的基本语句以下,可使用 target-dir 指明备份文件的存储位置,parallel 则是指明操做的并行度:
xtrabackup --backup --user=root --password --parallel=3 --target-dir=/data/backups/
复制代码
以上进行的是整个数据库实例的备份,若是须要备份指定数据库,则可使用 --databases 进行指定。
另一个容易出现的异常是:Xtrabackup 在进行备份时,默认会去 /var/lib/mysql/mysql.sock
文件里获取数据库的 socket 信息,若是你修改了数据库的 socket 配置,则须要使用 --socket 参数进行从新指定,不然会抛出找不到链接的异常。备份完整后须要当即执行的另一个操做是 prepare (准备备份)。
因为备份是将全部物理库表等文件复制到备份目录,而整个过程须要持续一段时间,此时备份的数据中就可能会包含还没有提交的事务或已经提交但还没有同步至数据文件中的事务,最终致使备份结果处于不一致状态。此时须要进行 prepare 操做来回滚未提交的事务及同步已经提交的事务至数据文件,从而使得总体达到一致性状态。命令以下:
xtrabackup --prepare --target-dir=/data/backups/
复制代码
须要特别注意的在该阶段不要随意中断 xtrabackup 进程,由于这可能会致使数据文件损坏,备份将没法使用。
因为 xtrabackup 执行的是物理备份,因此想要进行恢复,必须先要中止 MySQL 服务。同时这里咱们能够删除 MySQL 的数据目录来模拟数据丢失的状况,以后使用如下命令将备份文件拷贝到 MySQL 的数据目录下:
# 模拟数据异常丢失
rm -rf /usr/app/mysql-8.0.17/data/*
# 将备份文件拷贝到 data 目录下
xtrabackup --copy-back --target-dir=/data/backups/
复制代码
copy-back 命令只须要指定备份文件的位置,不须要指定 MySQL 数据目录的位置,由于 Xtrabackup 会自动从 /etc/my.cnf
上获取 MySQL 的相关信息,包括数据目录的位置。若是不须要保留备份文件,能够直接使用 --move-back
命令,表明直接将备份文件移动到数据目录下。此时数据目录的全部者一般为执行命令的用户,须要更改成 mysql 用户,命令以下:
chown -R mysql:mysql /usr/app/mysql-8.0.17/data
复制代码
再次启动便可完成备份恢复。
使用 Xtrabackup 进行增量备份时,每一次增量备份都须要以上一次的备份为基础,以后再将增量备份运用到第一次全备之上,从而完成备份。具体操做以下:
这里首先建立一个全备做为基础:
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
复制代码
准备基础备份:
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
选项来阻止事务的回滚,由于备份时未提交的事务可能正在进行,并可能在下一次增量备份中提交,若是不进行阻止,那么增量备份将没有任何意义。
恢复备份和全量备份时相同,只须要最终准备好的全备数据复制到 MySQL 的数据目录下便可:
xtrabackup --copy-back --target-dir=/data/backups/base
# 必须修改文件权限,不然没法启动
chown -R mysql:mysql /usr/app/mysql-8.0.17/data
复制代码
此时增量备份就已经完成。须要说明的是:按照上面的状况,若是第二次备份以后发生了宕机,那么第二次备份后到宕机前的数据依然无法经过 Xtrabackup 进行恢复,此时就只能采用上面介绍的分析二进制日志的恢复方法。由此能够看出,不管是采用何种备份方式,二进制日志都是很是重要的,所以最好对其进行实时备份。
想要备份二进制日志文件,能够经过定时执行 cp 或 scp 等命令来实现,也能够经过 mysqlbinlog 自带的功能来实现远程备份,将远程服务器上的二进制日志文件复制到本机,命令以下:
mysqlbinlog --read-from-remote-server --raw --stop-never \
--host=主机名 --port=3306 \
--user=用户名 --password=密码 初始复制时的日志文件名
复制代码
须要注意的是这里的用户必须具备 replication slave 权限,由于上述命令本质上是模拟主从复制架构下,从节点经过 IO 线程不断去获取主节点的二进制日志,从而达到备份的目的。
更多文章,欢迎访问 [全栈工程师手册] ,GitHub 地址:github.com/heibaiying/…