删库不跑路-详解MySQL备份策略

手抖、写错条件、写错表名、错连生产库形成的误删库表和数据总有据说,那么删库以后除了跑路,还能作什么呢,固然是想办法恢复,恢复数据的基础就在于完善的备份策略。html

备份和恢复是同一个话题,篇幅有限,就分开两章写mysql

1 关于备份

1.1 为何要备份

  • 灾难恢复,数据库在运行过程当中,终会遇到各类各样的问题: 硬件故障、Bug 致使数据损坏、因为服务器宕机或者其余缘由形成的数据库不可用。除此之外还有人为操做:DELETE 语句忘加条件、ALTER TABLE 执行错表、DROP TABLE 执行错表、黑客攻击,即便这些问题你都还没遇到,可是根据墨菲定律,总会有赶上的时候。
  • 回滚,因为某种Bug或系统被黑形成大量的损失,这个时候就须要回滚到某个状态。常见的有区块链交易所被黑而后回滚,游戏漏洞被利用而后总体回滚。
  • 审计,有时候有这样的需求:须要知道某一个时间点的数据是怎么样的,多是年底审计,也多是由于官司。
  • 测试,一个基本的测试需求是,定时拉取线上数据到测试环境,若是有备份,就能够很是方便地拉取数据。

1.2 有哪些备份方式

1.2.1 逻辑备份

逻辑备份是最多见的方式,在数据量比较少的时候很经常使用。sql

逻辑备份的优点:数据库

  • 备份恢复比较简单,例如 mysqldump 就是 MySQL 自带的备份工做,无需额外安装。恢复的时候能够直接使用 mysql 命令进行恢复。
  • 能够远程备份和恢复,也就是说,能够在其余机器执行备份命令。
  • 备份出来的数据很是直观,备份出来后,可使用 sed grep 等工具进行数据提取或者修改。
  • 与存储引擎无关,由于备份文件是直接从 MySQL 里面提取出来的数据,因此在直观上,备份数据数据不对引擎作区分,能够很方便地从 MyISAM 引擎改到 InnoDB 引擎。
  • 避免受到文件损坏的影响,若是直接复制原始文件,可能会受到某个文件损坏的影响而获得一个损坏的备份。使用逻辑备份,只要 MySQL 还能执行 SELECT 语句,就能够获得一份能够信赖的逻辑备份,在文件损坏的时候颇有用。

逻辑备份缺点:segmentfault

  • 由于必须使用 MySQL 服务进行数据操做,因此备份的时候会占用更多 CPU,且备份时间可能会更长。
  • 逻辑备份在某些场景下比数据库文件更大,文本存储的数据不老是比存储引擎更高效。固然,使用压缩的话会获得一个更小的备份,可是要占用 CPU 资源。(若是索引较多,逻辑备份会比物理备份小。)
  • 恢复时间更长,使用逻辑备份的数据恢复,须要占用更多资源去进行锁分配、索引构建、冲突检查、日志刷新。

逻辑备份经常使用方法:缓存

  • mysqldumpMySQL自带的备份工具,通用性强,很是常见。使用的使用一般要加上一些参数,后面继续介绍。
  • select into outfile,以符号分割数据建立逻辑备份,对于要导入到 CSV 等表格会比较实用。
  • mydumper,容许使用多线程进行备份,备份文件会进行表结构和数据分离,在恢复某些表或数据的时候会很是有效。

1.2.2 物理备份

物理备份在数据量较大的时候很是常见。安全

物理备份的优点:服务器

  • 备份速度快,由于物理备份是基于复制进行备份,意味者复制有多快,备份就能有多快。
  • 恢复速度快,只须要把文件复制到数据库目录就能够完成恢复,不须要检查锁、构建索引。
  • 恢复简单,对于 MySIAM 引擎的表,不须要停库,只须要简单地复制进数据目录就能够。对于 InnoDB,若是是每一个表一个表空间,也能够不停库操做,使用卸载加载表空间的方式即可导入(不太安全)。

物理备份缺点:多线程

  • 没有官方物理热备份工具的支持。没有官方工具的支持,意味着出问题的几率较大,使用的时候就要谨慎了
  • InnoDB 的原始文件一般比逻辑备份要大。InnoDB 表空间每每包含不少未被使用的空间,InnoDB 表在删除数据后不会释放空间,因此即便数据量不大,文件有可能很大。除此之外,文件中除了数据还包含了索引、日志等信息。
  • 物理备份不总能够跨平台跨版本。MySQL 文件和操做系统、MySQL 版本息息相关,若是环境与原来不一致,颇有可能会出现问题。

物理备份经常使用方法:app

  • xtrabackup 是最经常使用的物理备份工具,由 percona 开源,可以实现对 InnoDB 存储引擎和 XtraDB 存储引擎非阻塞地备份(对于 MyISAM 仍是要加锁),获得一份一致性备份。
  • 直接复制文件/文件系统快照,这种方式对于 MySIAM 引擎是很是高效的,只须要执行 FLUSH TABLE WITH READ LOCK 就能够复制获得一份备份文件。可是对于 InnoDB 引擎就比较困难,由于 InnoDB 引擎使用了大量的异步技术,即便执行了 FLUSH TABLE WITH READ LOCK,它仍是会继续合并日志、缓存数据。因此要用这种方法备份 InnoDB,须要确保 checkpoint 已经最新。

