• 运维特工,战胜心魔!!
  • 有些事情其实没有那么难,只是我们感觉难,走出第一步!
  • 你所浪费的今天,是昨天死去的人奢望的明天!!!
  • 欢迎访问 unixfbi.com 运维特工社区http://unixfbi.com/
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏吧
  • 运维特工:http://www.unixfbi.com
  • 人生没有白走的路,每一步都算数!!
  • 空杯心态,沉淀自己!

Percona XtraBackup 备份原理与实践

MySQL unixfbi 2年前 (2018-01-21) 10852次浏览 已收录 0个评论 扫描二维码
文章目录[隐藏]

Percona XtraBackup 备份原理与实践

一、Percona XtraBackup 介绍

1.什么是 Percona XtraBackup

XtraBackup 是由 Percona 公司开发的一款开源的 MySQL 热备工具,支持 Innodb 的在线基于物理 copy 备份,在备份的过程中不会锁住数据库。在 MySQL 备份的工具里面,XtraBackup 是比较常用的一种解决方案。该工具能够备份 InnoDB、XtraDB、MyISAM 表。并且还支持流方式、压缩、加密和增量备份。

Xtrabackup 中主要包含两个工具:
xtrabackup:是用于热备份 innodb, xtradb 表中数据的工具,不能备份其他类型的表,也不能备份数据表结构;

innobackupex:现在 2.4 版本 innobackupex 是 Xtrabackup 的一个软链接,原来的早期版本 innobackupex 是一个 perl 程序。

2.XtraBackup 原理

XtraBackup 是基于 InnoDB 自身的崩溃恢复机制完成备份的,它首先复制所有的 InnoDB 表数据文件副本,这样导致了内部数据的不一致。但是,它后来会执行崩溃恢复功能,是数据达到最终的一致,成为可用的数据库文件。而 innobackupex 会在外围打扫战场,解决除了 InnoDB 表和 redo log 之外的其他资源。

xtrabackup 之所以可以通过复制 InnoDB 表的 ibd 文件工作,是由于 InnoDB 内部维护了一个重做日志(redo log)。这包含了每次 InnoDB 会更改数据的记录。当 Innodb 启动时,它会检查数据文件并重做日志,并执行以下两步操作:应用已经提交的事务(前滚),回滚那些未提交的事务(回滚)。

xtrabackup 在备份的时候,会记录 LSN(log sequence number)位置,然后开始复制数据文件。如果数据库文件被修改了,数据库就会处于不一致的状态。与此同时,xtrabackup 开启一个后台进程,监控 redo log 的变化,并且复制变化的部分。xtrabackup 需要不断的循环该过程,因为 redo log 是循环使用的,可以重用。xtrabackup 需要记录每一次对数据文件操作的 redo log。

这样,从备份开始一直到备份结束,InnoDB 所有的 redo log 都能够备份,如果没有 redo log,那么由于数据是不一致的,后面就无法恢复了。

3.innobackupex 的基本原理

从 Percona XtraBackup version 2.3 innobackup 被用 C 运营重写了,并且将作为 xtrabackup 的一个软链接。iinnobackup 支持所有的特性和语法,像 2.2 版本那样。但是现在是被放弃了,并且将在下一个主版本中移除。新特性的语法将不会被添加到 innobackupex 中,只会被添加到 xtrabackup 的特性中。

  • 备份:

如果没有指定模式,innobackupex 默认将使用 backup 模式运行。
默认以--suspend-at-end 选项启动 xtrackup,让他拷贝 InnoDB 数据文件。当 xtrabackup 完成拷贝后,innobackupex 查看是否创建了 xtrabackup_suspended_2 文件,如果有这个文件,那么就会执行 FLUSH TABLES WITH READ LOCK。xtrabackup 将使用更轻量级的备份锁(Backup locks ) 来替代 FLUSH TABLES WITH READ LOCK 。这个特性在 Percona Server 5.6+可以使用。 Percona XtraBackup 会自动使用备份锁来拷贝 non-innoDB 数据,以避免锁住对 InnoDB tables 修改请求的 DML。然后开始复制剩余的文件。

