MySQL-备份与恢复

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
View Code

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
View Code

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),磁盘上的文件也是完整的,所以最终备份集里的数据文件都是写入完整的。

View Code

clipboard


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           : 备份命令用到的配置选项信息。

image

# innobackupex选项优化

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


4)备份恢复脚本


6.4 select into outputfile

image

原文地址:https://www.cnblogs.com/binliubiao/p/12691547.html