Mysql 热备份迁移

Xtrabackup 是由 percona 公司 开源 的免费数据库 热备份 软件,它能对 InnoDB数据库和 XtraDB存储引擎的数据库进行 非阻塞 地备份。

众所周知,mysqldump 备份方式是采用的逻辑备份,其最大的缺陷是备份和恢复速度较慢,如果数据库大于50Gmysqldump备份就不太适合。

相比而言,Xtrabackup 的优势体现在:

  • 备份、还原速度快,物理备份可靠
  • 备份过程不会打断正在执行的事务(无需锁表)
  • 能够基于压缩等功能节约磁盘空间和流量
  • 支持流式处理,将备份传输到另外一台机器上
  • 自动备份校验

Xtrabackup 安装完成后有 4 个可执行文件:

  • xtrabackup: 是专门用来备份InnoDB表的,和mysql服务器没有交互;
  • innobackupex: 是一个封装xtrabackup的Perl脚本,支持同时备份innodbmyisam,但在对myisam备份时需要加一个全局的读锁。
  • xbcrypt: 加密解密备份工具
  • xbstream: 流打包传输工具

全备恢复

首先,准备一个数据库全备份

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
root@zhaobi:~# innobackupex --user=*** --password=*** ./mysql.back
encryption: using gcrypt 1.6.5
...
180508 14:32:32 Connecting to MySQL server host: localhost, user: root, password: set, port: not set, socket: not set
Using server version 5.7.20-0ubuntu0.16.04.1
...
180508 14:32:33 >> log scanned up to (146069144514)
xtrabackup: Generating a list of tablespaces
InnoDB: Allocated tablespace ID 455 for parse/mtf_LTC_USDT, old maximum was 0
180508 14:32:33 [01] Copying ./ibdata1 to /root/mysql.back/2018-05-08_14-32-32/ibdata1
...
180508 14:38:27 [01] ...done
180508 14:38:27 Finished backing up non-InnoDB tables and files
180508 14:38:27 Executing FLUSH NO_WRITE_TO_BINLOG ENGINE LOGS...
xtrabackup: The latest check point (for incremental): '146066625808'
xtrabackup: Stopping log copying thread.
.180508 14:38:27 >> log scanned up to (146071684987)

180508 14:38:27 Executing UNLOCK TABLES
180508 14:38:27 All tables unlocked
180508 14:38:27 [00] Copying ib_buffer_pool to /root/mysql.back/2018-05-08_14-32-32/ib_buffer_pool
180508 14:38:27 [00] ...done
180508 14:38:27 Backup created in directory '/root/mysql.back/2018-05-08_14-32-32/'
180508 14:38:27 [00] Writing /root/mysql.back/2018-05-08_14-32-32/backup-my.cnf
180508 14:38:27 [00] ...done
180508 14:38:27 [00] Writing /root/mysql.back/2018-05-08_14-32-32/xtrabackup_info
180508 14:38:27 [00] ...done
xtrabackup: Transaction log of lsn (146061868327) to (146071684987) was copied.
180508 14:38:27 completed OK!

Xtrabackup 备份原理:

备份开始时首先会开启一个后台检测进程,实时检测 mysql redo log的变化,一旦发现有新的日志写入,立刻将日志记入后台日志文件 xtrabackup_log中,之后复制 InnoDB 的数据文件以及系统表空间文件ibdatax,复制结束后,将执行 flush tables with readlock ,然后复制 .frm .MYI .MYD 等文件,最后执行 unlock tables

输出 completed OK! 信息代表备份成功。

看一下备份后的文件列表:

1
2
3
4
5
6
7
8
9
10
11
12
root@zhaobi:~# ls -l mysql.back/2018-05-08_14-32-32/
total 349608
-rw-r----- 1 root root 487 May 8 14:38 backup-my.cnf
-rw-r----- 1 root root 2362 May 8 14:38 ib_buffer_pool
-rw-r----- 1 root root 348127232 May 8 14:32 ibdata1
drwxr-x--- 2 root root 4096 May 8 14:38 mysql
drwxr-x--- 2 root root 4096 May 8 14:38 parse
drwxr-x--- 2 root root 4096 May 8 14:38 performance_schema
drwxr-x--- 2 root root 12288 May 8 14:38 sys
-rw-r----- 1 root root 123 May 8 14:38 xtrabackup_checkpoints
-rw-r----- 1 root root 445 May 8 14:38 xtrabackup_info
-rw-r----- 1 root root 9819136 May 8 14:38 xtrabackup_logfile