iinobackupex 将会检查 MySQL 变量,确定哪些特性是被 server 支持的。特别有用的是备份锁,更改的页位图、GTID 模式等等。如果一切没有问题,二进制将作为子进程启动。

如果指定了--safe-slave-backup 选项,innobackupex 将等待 slave 复制设置,并且将用 flush all tables with READ LOCK 刷新所有表,以便阻止 MyISAM 表的写入(除非指定了--no-lock 选项)

锁只针对 MyISAM 和其他非 innoDB 表进行,并且锁定是在 XtraBackup 备份完成所有 InnoDB/XtraDB 数据和日志之后才会锁定。Percona XtraBackup 将使用更轻量级的备份锁(Backup locks ) 来替代 FLUSH TABLES WITH READ LOCK 。这个特性在 Percona Server 5.6+ 可以使用。 Percona XtraBackup 会自动使用备份锁来复制 non-innoDB 数据,以避免锁住对 InnoDB tables 修改请求的 DML。

一旦完成上面的操作,将会开始备份 .frm, .MRG, .MYD, .MYI, .TRG, .TRN, .ARM, .ARZ, .CSM, .CSV, .par, and .opt l 类型的文件.

当所有上述文件备份完成后,innobackupex 脚本将会恢复 xtrabackup 的执行,等待其备份上述逻辑执行过程中生成的事务日志文件。接下来,表被解锁,slave 被启动 (if the option --safe-slave-backup was used) ,到 server 的连接被关闭。接下来,脚本会删掉 xtrabackupsuspended2 文件,允许 xtrabackup 进程退出。

注意:我们大家一定要明白,innobackupex 备份的数据是 FLUSH TABLES WITH READ LOCK 之前的数据,FTWRL 之后的数据是不会备份的。因为执行 FTWRL 后整个数据库处于只读状态,不能写入数据了。如果你在 FTWRL 之后写入数据只会被卡在这里,假如你这时执行了 5 条 insert 语句,此时卡住不响应了,只有 innobackupex 执行了 UNLOCK TABLES 命令后,这 5 条 insert 语句才会被执行。

  • 恢复:
    为了恢复一个备份,innobackupex 必须使用--copy-backup 参数。
    innobackupex 将从 my.cnf 文件中获取 datadir, innodb_data_home_dir, innodb_data_file_path, innodb_log_group_home_dir 变量,并且会检查这些目录是否存在。

然后开始复制 MyISAM 表、索引文件 (.frm, .MRG, .MYD, .MYI, .TRG, .TRN, .ARM, .ARZ, .CSM, .CSV, par and .opt files) 等。
然后再接着复制 InnoDB 表、索引文件。
最后复制日志文件。

这些文件在复制的时候,将会保留文件属性,所以在启动 database server 之前,需要修改这些文件的所有权。

在恢复过程中,也可以使用--move-backup 选项,该选项与--copy-backup 的区别是,该选项是将备份文件移动到目标位置,而不是复制,即会删除备份文件,所以使用时一定要小心。不建议使用该选项。一般是在磁盘空间不足以同时保存数据文件和备份文件时,才使用该选项。

4.innobackupex 备份流程分析

Percona  XtraBackup 备份原理与实践
在上面描述的文件拷贝,都是备份进程直接通过操作系统读取数据文件的,只在执行 SQL 命令时和数据库有交互,基本不影响数据库的运行,在备份非 InnoDB 时会有一段时间只读(如果没有 MyISAM 表的话,只读时间在几秒左右),在备份 InnoDB 数据文件时,对数据库完全没有影响,是真正的热备。

InnoDB 和非 InnoDB 文件的备份都是通过拷贝文件来做的,但是实现的方式不同,前者是以 page 为粒度做的(xtrabackup),后者是 cp 或者 tar 命令(innobackupex),xtrabackup 在读取每个 page 时会校验 checksum 值,保证数据块是一致的,而 innobackupex 在 cp MyISAM 文件时已经做了 flush(FTWRL),磁盘上的文件也是完整的,所以最终备份集里的数据文件都是写入完整的。

