1. 确定待备份数据/文件
1)数据 2)二进制日志/InnoDB事务日志 3)代码块(存储过程,触发器,job等存储到mysql库的对象) 4)配置文件(服务器配置文件,复制配置相关文件)
2. 备份分类
2.1 备份数据的方式
热备份:当进行备份数据时,不会影响系统业务正常读写。
温备份:当进行备份数据时,可以进行读操作,但不能进行写操作。
冷备份:需要下线数据库后,才能进行备份数据。
2.2 数据备份的类型
完全备份:备份整个数据集
增量备份:备份自上一次任意类型的备份(全备或增备)以后所有变化的数据
差异备份:备份自上一次全备以来所有变化的数据
2.3文件备份类型分类
逻辑备份:将数据包含在一种MySQL能够解析的格式的文件中。如:SQL或是某符号分隔的文本文件。
裸文件备份(物理备份):对数据库的物理对象(数据文件,日志文件,配置文件等)进行备份。
逻辑备份优缺点:
优点:
1)逻辑备份文件可以方便查看和操作;
2)恢复非常简单;
3)跨平台系统;
4)与存储引擎无关;
缺点:
1)必须由数据库服务器完成生成逻辑备份的工作,需要占用服务器资源;
2)逻辑备份在某些场景下比数据库文件本身更大;
3)从逻辑备份中还原需要MySQL加载和解析语句,转化为存储格式,并重建索引,相对会很慢。
4)数据和结构存储在一起(尽管可以单独分开2次完成导出备份)
最大的缺点是从MySQL中导出数据和通过SQL语句将其加载回去的开销。
物理备份优缺点:
优点:
1)基于文件的物理备份,只需将文件复制到其它地方即可完成备份;
2)恢复简单,只需将备份文件复制到目标目录即可;
3)恢复速度快,不需要MySQL服务器执行任何SQL或构建索引。
缺点:
1)InnoDB的原始文件通常比相应的逻辑备份文件大(包含未使用的空间,插入缓冲,回滚段等)
2)物理备份不总是可以跨平台,操作系统和MySQL版本。
3. 备份恢复指标
RPO:恢复点目标,可以容忍丢失多少数据
RTO:恢复时间目标,需要等待多长时间将数据恢复
4. 备份工具
4.1 逻辑备份工具
1)mysqldump :官方自带,单线程备份慢的问题,适用于小表/小库数据备份。
2) mydumper:社区提供,使用myloader进行恢复。支持多线程备份和文件压缩功能。
3) select into outputfile : 使用分隔符文件格式创建逻辑备份。
4.2 物理备份工具
1)Xtrabackup: Percona公司提供开源免费数据库备份软件,它能对InnoDB数据库和XtraDB存储引擎的数据库非阻塞地备份(对于MyISAM的备份同样需要加表锁FTWRL)。
2)ibbackup:付费工具。
5. 备份相关性能因素
1)锁时间,如(FTWRL)
在众多备份方法中,一个最大的问题时使用FLUSH TABLE WITH READ LOCK (FTWRL)操作。这个操作会锁住所有表,将MsISAM的数据文件刷新到磁盘(InnoDB表不需要此过程),并刷新查询缓存。该操作需要非常长的时间来完成。
2)备份时间
3)备份负载
4)恢复时间
5)数据一致性
6)文件一致性
6. 各工具备份过程
6.1 mysqldump
1) 重要参数
--single-transaction:在开始备份前,执行start transaction命令,以此来获取一致性备份,该参数仅对innodb存储引擎有效。 --master-data=2:主要用于记录一致性备份的位点(position/gtid)。
2)流程步骤
1.调用FTWRL(flush tables with read lock),全局禁止读写 2.开启快照读,获取此时的快照(仅对innodb表起作用) 3.备份非innodb表数据(*.frm,*.myi,*.myd等) 4.非innodb表备份完毕后,释放FTWRL锁 5.逐一备份innodb表数据 6.备份完成。
3) 示例
-- 全库备份 mysqldump -uroot -proot -A --single-transaction > all_$(date +%Y%m%d).sql -- 全库恢复 mysql -uroot -proot < all_$(date +%Y%m%d).sql -- 单库备份 mysqldump -uroot -proot -A --single-transaction db1 > db1_$(date +%Y%m%d).sql -- 单库恢复,若db1已经删除则需要先创建 mysql -uroot -proot db1 < db1_$(date +%Y%m%d).sql -- 单表备份 mysqldump -uroot -proot -A --single-transaction db1 t > db1.t_$(date +%Y%m%d).sql -- 单表恢复 mysql -uroot -proot db1 < db1.t_$(date +%Y%m%d).sql -- 备份db1中t表的表结构 mysqldump -uroot -proot --single-transaction db1 t -d > t.sql -- 备份db1中t表id>3的记录 mysql -uroot -proot --single-transaction db1 t --where="id>3" > t.sql
mysqldump命令工具缺点:若出现需要将磁盘数据调回到内存的情况下,可能会将内存中的热数据给冲掉,从而导致性能问题。在mysql5.7中增加innodb_buffer_pool_dump_pct参数,来控制每个innodb buffer中转储活跃数据使用innodb buffer pages的比例,只有当数据库在1s内再次被访问时,才能放到热区域,从而避免热数据被冲掉的情况,默认值为25%。
6.2 mydumper/myloader
1) 软件安装
# 下载地址: https://launchpad.net/mydumper/+download yum -y install glib2-devel mysql-devel zlib-devel pcre-devel zlib gcc-c++ gcc cmake tar -xf mydumper-0.9.1.tar.gz cd mydumper-0.9.1 cmake --prefix=/ups/app/mysql/mydumper make --jobs $(grep -ci processor /proc/cpuinfo) make --jobs $(grep -ci processor /proc/cpuinfo) install
2) mydumper参数