然后,将备份好的数据拷贝到目标主机,准备进行恢复:

先关掉目标主机的 mysql 服务,准备一个全备份:

1
$ innobackupex --apply-log /path/to/BACKUP-DIR

准备完成后,检查下最后输出到信息:

1
2
150806 01:01:57  InnoDB: Shutdown completed; log sequence number 1609228
150806 01:01:57 innobackupex: completed OK!

接着进行全备恢复:

1
$ innobackupex --copy-back /path/to/BACKUP-DIR

增量备份

优点:

  • 数据库太大没有足够的空间全量备份,增量备份能有效节省空间,并且效率高;
  • 支持热备份,备份过程不锁表(针对InnoDB而言),不阻塞数据库的读写;
  • 每日备份只产生少量数据,也可采用远程备份,节省本地空间;
  • 备份恢复基于文件操作,降低直接对数据库操作风险;

原理:

  1. 首先完成一个全备份,并记录下此时检查点LSN
  2. 然后增量备份时,比较表空间中每个页的LSN是否大于上次备份的LSN,若是则备份该页并记录当前检查点的LSN

增量备份需要用到两个参数:

  • --incremental 告诉 innobackupex 进行增量备份
  • --incremental-basedir 指定增量备份的起始点,这里是之前备份过的某个目录

在全量备份基础上进行第一次增量备份:

1
2
3
4
5
root@zhaobi:~# innobackupex --user=** --password=*** --incremental --incremental-basedir=./mysql.back/2018-05-08_14-32-32/ ./mysql.inc1
...
180508 15:29:32 [00] ...done
xtrabackup: Transaction log of lsn (146084103197) to (146090143186) was copied.
180508 15:29:32 completed OK!

对比两次备份的 xtrabackup_checkpoints 记录可以看到:

  • backup_type 分别为 full-backupedincremental
  • 增量备份的 from_lsn 对应于上次全量备份的 to_lsn
1
2
3
4
5
6
7
8
9
10
11
12
13
14
root@zhaobi:~# cat mysql.back/2018-05-08_14-32-32/xtrabackup_checkpoints
backup_type = full-backuped
from_lsn = 0
to_lsn = 146066625808
last_lsn = 146071684987
compact = 0
recover_binlog_info = 0
root@zhaobi:~# cat mysql.inc1/2018-05-08_15-24-35/xtrabackup_checkpoints
backup_type = incremental
from_lsn = 146066625808
to_lsn = 146090143177
last_lsn = 146090143186
compact = 0
recover_binlog_info = 0

在第一次增量备份基础上,进行第二次增量备份:

1
2
3
4
5
root@zhaobi:~# innobackupex --user=** --password=*** --incremental --incremental-basedir=./mysql.inc1/2018-05-08_15-24-35/ ./mysql.inc2
...
180508 15:41:50 [00] ...done
xtrabackup: Transaction log of lsn (146090145039) to (146094909487) was copied.
180508 15:41:50 completed OK!

同理,第二次增量备份的 from_lsn 对应于第一次增量备份的 to_lsn

1
2
3
4
5
6
7
root@zhaobi:~# cat mysql.inc2/2018-05-08_15-36-58/xtrabackup_checkpoints
backup_type = incremental
from_lsn = 146090143177
to_lsn = 146090145039
last_lsn = 146094909487
compact = 0
recover_binlog_info = 0

增量恢复

首先,准备一个全备份:

1
innobackupex --apply-log --redo-only BASE-DIR

然后,依次将增量备份 append 到全备份,特别需要注意的是:最后一个增量备份不用 --redo-only

1
2
innobackupex --apply-log --redo-only BASE-DIR --incremental-dir=INCREMENTAL-DIR-1
innobackupex --apply-log BASE-DIR --incremental-dir=INCREMENTAL-DIR-2

确保每次操作最后都打出了日志信息: completed OK!

现在,所有的备份都整合到了 BASE-DIR,对合在一起的完全备份进行一次 apply 操作,回滚未提交的数据:

1
innobackupex --apply-log BASE-DIR

最后,恢复所有备份:

1
innobackupex --copy-back BASE-DIR

总结

这篇文章简单记录并总结了使用 Xtrabackupmysql 数据库进行 全量/增量备份并恢复的过程,希望能对初学者有所帮助。

很抱歉,就做了点微小的贡献。

彦祖老师 wechat