MYSQL备份工具——innobackupex程序

MYSQL备份工具——innobackupex程序

官方文档:https://www.percona.com/doc/percona-xtrabackup/LATEST/innobackupex/innobackupex_script.html

innobackupex程序是链接到 xtrabackup 的C程序。它让你在一个特定的时间点对InnoDB|XtraDB表,MyISAM表或其它表类型进行备份。在之前的版本(没写具体哪个版本用的是PERL脚本,写这文档时的版本是2.4)innobackupex是以Perl脚本实现的。

备份流程——全量备份

使用innobackupex创建备份:

$ innobackupex --user=DBUSER --password=DBUSERPASS /path/to/BACKUP-DIR/

检查最后两行的输出:

innobackupex: Backup created in directory '/path/to/BACKUP-DIR/2013-03-25_00-00-09'
innobackupex: MySQL binlog position: filename 'mysql-bin.000003', position 1946
111225 00:00:53  innobackupex: completed OK!

备份将被存到以时间戳命名的目录里。例如:/path/to/BACKUP-DIR/2013-03-25_00-00-09
innobackup实际上是调用xtrabackup去备份innodb所有表的数据并COPY所有表的定义(.frm文件),MyISAM,MERGE(相关其它表)相关的数据和文件,CSV归档表,相关的触发器数据库配置信息到这个时间戳命名的目录。(简单的来说就是所有文件)

准备使用innobackupex进行全量备份:

创建备份后,数据还不能被用来恢复。因为可能还有未提交的事务要被取消(undo)或被日志重放(replay)。这些操作都是为了数据的一致性并且这也是准备阶段的目的。一但这个阶段完毕,数据就可以用来恢复。

innobackupex必须使用–apply-log和完整的备份目录:

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

然后检查输出进程的最后几行:

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

如果innobackupex成功的执行了所有必要的操作,数据可以立即用来恢复。

innobackupex通过读取备份目录中的backup-my.cnf文件开始准备过程。

在这之后innobackupex重放日志中提交的事务(一些事务可能在备份过程中已经备份完了)并且回滚未提交的事务。一旦这一步完成,所有信息都存放在表空间文件中(innoDB文件),并且日志文件被创建。

这步实际调用xtrabackup --prepare两次。

注意准备阶段不适用于增量备份。如果在基于增量备份的过程,使用这一过程,你将不能添加增量。详见:https://www.percona.com/doc/percona-xtrabackup/LATEST/innobackupex/incremental_backups_innobackupex.html

–use-memory选项:准备过程可能通过使用更多的内存的方式来提高速度。它依赖于系统上自由的或可用的RAM,默认是100MB。一般来说更多的可用内存能处理的更好。例如:
$ innobackupex –apply-log –use-memory=4G /path/to/BACKUP-DIR

使用innobackupex恢复一个全量备份

为了方便,innobackupex有一个–copy-back参数,它将备份恢复到服务器的datadir中。

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

它将服务所有的相关数据文件到服务器的datadir中,datadir由服务器的my.cnf决定。输出的最后两行显示成功信息:

innobackupex: Finished copying back files.

111225 01:08:13  innobackupex: completed OK!

注意:

 datadir 目录必须是空的; Percona XtraBackup innobackupex --copy-back 选项不会覆盖已经有文件,除非 innobackupex --force-non-empty-directories 选项被指定,同样要注意一点,这时MYSQL服务需要在恢复前停止。你不能恢复数据到一个正在运行的MYSQL实例的datadir(除非恢复的是一个部分备份)。

文件的属性将会被保留,在大多数时候,在启动数据库服务之前你需要去改变一下恢复文件的所有者为mysql,因为它们的所有者是创建备份的用户:

$ chown -R mysql:mysql /var/lib/mysql

同样要注意,所有的恢复操作都由innobackupex完成,所以你要有服务器datadir的写权限。

其它类型的备份

innobackupex的增量备份功能

因为每次备份并不是所有的数据都要改变,使用增量备份的策略可以减少存储空间和备份时间。

因为InnoDB页的日志序列号——LSN,它可以做为整个数据库的版本号。每次数据库被修改,这个号码都会增长,所以innobackupex通过这个功能来制作增量备份。

增量备份COPY指定LSN以后的所有页。