1.2 为何要备份 binlog

若是有 DBA 告诉你,这个数据库可以恢复到两个个月内任何状态,这说明了,这个数据库的 binlog 日志至少保留了两个月。备份 binlog 的好处:

  • 能够实现基于任意时间点的恢复
  • 能够用于误操做数据闪回
  • 能够用于审计

当你要进行数据恢复的时候,就会很是庆幸有作 binlog 备份。固然,使用 binlog 恢复数据的前提是 binlog 格式要设为 row,不要担忧空间问题,当前最不缺的资源就是硬盘空间。对于 binlog,咱们推荐的配置是

# 记录每一行数据的变化
binlog_format = row
# 备库在重作数据的时候,记录一条 binlog
log_slave_updates = 1

1.3 复制和备份

主从复制等于多了一个数据副本,可是复制并不等于备份,也不能代替备份。假设在主库执行了 drop table 操做,会马上同步到备库,并执行相同的操做,没有办法在出现意外的时候使用备库进行数据恢复。

延迟复制也不能代替备份,可是能加快恢复的速度,是一种很是有用的策略。

在实际使用中,为了避免影响主库的使用,咱们每每会在备库进行备份,同时记录同步点,以方便进行新备库搭建。在备库备份须要注意的是,主从复制并不能保证主备间数据是一致的。实际上,基于复制的 MySQL 集群并不能保证集群内部一致性,当前也没有很是好的办法,经常使用的是使用 pt-table-checksum 进行一致性检查。

2. 全量备份

全量备份介绍最经常使用的逻辑备份工具 mysqldump 和物理备份工具 xtrabackup。若是对 mysqldump 不太满意 可使用 mydumper 来替代 mysqldump

2.1 mysqldump

mysqldump 是用得最多的工具,可是要用好的话,须要增长一些额外的参数。mysqldump 有不少可用参数,这里不展开,建议直接访问官网 mysqldump。使用 mysqldump 某些参数须要 select,reload,lock tables 权限。

2.1.1 常见例子

2.1.1.1 InnoDB 全库备份

mysqldump --opt --single-transaction --master-data=2 --default-character-set=utf8 -h<host> -u<user> -p<password> -A > backup.sql
  • --opt 若是有这个参数表示同时激活了mysqldump命令的quick,add-drop-table,add-locks,extended-insert,lock-tables参数,它能够给出很快的转储操做并产生一个能够很快装入MySQL服务器的转储文件。当备份大表时,这个参数能够防止占用过多内存
  • --single-transaction 设置事务的隔离级别为可重复读,而后备份的时候开启事务,这样能保证在一个事务中全部相同的查询读取到一样的数据。注意,这个参数只对支持事务的引擎有效,若是有 MyISAM 的数据表,并不能保证数据一致性
  • -A 导出所有数据库
  • –-default-character-set=charset 指定导出数据时采用何种字符集
  • --master-data=2 表示在备份过程当中记录主库的 binlogpos 点,并在dump文件中注释掉这一行,在使用备份文件作新备库时会用到

2.1.1.2 MyISAM 全库备份

mysqldump --opt --lock-all-tables --master-data=2 --default-character-set=utf8 -h<host> -u<user> -p<password> -A > backup.sql
  • --lock-all-tables 锁表备份。因为 MyISAM 不能提供一致性读,若是要获得一份一致性备份,只能进行全表锁定。

2.1.1.3 备份带上压缩

mysqldump -h<host> -u<user> -p<password> -A | gzip >> backup.sql.gz

2.1.1.4 备份多个库

mysqldump -h<host> -u<user> -p<password> --databases <dbname1> <dbname2> > backup.sql

2.1.2 恢复

恢复方式比较简单,直接执行 sql 语句就能够了

mysql -h<host> -u<user> -p<password> < backup.sql

2.1.3 mysqldump执行流程

打开 general_log 能够查看 mysqldump 的执行流程,这里以 --single-transaction --opt -A 参数为例

FLUSH /*!40101 LOCAL */ TABLES
FLUSH TABLES WITH READ LOCK
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ
START TRANSACTION
SHOW VARIABLES LIKE 'gtid\_mode'
SHOW MASTER STATUS
UNLOCK TABLES
...
SHOW CREATE DATABASE IF NOT EXISTS `employees`
SAVEPOINT sp
...
SELECT /*!40001 SQL_NO_CACHE */ * FROM `departments`
....

2.2 xtrabackup

2.2.1 安装方式

更多安装方式参考官网 xtrabackup

这里咱们使用 rpm 安装的方式

yum install http://www.percona.com/downloads/percona-release/redhat/0.1-6/percona-release-0.1-6.noarch.rpm
yum update percona-release
# qpress 用做压缩解压
yum install percona-xtrabackup-24 qpress

2.2.2 使用方法

2.2.2.1 增长备份帐号并受权