查看备份时生成的 general_log 日志:

2018-01-16T04:06:25.254934Z        26 Query     FLUSH NO_WRITE_TO_BINLOG TABLES
2018-01-16T04:06:25.255211Z        26 Query     FLUSH TABLES WITH READ LOCK
2018-01-16T04:06:34.220053Z        26 Query     SHOW MASTER STATUS
2018-01-16T04:06:34.220179Z        26 Query     SHOW VARIABLES
2018-01-16T04:06:34.278326Z        26 Query     FLUSH NO_WRITE_TO_BINLOG ENGINE LOGS
2018-01-16T04:06:34.544758Z        26 Query     UNLOCK TABLES
2018-01-16T04:06:34.644768Z        26 Query     SELECT UUID()
2018-01-16T04:06:34.644873Z        26 Query     SELECT VERSION()
2018-01-16T04:06:34.887686Z        26 Quit

general_log 中的输出重点语句,如下:

FLUSH NO_WRITE_TO_BINLOG TABLES、FLUSH TABLES WITH READ LOCK、SHOW MASTER STATUS、UNLOCK TABLES 几个语句的作用与 mysqldump 备份过程中的这几个语句的作用一样

FLUSH NO_WRITE_TO_BINLOG ENGINE LOGS,在 mysqldump 备份过程中没有该语句。

这句的作用是在所有的事务表和非事务表备份完成,获取了全局读锁,且使用 SHOW MASTER STATUS 语句获取了 binlog pos 之后,执行刷新 redo log buffer 中的日志到磁盘中,然后 redo log copy 线程拷贝这最后的 redo log 日志数据(为什么说是最后的 redo log 日志数据呢?因为此时使用 FLUSH TABLES WITH READ LOCK 加锁之后,使用 UNLOCK TABLES 释放全局读锁之前,不会再有新的请求进来,),拷贝完成之后就停止 copy 线程并关闭 xtrabackup_logfile 文件。然后再使用 UNLOCK TABLES 释放全局读锁。

5.Percona XtraBackup 优点

  • 无须停止数据库进行 InnoDB 热备份。
  • 增量备份 MySQL
  • 留压缩传输到其他服务器。
  • 在线移动表。
  • 能够相当方便的创建主从同步。
  • 备份 MySQL 时不会增大服务器负载。

6.XtraBackup 常用参数

  • -u, --user=name:备份时连接数据的用户名称。
  • -H, --host=name:指定数据库的 IP 地址或者主机名(如果主机名可以解析的话)
  • -P, --port=#:连接数据库的端口号。
  • -p, --password=name:连接数据库用户的密码。
  • -S, --socket=name:该选项接受一个字符串参数,可以指定使用 UNIX 套接字的方式连接到本地数据库。
  • --apply-log:通过应用 BACKUP_DIR 目录中的 xtrabackup_logfile 的事务日志,在 BACKUP_DIR 目录中准备备份,并且创建新的事务日志。innobackupex --apply-log 默认使用 BACKUP_DIR 目录 backup-my.cnf 中的 InnoDB 配置,如果指定了--defaults-file 选项,那么就使用它指定的配置文件。
  • --copy-back:将准备好的备份文件从备份目录复制到原始位置,其原始位置目录必须为空,否则报错(除非指定--force-non-empty-directories 选项)。
  • --move-back:将之前备份的所有文件从备份目录移动到原始目录。此选项恢复后将删除备份文件,请大家慎重使用。
  • --stream=name:该选项接受指定流备份执行格式的字符串参数,备份将以指定的格式完成 STDOUT。对备份文件进行打包。支持格式有 tar 和 xbstream。如果在该选项后指定路径,则该路径被解释为 tmpdir 的值。
  • --tables-file=name
  • -t, --tmpdir=name:该选项接受一个指定临时文件位置的字符串参数。它可以与--stream 选项一起使用。使用该选项,事务日志首先会存储到临时文件中,然后流式传输或者复制到远程主机。如果未指定该选项,则默认值为使用 my.cnf 配置读取的 tmpdir 值。
  • --use-memory=#:该选项指定 xtrabackup 在 prepare 阶段进行崩溃恢复的内存使用量,以字节为单位,支持的单位如 1MB、1M、1GB、1G。仅仅可以和--apply-log 选项一起使用。
  • --defaults-file=#:指定从该配置文件中读取 MySQL 的配置选项。如果使用该选项必须作为命令行的第一个选项。
  • --no-timestamp :使用该选项在备份的根目录不会创建以时间命名的目录。
  • --slave-info:该选项用于在从库上的备份。它会打印二进制日志的位置和主库的名称,还会将此信息以“CHANGE MASTER”命令的形式写入到 xtrabackup_slave_info 文件中,可以通过此备份启动从实例。
  • --safe-slave-backup:这个选项是要和--slave-info 结合使用的。发起备份时,会暂停 SLAVE 的 SQL Thread,确保备份时没有临时表打开,保证数据的一致性。备份结束后,SQL 线程会自动启动。如果 Slave_open_temp_tables 在--safe-slave-backup-timeout 秒后未变成零,则备份失败。
  • --safe-slave-backup-timeout=seconds:该选项指定--safe-slave-backup 应等待多长时间,以使 Slave_open_temp_tables 变为零。默认时间为 300 秒。