-B, --database 要备份的数据库,不指定则备份所有库 -T, --tables-list 需要备份的表,名字用逗号隔开 -o, --outputdir 备份文件输出的目录 -s, --statement-size 生成的insert语句的字节数,默认1000000 -r, --rows 将表按行分块时,指定的块行数,指定这个选项会关闭 --chunk-filesize -F, --chunk-filesize 将表按大小分块时,指定的块大小,单位是 MB -c, --compress 压缩输出文件 -e, --build-empty-files 如果表数据是空,还是产生一个空文件(默认无数据则只有表结构文件) -x, --regex 是同正则表达式匹配 'db.table' -i, --ignore-engines 忽略的存储引擎,用都厚分割 -m, --no-schemas 不备份表结构 -k, --no-locks 不使用临时共享只读锁,使用这个选项会造成数据不一致 --less-locking 减少对InnoDB表的锁施加时间(这种模式的机制下文详解) -l, --long-query-guard 设定阻塞备份的长查询超时时间,单位是秒,默认是60秒(超时后默认mydumper将会退出) --kill-long-queries 杀掉长查询 (不退出) -b, --binlogs 导出binlog -D, --daemon 启用守护进程模式,守护进程模式以某个间隔不间断对数据库进行备份 -I, --snapshot-interval dump快照间隔时间,默认60s,需要在daemon模式下 -L, --logfile 使用的日志文件名(mydumper所产生的日志), 默认使用标准输出 --tz-utc 跨时区是使用的选项,不解释了 --skip-tz-utc 同上 --use-savepoints 使用savepoints来减少采集metadata所造成的锁时间,需要 SUPER 权限 --success-on-1146 Not increment error count and Warning instead of Critical in case of table doesn't exist -h, --host 连接的主机名 -u, --user 备份所使用的用户 -p, --password 密码 -P, --port 端口 -S, --socket 使用socket通信时的socket文件 -t, --threads 开启的备份线程数,默认是4 -C, --compress-protocol 压缩与mysql通信的数据 -V, --version 显示版本号 -v, --verbose 输出信息模式, 0 = silent, 1 = errors, 2 = warnings, 3 = info, 默认为 2
3)myloader参数