一旦这些页按照它们的顺序被放到一起,应用日志将会重新创建被影响的数据库的进程,产生最新的备份。

使用innobackupex创建增量备份

(1)需要有一个全量备份做为之后增量备份的基础:

$ innobackupex /data/backups

这将在/data/backups里建立一个时间戳文件夹。假设这个备份的BASEDIR/data/backups/2013-03-31_23-01-18

如果在BASEDIR中检查xtrabackup-checkpoints文件,你将会看到诸如下面的记录:

backup_type = full-backuped
from_lsn = 0
to_lsn = 1626007
last_lsn = 1626007
compact = 0
recover_binlog_info = 1

之后创建增量备份时,使用--incremental选项,并提供BASEDIR

$ innobackupex --incremental /data/backups --incremental-basedir=BASEDIR

之后其它时间戳的文件夹会被创建在/data/backups目录里,如:/data/backups/2013-04-01_23-01-18,它包含了增量备份,我们称它为INCREMENTAL-DIR-1
如果你检查INCREMENTAL-DIR-1目录下的xtrabackup-checkpoints文件,你将会看到类似这样的内容:

backup_type = incremental
from_lsn = 1626007
to_lsn = 4124244
last_lsn = 4124244
compact = 0
recover_binlog_info = 1

接下来创建其它增量备份也是类似的,不过这时之前的增量文件将变成基础,如:

$ innobackupex --incremental /data/backups --incremental-basedir=INCREMENTAL-DIR-1

产生 /data/backups/2013-04-02_23-01-18目录,我们称它为INCREMENTAL-DIR-2

这时INCREMENTAL-DIR-2目录下的xtrabackup-checkpoints文件应该像是这样:

backup_type = incremental
from_lsn = 4124244
to_lsn = 6938371
last_lsn = 7110572
compact = 0
recover_binlog_info = 1

就像之前说的那样,增量备份只COPY大于指定LSN值的页。提供LSN将会在目录中产生相同的数据:

innobackupex --incremental /data/backups --incremental-lsn=4124244
innobackupex --incremental /data/backups --incremental-lsn=6938371

这对于增量备份来说非常有用,因为最后的增量未必一直都有是可用的。

警告

这一过程只对 XtraDBInnoDB-based 的表有用。像 MyISAM引擎的表,每次都是全量COPY。

准备使用innobackup进行增量备份

和全量备份有一点不同。应该更注意两点:

  • 首先,提交的事务必须在每个备份上重放。这将增量备份和基础的全量备份融合。
  • 之后,未提交的事务必须按顺序回滚到一个ready-to-use的备份。

如果你准备在基础备份中提交事务回滚未提交的事务,你将不能添加增量更新。如果你在某一增量更新点上这么做,那么以后就不能在这个更新点上添加增量更新。

在这种思路下,过程中只要直接使用--redo-only选项,在基础备份之上:

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

你将会看到类似的输出:

160103 22:00:12 InnoDB: Shutdown completed; log sequence number 4124244
160103 22:00:12 innobackupex: completed OK!

然后,第一个增量备份能被用于基础备份之上,通过使用:

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

你将会看到类似之前的输出,但有一个相应的LSN:

160103 22:08:43 InnoDB: Shutdown completed; log sequence number 6938371
160103 22:08:43 innobackupex: completed OK!

如果没有设置-incremental-dir目录,innobackupex将会使用basedir中最近的子目录。
这时,BASE-DIR包含的数据截止到第一次增量备份的时候。注意,全量数据一直在基本目录中,我们只是追加了一些增量到它上面。
重复这个步骤添加额外的增量目录:

innobackupex --apply-log BASE-DIR --incremental-dir=INCREMENTAL-DIR-2

如果显示了“completed OK!”信息,那么最终的数据将会在基础备份目录中——BASE-DIR

注意

除了最后一个增量更新之外,其它增量都要使用--redo-only 这个参数。这就是为什么上一行没有包含 --redo-only 选项。 Even if the --redo-only was used on the last step, backup would still be consistent but in that case server would perform the rollback phase.

你可以使用这一步骤添加更多的增量到基本备份中,只要你以时间顺序进行添加就行。如果你融合一个增量以错误的顺序,那么这个备份将会失效(useless)。如果顺序无法确定,但又必须应用,你可以查看每份备份目录中的xtrabackup_checkpoints文件,就像上面写的那样。
一但基本备份融合了所有增量,那么你就能准备去回滚未提交的事务了:

innobackupex --apply-log BASE-DIR

现在你的备份只要恢复它,它就可以立即被使用。这个准备步骤是可选的。但是,如果你恢复了一个没有进行准备步骤的备份,数据库服务器将开始回滚未提交的事务,如果发生崩溃相同的工作也将去做。这个结果将会延迟到数据库服务器启动,而如果你做了准备步骤那么能避免延迟。
注意,iblog*文件不会被innobackupex创建,如果你希望它们被创建,请在目录上使用xtrabackup –prepare。否则,文件会在服务器启动时创建。

使用innobackupex恢复增量备份

在准备增量备份后,基本备份目录包含了一份完整的备份。恢复备份可以使用:

innobackupex --copy-back BASE-DIR

恢复之后你必须改变所有者。

使用xbstream和tar进行增量流备份

增量流备份能使用 xbstream 流选项,当前流备份使用的默认格式是xbstream。使用xbstream做为基础备份是不错的选择(With this feature taking a BASE backup is needed as well.)。

Taking a base backup:

innobackupex /data/backups

Taking a local backup:

innobackupex --incremental --incremental-lsn=LSN-number --stream=xbstream ./ > incremental.xbstream

Unpacking the backup:

xbstream -x < incremental.xbstream

Taking a local backup and streaming it to the remote server and unpacking it:

innobackupex  --incremental --incremental-lsn=LSN-number --stream=xbstream ./ | /
ssh user@hostname " cat - | xbstream -x -C > /backup-dir/"

部分备份

它意味着你可以备份某一特定的表或数据库。你要备份的表必须在单独的表空间才可以,所以你必须修改服务器选项 innodb_file_per_table 之后才能使用该功能。(这个选项默认是开启的,InnoDB表的数据和索引会存在.ibd文件中,表定义存在.frm中。如果关闭这个选项数据都会存在系统表空间中,这会使系统表空间变的非常庞大,而且系统表空间只能增长不能减小。)

这里只有一个关于部分备份的警告:不要向回复制(--copy-back)准备好的备份(prepared backup)。恢复部分备份的数据应该通过导入表,而不是通过传统的--copy-back选项。虽然有一些使用向回复制文件的方案,但是这可能会导致数据库不一致,所以这种向回复制(--copy-back)的方法并不推荐。

创建部分备份

这有三种方法指定要去备份全部数据的哪部分:正则表达式(--include),枚举表文件(--tables-file)或提供数据库列表(--databases)。

使用--include选项

由正则表达式提供的值被完全匹配成表名,其中包含数据库的名字,它的形式是:databasename.tablename

例如:

$ innobackupex --include='^mydatabase[.]mytable' /path/to/backup

上面的命令将创建一个时间戳目录,里面的文件由innobckupex创建,但是只有和表相关的数据文件。
注意:这个选项被传到xtrabackup --tables并且它匹配每个数据库的每个表,即使数据库是空的,每个数据库的文件夹也会被创建。

使用--tables-file选项

提供的文本文件可以包含多个表名,每行一个,格式:databasename.tablename

例:

$ echo "mydatabase.mytable" > /tmp/tables.txt
$ innobackupex --tables-file=/tmp/tables.txt /path/to/backup

上面的命令将会建立一个时间戳文件夹,其中包含的文件是由innobackupex穿件,但是只包含和表相关的数据文件。

这个选项传递到xtrabackup --tables-file,而且和--tables选项不同,只有被选择的表的数据库才会建立目录。

使用–databases选项

这个选项既可以接受空格分隔的数据库和表的清单去备份(格式:databasename[.tablename]),也可以文本文件列表,其每行一个元素。

例如:

$ innobackupex --databases="mydatabase.mytable mysql" /path/to/backup

上面这条命令将会建立一个时间戳文件夹,其中包含的文件由innobackupex创建,但是只在mydatabase目录下包含和mytable相关的数据目录,并且包含完整的mysql数据库目录。

准备部分备份

对于“预部分备份”,这一步骤和restoring individual tables类似:应用日志并使用--export选项:

$ innobackupex --apply-log --export /path/to/partial/backup