7.xtrabackup 备份生成的文件说明

  • backup-my.cnf: 该文件包含了备份所需要的 my.cnf 中的选项。例如:
    innodb_data_file_path,
    innodb_log_files_in_group,
    innodb_log_file_size,
    innodb_fast_checksum,
    innodb_page_size,
    innodb_log_block_size,
    innodb_undo_directory,
    innodb_undo_tablespaces,
    server_id
    等选项。在恢复数据的过程中,innobackupex 会依赖该文件中的选项.

  • xtrabackup_info: 该文件中包含了 uuid,命令的名称版本和使用过的参数信息。数据库版本,备份开始时间和结束时间,锁了多长时间。binlog 文件和位置点以及 LSN 信息。

  • xtrabackup_binlog_info: 该文件作用非常大。该文件中记录了备份数据库时的二进制文件和位置信息。这是备份后数据库的为位置。当利用备份来搭建从库时,该二进制信息可以直接 CHANGE MASTER TO 中使用。通过该文件知道了备份时数据库的位置,可以与 Binlog 结合使用,恢复到任何位置。

文件内容:

mysql-bin.000002        16014   b5a3240c-8946-11e7-bf07-d067e528dfb8:1-69
  • xtrabackup_checkpoints:该文件记录备份的类型(full-backuped、incremental)、备份状态及备份的 LSN 信息,增量备份依赖于该信息。
  • xtrabackup_binlog_pos_innodb:当执行--apply-log 时,会创建该文件。该文件记录了 InnoDB 表或 XtraDB 表的二进制文件和位置信息。
  • xtrabackup_logfile:该文件记录--apply-log 操作时所需要的数据(ib_logfile0)。如果--apply-log 操作时间很长,该文件就会很大。
  • xtrabackup_slave_info:在从库上备份时指定了--slave-info 选项,那么就会产生该文件,该文件记录了在建立主从关系时 CHANGE MASTER 语句所需要的信息。
    例如该文件内容为:
    MySQL 5.7 版本
# cat xtrabackup_slave_info 
SET GLOBAL gtid_purged='b5a3240c-8946-11e7-bf07-d067e528dfb8:1-69';
CHANGE MASTER TO MASTER_AUTO_POSITION=1;

二、Percona XtraBackup 实践

1.安装 Percona XtraBackup

现在最新版本是 2.4.9,我们也安装此版本
下载:

# wget https://www.percona.com/downloads/XtraBackup/Percona-XtraBackup-2.4.9/binary/redhat/7/x86_64/percona-xtrabackup-24-2.4.9-1.el7.x86_64.rpm

安装:

# yum localinstall percona-xtrabackup-24-2.4.9-1.el7.x86_64.rpm 

安装后查看创建了什么文件:

# rpm -ql percona-xtrabackup-24
/usr/bin/innobackupex
/usr/bin/xbcloud
/usr/bin/xbcloud_osenv
/usr/bin/xbcrypt
/usr/bin/xbstream
/usr/bin/xtrabackup
/usr/share/doc/percona-xtrabackup-24-2.4.9
/usr/share/doc/percona-xtrabackup-24-2.4.9/COPYING
/usr/share/man/man1/innobackupex.1.gz
/usr/share/man/man1/xbcrypt.1.gz
/usr/share/man/man1/xbstream.1.gz
/usr/share/man/man1/xtrabackup.1.gz

2.全量备份与恢复

2.1.备份阶段

在备份时,一般需要指定连接数据库的参数和备份目录即可,但是我们平时需要使用一些其他参数。

# innobackupex  --defaults-file=/etc/my.cnf --user=root --password=unixfbi --host=127.0.0.1  /data/backup/

备份的数据会放到以时间命名的文件夹中,例如:/data/backup/2018-01-16_16-44-50
如果不生成以时间命名的文件夹,使用--no-timestamp 参数即可。

备份完成后,innobackupex 会输出以下信息:

180116 16:45:05 Backup created in directory '/data/backup/2018-01-16_16-44-50/'
MySQL binlog position: filename 'mysql-bin.000004', position '614', GTID of the last change 'b5a3240c-8946-11e7-bf07-d067e528dfb8:1-17'
180116 16:45:05 [00] Writing /data/backup/2018-01-16_16-44-50/backup-my.cnf
180116 16:45:05 [00]        ...done
180116 16:45:05 [00] Writing /data/backup/2018-01-16_16-44-50/xtrabackup_info
180116 16:45:05 [00]        ...done
xtrabackup: Transaction log of lsn (2173186534) to (2173186543) was copied.
180116 16:45:05 completed OK!
  • 打包和压缩备份数据
# innobackupex  --defaults-file=/etc/my.cnf --user=root --password=xxx  --host=127.0.0.1  --stream=tar /tmp |gzip -> /data/backup/xtra_fullbackup.tar.gz

--stream=tar 指定标准输出的格式,也是对备份文件进行打包。如果在该选项后指定路径,则该路径被解释为 tmpdir 的值。

gzip 是对数据文件进行压缩。

2.2.Prepare 阶段

在创建备份后,备份数据其实处于不可用状态。因为在 redo log 中可能存在未提交的事务和已经提交的事务,需要通过准备阶段来使备份数据达到一致的状态。通过此阶段,备份数据就可以用来恢复了。
在备份阶段,需要指定选项 --apply-log和备份路径。

# innobackupex    --apply-log   /path/BACKUP_DIR/2017-11-29_21-02-54

输出信息如下:

InnoDB: Shutdown completed; log sequence number 2173187112
180116 17:14:45 completed OK!

如果状态为"completed OK!" ,表示 innobackupex 执行完成了所有需要的操作,数据也达到了一致状态。

2.3.恢复阶段

在 Prepare 阶段后,用备份数据来恢复数据库,只需要指定--copy-backup 和备份数据所在的目录即可。

# innobackupex  --copy-back  /path/BACKUP_DIR/2017-11-29_21-02-54

innobackupex 会读取 my.cnf 配置文件,并把所有的数据相关文件复制到配置文件中配置的 datadir 目录中。
复制完成后,在启动 MySQL 数据库之前,需要修改文件的所有权。
例如:

# chown -R mysql.mysql /datadir/

在恢复的过程中,datadir 目录必须为空。如果不为空,innobackupex --copy-back 将会失败,除非指定了--force-non-empty-directories 选项;
在恢复过程中,数据库必须是关闭状态。

3.增量备份与恢复

因为增量备份,恢复操作相对较多。恢复过程相对较慢,需要基于全量备份或者增量备份来恢复。
如果最原始的全量备份或者上一个增量备份出现问题,那么该增量备份就会出现问题。
所以我平时不使用增量备份。