-d, --directory 备份文件的文件夹 -q, --queries-per-transaction 每次事物执行的查询数量,默认是1000 -o, --overwrite-tables 如果要恢复的表存在,则先drop掉该表,使用该参数,需要备份时候要备份表结构 -B, --database 需要还原的数据库 -e, --enable-binlog 启用还原数据的二进制日志 -h, --host 主机 -u, --user 还原的用户 -p, --password 密码 -P, --port 端口 -S, --socket socket文件 -t, --threads 还原所使用的线程数,默认是4 -C, --compress-protocol 压缩协议 -V, --version 显示版本 -v, --verbose 输出模式, 0 = silent, 1 = errors, 2 = warnings, 3 = info, 默认为2
4)示例
# 备份 sakila库
mydumper -u root -p root -P 3308 -h localhost -S -B sakila -o /ups/data/mydata/backup/mydumper/
# 恢复 sakila库
mycli -e "drop database sakila;"
myloader -u root -p root -P 3308 -h localhost -B sakila -d /ups/data/mydata/backup/mydumper/
5) 备份流程
1) 主线程 FLUSH TABLES WITH READ LOCK(FTWRL), 施加全局只读锁,保证数据的一致性 2) 读取当前时间点的二进制日志文件名和日志写入的位置并记录在metadata文件中,以供即使点恢复使用 3) N个(默认是4)dump线程把事务隔离级别改为可重复读并开启读一致的事物 4) dump non-InnoDB tables, 首先导出非事物引擎的表 5) 主线程 UNLOCK TABLES 非事物引擎备份完后,释放全局只读锁 6) dump InnoDB tables, 基于事物导出InnoDB表 7) 事物结束
6.3 xtrabackup
6.3.1 备份过程