你可能在输出看到关于表不存在的警告。这是因为基于InnoDB的引擎的数据是存储在表空间文件中,另外还有.frm文件。innobackupex将使用xtrabackup在数据目录中按顺序移除不存在的表(没有在部分备份中选择的表),这是为了避免将来的警告或错误:

111225  0:54:06  InnoDB: Error: table 'mydatabase/mytablenotincludedinpartialb'
InnoDB: in InnoDB data dictionary has tablespace id 6,
InnoDB: but tablespace with that id or name does not exist. It will be removed from data dictionary.

同时你应该也会看到为了导入(.exp文件)每个被包含在部分备份中的表的创建文件的通知:

xtrabackup: export option is specified.
xtrabackup: export metadata of table 'employees/departments' to file `.//departments.exp` (2 indexes)
xtrabackup:     name=PRIMARY, id.low=80, page=3
xtrabackup:     name=dept_name, id.low=81, page=4

注意你能在一个已经预备份完毕的备份上使用--export选项的同时使用 --apply-log选项,这是为了去创建.exp文件。

最后,检查确认信息的输出:

111225 00:54:18  innobackupex: completed OK!

恢复部分备份

Restoring should be done by restoring individual tables in the partial backup to the server.

It can also be done by copying back the prepared backup to a “clean” datadir (in that case, make sure to include the mysql database). System database can be created with:

$ sudo mysql_install_db --user=mysql

高级功能

恢复单独的表

在服务器版本5.6之前,是不能在服务器之间复制表的,即使开启了 innodb_file_per_table。但是,使用Percona XtraBackup,你能从任何一个InnoDB数据库中导出单独的表,并将它们导入到使用XtraDB的Percona Server或MySQL 5.6(源不一定是XtraDB或MySQL5.6,但目的一定要是)。这只对单独的.ibd文件有用,并且不能导出一个不包含在它所属的.ibd文件的表。

导出表

导出在准备阶段完成,而不是在创建备份的那一瞬间。一旦完整备份创建完成,使用--export选项进行准备:

$ innobackupex --apply-log --export /path/to/backup

这将为每个拥有自己表空间的InnoDB表建立一个.exp文件。这个步骤的输出可能包含如下内容:

..
xtrabackup: export option is specified.
xtrabackup: export metadata of table 'mydatabase/mytable' to file
`./mydatabase/mytable.exp` (1 indexes)
..

现在你将在目标文件夹中看到一个.exp的文件:

$ find /data/backups/mysql/ -name export_test.*
/data/backups/mysql/test/export_test.exp
/data/backups/mysql/test/export_test.ibd
/data/backups/mysql/test/export_test.cfg

这三个文件是你导入到使用XtraDB的Percona Server 或MySQL5.6要用的。

Note

MySQL使用 .cfg 文件它包含了InnoDB 目录的特殊格式。 这种格式不同于 .exp 用于 XtraDB 中的目录格式。 严格来说,.cfg 文件是不需要导入到 MySQL 5.6 或 Percona Server 5.6的表空间中的。 表空间将成功的被导入即使它来自其它服务器,但是如果提供了相应的.cfg 文件在相同的目录里,InnoDB 将会验证schema的有效性。

每个一.exp(或.cfg)文件都会用于导入表。

注意

InnoDB执行了一个slow shutdown (i.e. full purge + change buffer merge) 在 –export上, 否则表空间将会不一致,因此不能被导入。 通常基于性能的考虑需要:充足的 buffer pool (i.e. –use-memory, 100MB by default)和足够快的存储,否则它将会执行非常久的时间才能导出完成。

导入表

在其它服务器上导入表,首先使用相同结构在这台服务器创建一个新表,做为导入使用。

OTHERSERVER|mysql> CREATE TABLE mytable (...) ENGINE=InnoDB;

然后关闭它的表空间:

OTHERSERVER|mysql> ALTER TABLE mydatabase.mytable DISCARD TABLESPACE;

在这之后,复制mytable.ibd mytable.exp ( 如果要导入到MySQL5.6的话还有mytable.cfg文件到数据库的目录里,然后导入这些表空间:

OTHERSERVER|mysql> ALTER TABLE mydatabase.mytable IMPORT TABLESPACE;

一旦执行成功,导入的数据就可以使用了。

发表评论