4.加密备份

可以本地发起备份操作,备份数据到远程机器上。但是不能远端发起备份请求,备份数据到远端机器上。必须和 mysql server 安装到同一台机器上。

首先产生一个随机密码:

# openssl rand -base64 24
M3QcCnA5KJkUOghE6X4FQaTPx60rog61

4.1.加密备份

# innobackupex --defaults-file=/etc/my.cnf  -uroot -punixfbi --encrypt=AES256 --encrypt-key="M3QcCnA5KJkUOghE6X4FQaTPx60rog61" /path/BACKUP_DIR/

查看加密后的文件:
发现文件后缀都是以.xbcrypt 结尾,被加密了。

# ll
总用量 102604
-rw-r-----. 1 root root       524 1 月  17 06:47 backup-my.cnf.xbcrypt
drwxr-x---. 2 root root      4096 1 月  17 06:47 db1
drwxr-x---. 2 root root      4096 1 月  17 06:47 db2
-rw-r-----. 1 root root       905 1 月  17 06:47 ib_buffer_pool.xbcrypt
-rw-r-----. 1 root root 105004800 1 月  17 06:46 ibdata1.xbcrypt
drwxr-x---. 2 root root      4096 1 月  17 06:46 mysql
drwxr-x---. 2 root root      8192 1 月  17 06:46 performance_schema
drwxr-x---. 2 root root      8192 1 月  17 06:47 sys
-rw-r-----. 1 root root       155 1 月  17 06:47 xtrabackup_binlog_info.xbcrypt
-rw-r-----. 1 root root       211 1 月  17 06:47 xtrabackup_checkpoints.xbcrypt
-rw-r-----. 1 root root       686 1 月  17 06:47 xtrabackup_info.xbcrypt
-rw-r-----. 1 root root      2744 1 月  17 06:47 xtrabackup_logfile.xbcrypt

4.2.解密备份文件

# innobackupex --decrypt=AES256 --encrypt-key="M3QcCnA5KJkUOghE6X4FQaTPx60rog61"  --remove-original /path/BACKUP_DIR

这样就把加密后的文件进行解密了。

5.备份到远端机器

首先我们需要配置好免密钥登录远端机器。而且目标目录也要存在并且登录用户有权限写入。

  • 无压缩备份:
# innobackupex --defaults-file=/etc/my.cnf  -uroot -pxxx --stream=tar /tmp  | ssh user@unixfbi-node1 " cat -> /data/backup/db.tar"
  • 压缩备份:
# innobackupex --defaults-file=/etc/my.cnf  -uroot -pxxxx --stream=tar /tmp | gzip |ssh user@unixfbi-node1 "cat -> /data/backup/db.tar.gz"

查看备份文件:
发现文件压缩前和压缩后的占用磁盘空间区别还是挺大的。

# ll -h
总用量 116M
-rw-rw-r-- 1 root root 114M 1 月  16 18:25 db.tar
-rw-rw-r-- 1 root root 2.5M 1 月  17 06:34 db.tar.gz

参考文档

http://mysql.taobao.org/monthly/2016/03/07/
https://www.percona.com/doc/percona-xtrabackup/LATEST/index.html
https://www.percona.com/doc/percona-xtrabackup/2.4/innobackupex/how_innobackupex_works.html
http://blog.csdn.net/lijingkuan/article/details/72803531
https://www.cnblogs.com/yuyue2014/p/3705448.html
http://chuansong.me/n/372118651979
http://blog.csdn.net/woqutechteam/article/details/75289255

本文出自 “运维特工” 博客,转载请务必保留原文链接 和 http://www.unixfbi.com


UnixFBI 运维特工 , 版权所有丨如未注明 , 均为原创丨 转载请务必注明原文链接http://www.unixfbi.com/349.html
喜欢 (7)
[支付宝]
分享 (0)
unixfbi
关于作者:
运维工程师一枚,做有价值的事情!
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址