# 备份过程 1> innobackupex 在启动后,会先 fork 一个进程,启动 xtrabackup进程,然后就等待 xtrabackup 备份完 ibd 数据文件; 2> xtrabackup 在备份 InnoDB 相关数据时,是有2种线程的,1种是 redo 拷贝线程,负责拷贝 redo 文件,1种是 ibd 拷贝线程,负责拷贝 ibd 文件;redo 拷贝线程只有一个,在 ibd 拷贝线程之前启动,在 ibd 线程结束后结束。xtrabackup 进程开始执行后,先启动 redo 拷贝线程,从最新的 checkpoint 点开始顺序拷贝 redo 日志;然后再启动 ibd 数据拷贝线程,在 xtrabackup 拷贝ibd 过程中,innobackupex 进程一直处于等待状态(等待文件被创建)。 3> xtrabackup 拷贝完成idb后,通知 innobackupex(通过创建文件),同时自己进入等待(redo 线程仍然继续拷贝); 4> innobackupex 收到 xtrabackup 通知后,执行FLUSH TABLES WITH READ LOCK (FTWRL),取得一致性位点,然后开始备份非InnoDB 文件(包括 frm、MYD、MYI、CSV、opt、par等)。拷贝非 InnoDB 文件过程中,因为数据库处于全局只读状态,如果在业务的主库备份的话,要特别小心,非 InnoDB 表(主要是MyISAM)比较多的话整库只读时间就会比较长,这个影响一定要评估到。 5> 当 innobackupex 拷贝完所有非 InnoDB 表文件后,通知 xtrabackup(通过删文件) ,同时自己进入等待(等待另一个文件被创建); 6> xtrabackup 收到 innobackupex 备份完非 InnoDB 通知后,就停止 redo 拷贝线程,然后通知 innobackupex redo log 拷贝完成(通过创建文件); 7> innobackupex 收到 redo 备份完成通知后,就开始解锁,执行 UNLOCK TABLES; 8> 最后 innobackupex 和 xtrabackup 进程各自完成收尾工作,如资源的释放、写备份元数据信息等,innobackupex 等待xtrabackup 子进程结束后退出。 在上面描述的文件拷贝,都是备份进程直接通过操作系统读取数据文件的,只在执行 SQL 命令时和数据库有交互,基本不影响数据库的运行,在备份非 InnoDB 时会有一段时间只读(如果没有MyISAM表的话,只读时间在几秒左右),在备份 InnoDB 数据文件时,对数据库完全没有影响,是真正的热备。 InnoDB 和非 InnoDB 文件的备份都是通过拷贝文件来做的,但是实现的方式不同,前者是以page为粒度做的(xtrabackup),后者是cp 或者 tar 命令(innobackupex),xtrabackup 在读取每个page时会校验 checksum 值,保证数据块是一致的,而 innobackupex 在cp MyISAM 文件时已经做了flush(FTWRL),磁盘上的文件也是完整的,所以最终备份集里的数据文件都是写入完整的。
6.3.2 软件安装
6.3.3 创建备份用户
-- minimum privileges required mysql> CREATE USER 'backup'@'localhost' IDENTIFIED BY 'backup'; mysql> GRANT RELOAD, LOCK TABLES, PROCESS, REPLICATION CLIENT ON *.* TO 'backup'@'localhost'; mysql> FLUSH PRIVILEGES; or mysql> CREATE USER 'bkpuser'@'localhost' IDENTIFIED BY 'password'; mysql> GRANT BACKUP_ADMIN, PROCESS, RELOAD, LOCK TABLES, REPLICATION CLIENT ON *.* TO 'bkpuser'@'localhost'; mysql> GRANT SELECT ON performance_schema.log_status TO 'bkpuser'@'localhost'; mysql> FLUSH PRIVILEGES;
6.3.4 示例
# 1. 创建备份目录 mkdir -p /ups/bakup/mybackup chown mysql:mysql /ups/bakup/mybackup # 2. 备份 #-- 全备 [参数--no-timestamp 表示不生成带时间戳的目录] innobackupex --defaults-file=/ups/app/mysql/mysql/my.cnf --no-timestamp --user=backup --password=backup --host=localhost --port=3308 --backup /ups/bakup/mybackup/all_$(date +%Y%m%d) #-- 增备(--incremental-basedir 参数指定全备的目录或上一次增备目录) innobackupex --defaults-file=/ups/app/mysql/mysql/my.cnf --no-timestamp --user=backup --password=backup --host=localhost --port=3308 --incremental /ups/bakup/mybackup/incr_$(date +%Y%m%d) --incremental-basedir=/ups/bakup/mybackup/all_$(date +%Y%m%d) # 3. 恢复 # 使用--apply-log参数先进行合并数据文件,确保数据的一致性 innobackupex --defaults-file=/etc/my.cnf --user=backup --password=backup --host=localhost --port=3309 --apply-log --redo-only /ups/bakup/mybackup/all_$(date +%Y%m%d) # 合并增量数据到全备目录 innobackupex --defaults-file=/etc/my.cnf --user=backup --password=backup --host=localhost --port=3309 --apply-log --redo-only /ups/bakup/mybackup/all_$(date +%Y%m%d) -incremental-dir=/ups/bakup/mybackup/incr_$(date +%Y%m%d)
# 合并最后一次增量数据到全备目录(注意不加—redo-only参数了) innobackupex --defaults-file=/etc/my.cnf --user=backup --password=backup --host=localhost --port=3309 --apply-log /ups/bakup/mybackup/all_$(date +%Y%m%d) -incremental-dir=/ups/bakup/mybackup/incr_$(date +%Y%m%d)
# 把所有合在一起的完全备份整体进行一次apply操作,回滚未提交的数据
innobackupex --defaults-file=/etc/my.cnf --user=backup --password=backup --host=localhost --port=3309 --apply-log /ups/bakup/mybackup/all_$(date +%Y%m%d) # 恢复到指定datadir innobackupex --defaults-file=/etc/my.cnf --user=backup --password=backup --host=localhost --port=3309 --copy-back /ups/bakup/mybackup/all_$(date +%Y%m%d)
# 重要备份文件信息
xtrabackup_checkpoints : 备份类型信息(完全备份或增量备份)、LSN(日志序列号)范围信息、备份是否压缩 xtrabackup_binlog_info : 二进制日志信息,MySQL当前正在使用的二进制日志文件及位置。 xtrabackup_info : xtrabackup工具的版本信息、详细命令、参数以及备份的开始、结束时间,以及备份详细信息等。 xtrabackup_logfile : backup-my.cnf : 备份命令用到的配置选项信息。
# innobackupex选项优化

--ftwrl-wait-timeout=60 # 防止发生阻塞。在FTWRL时,如果有长查询,最多等待60S的时间,如果60秒之内长查询执行完了,就成功执行FTWRL了,如果60秒之内没有执行完,那么就直接报错退出,放弃执行。默认值为0 --rsync # 减少FTWRL时间 缩短备份非事务引擎表的锁定时间 --parallel=4 # 开并行 --use-memory=4G # 使用的内存量,在 --apply-log 阶段使用该选项
4)备份恢复脚本