CREATE USER 'backup'@'localhost' IDENTIFIED BY 'backup';
GRANT PROCESS,RELOAD, LOCK TABLES, REPLICATION CLIENT ON *.* TO 'backup'@'localhost';
FLUSH PRIVILEGES;

2.2.2.2 全备

innobackupex --defaults-file=/etc/my.cnf --user=<user> --password=<pwd> <要备份到哪一个目录> --no-timestamp --compress --compress-threads=4 --parallel=4
  • --no-timestamp 不使用当前时间创建文件夹。默认状况下会在备份目录以当前时间建立文件夹
  • --compress 压缩
  • --compress-threads=N 压缩线程
  • --parallel=N 备份线程

2.2.2.3 恢复

# 步骤一:解压
innobackupex --decompress <备份文件所在目录> --parallel=4

# 步骤二:应用日志
innobackupex --apply-log <备份文件所在目录> --parallel=4

# 步骤三:复制备份文件到数据目录
innobackupex --datadir=<MySQL数据目录> --copy-back <备份文件所在目录> --parallel=4

3. 增量备份

当数据了变得庞大时,一个常见策略就是作按期的增量备份。例如:周一作了一次全量备份,而后周二到日作增量备份。

增量备份只包含变化的数据集,通常状况不会比原始数据量大,因此能够减小服务器的开销、备份时间、备份空间。

固然,使用增量备份也会有风险,增量备份每一次迭代都是基于上一次的备份实现,意味着只要其中一份备份出现问题,那么就有可能致使全部备份不可用。

下面介绍一些增量备份方法:

3.1 使用 xtrabackup 作增量备份

xtrabackup 容许进行增量备份,命令以下:

innobackupex --defaults-file=/etc/my.cnf --user=<user> --password=<pwd> --no-timestamp --compress --incremental --incremental-basedir=<全量备份的目录> <要增量备份到什么目录>

恢复:

# 步骤一:对全备解压
innobackupex --decompress <全量备份文件所在目录>

# 步骤二:对全备应用日志
innobackupex --apply-log --redo-only <全量备份文件所在目录>

# 步骤三:对增量备份进行解压
innobackupex --decompress <增量文件所在目录>

# 步骤四:合并增量数据
innobackupex --apply-log --redo-only --incremental <全量备份文件所在目录> --incremental-dir=<增量文件所在目录>

# 步骤五:对合并后的数据应用日志
innobackupex --apply-log <全量备份文件所在目录>

# 步骤六:复制备份文件到数据目录
innobackupex --datadir=<MySQL数据目录> --copy-back <全量备份文件所在目录>

3.2 使用 binlog 作增量备份

使用 binlog 作增量备份比较简单,备份的时候执行 FLUSH LOGS 轮转日志,而后把旧的 binlog 复制到备份目录就能够了。

恢复的时候使用 mysqlbinlog --start-position=<备份集的pos点> binlog日志 | mysql -u<user> -p 就能够了

4. 延迟同步

延迟同步是常见的使用主从复制使用模式,在遇到误操做的时候,不管是用于恢复数据,仍是使用跳过的方式跳过错误都是很是有用。

例如在主库作了 drop 的误操做,在主库找到命令所在 binlog 日志和 pos 位置,Delay库中止同步,而后使用 start slave until master_log_file='<对应file>',master_log_pos=<误操做命令前一个SQL的pos>; 等待同步到这个位置,执行跳过一条 SQL 的命令再开启同步。

常见的延迟同步复制模式有:

一主带三从

图片描述

有时候为了减小主库压力,会把延迟库放在备节点以后

图片描述

延迟同步开启方式以下:

stop slave;
CHANGE MASTER TO MASTER_DELAY = N秒;
start slave;

5. 数据校验

除了备份,很是重要的一件事情就是验证备份数据的可用性。想象一下,当你须要进行数据恢复的时候,突然发现过去的备份数据都是无效的,那得有多难受。不少朋友在写好备份脚本加到定时任务后,只要检查到定时任务有执行,备份目录有文件就再也不关注了,每每到了须要使用备份文件的时候才发现备份数据有问题。

目前对于备份文件的数据校验没有很是方便的办法,用的比较多的仍是定时把备份文件拉出来作备份恢复演练,例如一个月作一次备份恢复演练就能够有效提升备份文件可用性,内心也踏实。

数据校验部分,若是是逻辑备份,每每会抽查某个表的数据,检查是否符合预期。若是是物理备份,首先要使用 mysqlcheck 等命令检查是否有表损坏,没有损坏再抽查表数据。

6. 总结

  1. 逻辑备份和物理备份能够一块儿使用,不一样的备份周期使用不一样的工具,全备周期不该该太长,至少一周一次全备
  2. 若是数据量较大,可使用增量备份的方式减小数据量,要注意的是,增量备份风险更大
  3. binlog功能要开启,设为 row 模式,设置 log_slave_updates = 1,且最好定时备份 binlog
  4. 有条件的话能够增长一个 Delay 库,在作紧急恢复的时候有奇效
  5. 数据校验要定时去作,不然当须要备份恢复的时候而备份文件又失效,后悔都来不及

参考资料:

  • 高性能MySQL(第3版)
相关文章
相关标签/搜索