使用 xtrabackup 进行MySQL数据库物理备份

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用 xtrabackup 进行MySQL数据库物理备份相关的知识,希望对你有一定的参考价值。

0. xtrabackup的功能

能实现的功能:

非阻塞备份innodb等事务引擎数据库、

备份myisam表会阻塞(需要锁)、

支持全备、增量备份、压缩备份、

快速增量备份(xtradb,原理类似于oracle:tracking 上次备份之后发生修改的page.)、

percona支持归档redo log的备份、

percona5.6+支持轻量级的backup-lock替代原来重量级的FTWRL,此时即使备份非事务引擎表也不会阻塞innodb的DML语句了、

支持加密备份、流备份(备份到远程机器)、并行本地备份、并行压缩、并行加密、并行应用备份期间产生的redo日志、并行copy-back

支持部分备份,只备份某个库,某个表

支持部分恢复

支持备份单个表分区

支持备份速度限制,指备份产生的IO速度的限制

支持point-in-time恢复

支持compat备份,也即使不备份索引数据,索引在prepare时--rebuild-indexs

支持备份buffer pool

支持单表export, import到其它库

支持 rsync 来缩短备份非事务引擎表的锁定时间

1. 物理备份需要的权限

使用innobackupex/xtrabackup进行备份,必须先配置好权限。需要的权限分为两部分:

1>系统层面的权限: 执行 innobackupex/xtrabackup 命令的Linux用户需要对mysql datadir和保存备份的目录有读写执行的权限,当然需要对这些命令要有执行权限;

2>mysqld层面的权限:innobackupex/xtrabackup --user=bkpuser 该用户bkpuser是指mysql.user表中的用户,不是系统层面的用户;需要一些基本的权限来执行备份过程:

最基本的权限:

create user ‘bkpuser‘@‘localhost‘ identified by ‘xxx‘;

grant reload,lock tables,replication client on *.* to ‘bkpuser‘@‘localhost‘;

这些权限仅仅只能完成:全备,增量备份,恢复;

一般如果需要部分备份,export表,import表,还需要:grant create tablespace on *.* to ‘bkpuser‘@‘localhost‘;

如果还需要对备份的过程中对锁进行一些优化,防止发生阻塞所有DML的情况,则还需要:

grant process,super on *.* to ‘bkpuser‘@‘localhost‘;

([email protected])[(none)]mysql>show grants for ‘bkpuser‘@‘localhost‘\G*************************** 1. row ***************************Grants for [email protected]: GRANT RELOAD, PROCESS, SUPER, LOCK TABLES, REPLICATION CLIENT, CREATE TABLESPACE ON *.* TO ‘bkpuser‘@‘localhost‘ IDENTIFIED BY PASSWORD ‘*BDC62F68AF8F0B8BFAE27FF782C5D8CE9F4BAFCB‘1 row in set (0.00 sec)

2. innobackupex 命令选项:

3. 使用 innobackupex 备份

3.1 全备

(这里系统层面使用的root用户备份,msyql层面使用的是bkpuser用户,root需要对datadir /var/lib/mysql, 备份目录/backup/xtrabackup/full有读写执行权限;bkpuser也需在mysql中有相关权限)

[[email protected] ~]# innobackupex  /backup/xtrabackup/full --user=bkpuser --password=digdeep

3.2 恢复

1> 第一步prepare(两次prepare,第一次应用备份期间产生的redo log,进行前滚和回滚:replay在redo log中已经提交的事务,rollback没有提交的事务)

注意这里的路径,必须要包括最后那个timestamp目录,不然会下面的错误:


[[email protected] ~]# innobackupex --apply-log /backup/xtrabackup/full/ --user=bkpuser --password=digdeep151106 10:41:48 innobackupex: Starting the apply-log operation

IMPORTANT: Please check that the apply-log run completes successfully.
           At the end of a successful apply-log run innobackupex
           prints "completed OK!".innobackupex version 2.3.2 based on MySQL server 5.6.24 Linux (i686) (revision id: 306a2e0)
xtrabackup: cd to /backup/xtrabackup/full
xtrabackup: Error: cannot open ./xtrabackup_checkpoints
xtrabackup: error: xtrabackup_read_metadata()
xtrabackup: This target seems not to have correct metadata...2015-11-06 10:41:48 b771e6d0  InnoDB: Operating system error number 2 in a file operation.InnoDB: The error means the system cannot find the path specified.xtrabackup: Warning: cannot open ./xtrabackup_logfile. will try to find.2015-11-06 10:41:48 b771e6d0  InnoDB: Operating system error number 2 in a file operation.InnoDB: The error means the system cannot find the path specified.
  xtrabackup: Fatal error: cannot find ./xtrabackup_logfile.xtrabackup: Error: xtrabackup_init_temp_log() failed.


--apply-log会调用 xtrabackup --prepare两次,第一次前滚和回滚,第二次生成iblogfile[0|1]

[[email protected] ~]# innobackupex --apply-log /backup/xtrabackup/full/2015-11-05_22-38-55--user=bkpuser --password=digdeep 

3.3 恢复 --copy-back

直接将上面prepare好的所有文件,复制到mysqld的datadir目录(会读取my.cnf中的配置信息)。

--copy--back的注意事项:

1> datadir必须是空的,或者使用--force-non-empty-directories选项;

2> mysqld必须关闭,如果是--import部分恢复,则不能关闭;

3> --copy-back完成之后,需要修改datadir目录下的文件权限: chown -R mysql:mysql /var/lib/mysql


[[email protected] ~]# mysqladmin -uroot -pxxx shutdown (关闭mysqld)

[[email protected] ~]# cd /var/lib/mysql

[[email protected] mysql]# ls

aazj         ib_logfile1         mysql-bin.000003  mysql-bin.000008  mysql-bin.000013  performance_schema

auto.cnf     localhost-slow.log  mysql-bin.000004  mysql-bin.000009  mysql-bin.000014  t

general.log  mysql               mysql-bin.000005  mysql-bin.000010  mysql-bin.000015  xtrabackup_binlog_pos_innodb

ibdata1      mysql-bin.000001    mysql-bin.000006  mysql-bin.000011  mysql-bin.000016  xtrabackup_info

ib_logfile0  mysql-bin.000002    mysql-bin.000007  mysql-bin.000012  mysql-bin.index

[[email protected] mysql]# mv * /backup/xtrabackup/  (进行清空)

[[email protected] mysql]# ls

[[email protected] mysql]# innobackupex --copy-back /backup/xtrabackup/full/2015-11-05_22-38-55--user=bkpuser --password=digdeep 

[[email protected] mysql]# innobackupex --copy-back /backup/xtrabackup/full/2015-11-05_22-38-55/ --user=bkpuser --password=digdeep 151106 11:07:38 innobackupex: Starting the copy-back operation

IMPORTANT: Please check that the copy-back run completes successfully.
           At the end of a successful copy-back run innobackupex
           prints "completed OK!".innobackupex version 2.3.2 based on MySQL server 5.6.24 Linux (i686) (revision id: 306a2e0)151106 11:07:38 [01] Copying ib_logfile0 to /var/lib/mysql/ib_logfile0151106 11:07:40 [01]        ...done151106 11:07:40 [01] Copying ib_logfile1 to /var/lib/mysql/ib_logfile1151106 11:07:41 [01]        ...done151106 11:07:41 [01] Copying ibdata1 to /var/lib/mysql/ibdata1151106 11:07:45 [01]        ...done151106 11:07:45 [01] Copying ./xtrabackup_info to /var/lib/mysql/xtrabackup_info151106 11:07:45 [01]        ...done151106 11:07:45 [01] Copying ./mysql/slave_master_info.ibd to /var/lib/mysql/mysql/slave_master_info.ibd151106 11:07:45 [01]        ...done
[... ...]151106 11:07:57 [01] Copying ./t/db.opt to /var/lib/mysql/t/db.opt151106 11:07:57 [01]        ...done151106 11:07:57 [01] Copying ./t/t.frm to /var/lib/mysql/t/t.frm151106 11:07:57 [01]        ...done151106 11:07:57 completed OK![[email protected] mysql]# pwd/var/lib/mysql
[[email protected] mysql]# lsaazj  ibdata1  ib_logfile0  ib_logfile1  mysql  performance_schema  t  xtrabackup_binlog_pos_innodb  xtrabackup_info


可以看到恢复之后,没有 binlog 文件盒index文件

启动myqld之前需要修改权限:


[[email protected] mysql]# ls -ltotal 176164drwx------ 2 root  root      4096 Nov  6 11:07 aazj-rw-rw---- 1 mysql mysql      543 Nov  6 11:13 general.log-rw-r----- 1 root  root  79691776 Nov  6 11:07 ibdata1-rw-r----- 1 root  root  50331648 Nov  6 11:07 ib_logfile0-rw-r----- 1 root  root  50331648 Nov  6 11:07 ib_logfile1-rw-rw---- 1 mysql mysql      543 Nov  6 11:13 localhost-slow.logdrwx------ 2 root  root      4096 Nov  6 11:07 mysql-rw-rw---- 1 mysql mysql        0 Nov  6 11:12 mysql-bin.indexdrwx------ 2 root  root      4096 Nov  6 11:07 performance_schema
drwx------ 2 root  root      4096 Nov  6 11:07 t-rw-r----- 1 root  root        24 Nov  6 11:07 xtrabackup_binlog_pos_innodb-rw-r----- 1 root  root       487 Nov  6 11:07 xtrabackup_info
[[email protected] mysql]# chown -R mysql:mysql arb/mysql[[email protected] mysql]# ls -ltotal 176164drwx------ 2 mysql mysql     4096 Nov  6 11:07 aazj-rw-rw---- 1 mysql mysql      543 Nov  6 11:13 general.log-rw-r----- 1 mysql mysql 79691776 Nov  6 11:07 ibdata1-rw-r----- 1 mysql mysql 50331648 Nov  6 11:07 ib_logfile0-rw-r----- 1 mysql mysql 50331648 Nov  6 11:07 ib_logfile1-rw-rw---- 1 mysql mysql      543 Nov  6 11:13 localhost-slow.logdrwx------ 2 mysql mysql     4096 Nov  6 11:07 mysql-rw-rw---- 1 mysql mysql        0 Nov  6 11:12 mysql-bin.indexdrwx------ 2 mysql mysql     4096 Nov  6 11:07 performance_schema
drwx------ 2 mysql mysql     4096 Nov  6 11:07 t-rw-r----- 1 mysql mysql       24 Nov  6 11:07 xtrabackup_binlog_pos_innodb-rw-r----- 1 mysql mysql      487 Nov  6 11:07 xtrabackup_info


不然启动会在error.log中报错:

2015-11-06 11:13:55 3542 [ERROR] InnoDB: ./ibdata1 can‘t be opened in read-write mode

2015-11-06 11:13:55 3542 [ERROR] InnoDB: The system tablespace must be writable!

2015-11-06 11:13:55 3542 [ERROR] Plugin ‘InnoDB‘ init function returned error.

2015-11-06 11:13:55 3542 [ERROR] Plugin ‘InnoDB‘ registration as a STORAGE ENGINE failed.

2015-11-06 11:13:55 3542 [ERROR] Unknown/unsupported storage engine: InnoDB

2015-11-06 11:13:55 3542 [ERROR] Aborting

 

启动成功之后,datadir目录下各种文件都产生了:

[[email protected] mysql]# pwd

/var/lib/mysql

[[email protected] mysql]# ls

aazj      general.log  ib_logfile0  localhost-slow.log  mysql-bin.000001  performance_schema  xtrabackup_binlog_pos_innodb

auto.cnf  ibdata1      ib_logfile1  mysql               mysql-bin.index   t                   xtrabackup_info


3.4 innobackupex 增量备份

增量备份之前,必须建立一个全备,第一次增量备份是在全备的基础之上,第二次增量备份是在第一次增量备份的基础之上的,一次类推

全备:

[[email protected] mysql]# innobackupex --user=bkpuser --password=digdeep /backup/xtrabackup/full


第二次增量备份:

[[email protected] mysql]# innobackupex --incremental /backup/xtrabackup/incr2 --incremental-basedir=/backup/xtrabackup/incr1/2015-11-06_11-33-16/ --user=bkpuser --password=digdeep

3.5 innobackupex 增量备份的恢复

1> 应用全备的redo log:

[[email protected] ~]# innobackupex --apply-log --redo-only /backup/xtrabackup/full/2015-11-06_11-29-51/ --user=bkpuser --password=digdeep

2> 应用第一次增量备份的redo log:

[[email protected] ~]# innobackupex --apply-log --redo-only /backup/xtrabackup/full/2015-11-06_11-29-51/ --incremental-dir=/backup/xtrabackup/incr1/2015-11-06_11-33-16/ --user=bkpuser --password=digdeep

3> 应用第二次(最后一次)增量备份的redo log,并且回滚进行崩溃恢复过程(没有--redo-only选项):

[[email protected] ~]# innobackupex --apply-log /backup/xtrabackup/full/2015-11-06_11-29-51/ --incremental-dir=/backup/xtrabackup/incr2/2015-1  1-06_11-43-22/ --user=bkpuser --password=digdeep


[[email protected] ~]#

然后 --copy-back:

先关闭mysqld: mysqladmin -uroot -pxxx shutdown

[[email protected] mysql]# innobackupex --copy-back /backup/xtrabackup/full/2015-11-06_11-29-51/ --user=bkpuser --password=digdeep


修改权限:

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

启动:mysqld_safe --user=mysql &

最后验证还原成功。

4. 部分备份

需要启用 innodb_file_per_table,5.6默认启用。另外在还原时,prepare之后,并不能直接 --copy-back,而只能一个表一个表的import来还原。

[[email protected] xtrabackup]# innobackupex --databases t /backup/xtrabackup/ --user=bkpuser --password=digdeep


数据库 t 中只有两个表:city, t 都被备份了。

下面我们来看如何还原:

4.1 部分prepare:

[[email protected] xtrabackup]# innobackupex --apply-log --export /backup/xtrabackup/2015-11-06_15-39-34/ --user=bkpuser --password=digdeep

4.2 下面我们将其 import 到一个新的数据库中:

([email protected])[t]mysql>create database partial;

([email protected])[t]mysql>use partial;

Database changed

([email protected])[partial]mysql>create table city like t.city;

([email protected])[partial]mysql>alter table partial.city discard tablespace;

然后将 city.exp 和 city.ibd 拷贝到 /var/lib/mysql/partial/ 目录下,并修改权限:

[[email protected] t]# cp city.exp city.ibd /var/lib/mysql/partial/

[[email protected] partial]# chown -R mysql:mysql /var/lib/mysql

然后 

([email protected])[aazj]mysql>alter table partial.city import tablespace;

Query OK, 0 rows affected, 1 warning (0.11 sec)

 

([email protected])[aazj]mysql>select count(*) from partial.city;

+----------+

| count(*) |

+----------+

|     3285 |

+----------+

1 row in set (0.01 sec)

 

可以看到import 成功了。部分恢复成功。

低于t表也同样操作就行了。

([email protected])[partial]mysql>select count(*) from t;

+----------+

| count(*) |

+----------+

|       11 |

+----------+

1 row in set (0.00 sec)

 

可以看到,这种部分备份/恢复,操作起来比较麻烦,步骤比较多,还需要一个表一个表的处理。对少数表处理还可以,如果很多表,就不方面了。

4.3 部分备份恢复之备份/恢复一个或者多个数据库:

1)备份:

[[email protected] mysql]# innobackupex --database="aazj t mysql information_schema performance_schema"/backup/xtrabackup/partial/ --user=pkpuser --password=digdeep

注意这里 --database = "aazj t mysql performance_schema" 表示指定备份的数据库;还可以增加其他数据库,但是必须使用引号。

2)恢复 prepare:

[[email protected] partial]# innobackupex --apply-log /backup/xtrabackup/partial/2015-11-11_15-22-56 --user=bkpuser --password=digdeep

然后 关闭 mysqld, 清空 datadir :

[[email protected] mysql]# pwd
/var/lib/mysql

[[email protected] mysql]# rm -rf *

3)copy-back:

[[email protected] partial]# innobackupex --copy-back /backup/xtrabackup/partial/2015-11-11_15-22-56 --user=bkpuser --password=digdeep

然后修改权限:chown -R mysql:mysql /var/lib/mysql

然后启动mysqld,发现数据库 t 被恢复出来了。这里也可以一次备份多个数据库,但是一定要带上 mysql 数据库,不然恢复出来时,没有了数据字典,select读不出数据:

Restoring Partial Backups:

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 (摘自xtrabackup文档)

部分恢复一般需要 export, 然后 import. 比较麻烦,但是我们也可以在一个空的 datadir 目录直接 --copy-back,这样的话,那么在备份的时候一定要带上mysql数据库,当然最好带上所有的系统数据库,不然的话,需要使用命令:mysql_install_db --user=mysql --basedir=... 重建那些系统数据库。这就是为什么在部分备份时带上了:mysql performance_schema(information_schema是系统视图,不需要带上,当然带上也是可以的)

4)如果你不想带上 performance_schema(mysql是一定要带上的),那么就必须使用: mysql_install_db --user=mysql --basedir=/usr/local/mysql 来重新生成系统数据库mysql 和 performance_schema。那么此时在 --copy-back之前,必须先删除刚才生成的 和 我们要 --copy-back 重复的文件:

[[email protected] mysql]# rm ibdata1 ib_logfile0 ib_logfile1

[[email protected] mysql]# rm -rf mysql

另外 --copy-back 时要带上参数: --force-non-empty-directories

innobackupex --copy-back --force-non-empty-directories /backup/xtrabackup/partial/2015-11-11_16-17-11/ --user=pkpuser --password=digdeep

因为 datadir 目录非空,所以需要带上该参数:

 --force-non-empty-directories
                      This option, when specified, makes --copy-back or
                      --move-back transfer files to non-empty directories. Note
                      that no existing files will be overwritten. If
                      --copy-back or --nove-back has to copy a file from the
                      backup directory which already exists in the destination
                      directory, it will still fail with an error.
即使带上了该参数,如果还存在重名的文件,还是会报错,需要先删除datadir中的重名文件。

 

5. point-in-time 恢复

利用全备、增量备份最多只能恢复到全备完成时的那一刻,或者增量备份完成时的那一刻的数据。备份之后产生的数据,我们需要结合binlog,来恢复。我们可以从binlog中获得innobackupex最后一次备份完成时的position,它之后的所有的sql,应用完,这些sql,就能将数据库恢复到最新的状态,或者我们想要的某个时间的状态。

1> 先来一个全备:

[[email protected] xtrabackup]# innobackupex /backup/xtrabackup/full --user=bkpuser --password=digdeep

2> 再来一个增量:

将t表数据删除一行:delete from t where i=11;

[[email protected] xtrabackup]# innobackupex --incremental /backup/xtrabackup/incr1/ --incremental-basedir=/backup/xtrabackup/full/2015-11-06_16-26-08 --user=bkpuser --password=digdeep

3> 再来一个增量:

将t表数据删除一行:delete from t where i=10;

[[email protected] xtrabackup]# innobackupex --incremental /backup/xtrabackup/incr2/ --incremental-basedir=/backup/xtrabackup/incr1/2015-11-06_16-31-13/ --user=bkpuser --password=digdeep

4> 备份完成之后,我们再来操作 t 表:

([email protected])[t]mysql>delete from t where i>3;

此时的状态:

([email protected])[t]mysql>show binary logs;

+------------------+-----------+

| Log_name         | File_size |

+------------------+-----------+

| mysql-bin.000001 |       927 |

| mysql-bin.000002 |       688 |

+------------------+-----------+

2 rows in set (0.00 sec)

 

([email protected])[t]mysql>show master status;

+------------------+----------+--------------+------------------+-------------------+

 | File                       | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |

+------------------+----------+--------------+------------------+-------------------+

| mysql-bin.000002 |      688 |              |                  |                   |

+------------------+----------+--------------+------------------+-------------------+

1 row in set (0.00 sec)

 

假设此时数据库表数据所在的磁盘发生故障,但是 binlog 文件是好的。那么此时,我们就可以使用上面的全备、增量备份、还有binlog文件一起来将数据库恢复到磁盘发生故障那一刻的最新状态来。

5> 首先从全备、增量备份得到最后一次备份完成时的数据:

1)应用全备的redo log:

[[email protected] xtrabackup]# innobackupex --apply-log --redo-only /backup/xtrabackup/full/2015-11-06_16-26-08 --user=bkpuser --password=digdeep

2)应用第一次增量备份的redo log:

[[email protected] xtrabackup]# innobackupex --apply-log --redo-only /backup/xtrabackup/full/2015-11-06_16-26-08 --incremental-dir=/backup/xtr  abackup/incr1/2015-11-06_16-31-13/ --user=bkpuser --password=digdeep


3)应用第二次增量备份的 redo log,并且仅限回滚(去掉 --redo-only选项):

[[email protected] xtrabackup]# innobackupex --apply-log /backup/xtrabackup/full/2015-11-06_16-26-08 --incremental-dir=/backup/xtrabackup/incr2/2015-11-06_16-33-57/ --user=bkpuser --password=digdeep

此时已经恢复到了最后一次备份完成时的状态了。

我们看一下最后一次增量备份时的 xtrabackup_binlog_info 文件信息:

[[email protected] xtrabackup]# cat incr2/2015-11-06_16-33-57/xtrabackup_binlog_info

mysql-bin.000002        482

可以看到对应的binlog postion为:mysql-bin.000002        482

而崩溃那一刻的binlog postion为: mysql-bin.000002      688

 

所以我们需要应用 mysql-bin.000002 文件的 482 到 688之间的sql:

4)先 --copy-back

[[email protected] mysql]# innobackupex --copy-back /backup/xtrabackup/full/2015-11-06_16-26-08 --user=bkpuser --password=digdeep

修改权限:

[[email protected] ~]# chown -R mysql:mysql /var/lib/mysql

启动msyqld:  mysqld_safe --user=mysql &

然后验证,t 表的数据,应该有i<10 & i>3 的数据:

([email protected])[t]mysql>select * from t;

+------+

| i    |

+------+

|    1 |

|    2 |

|    3 |

|    4 |

|    5 |

|    6 |

|    7 |

|    8 |

|    9 |

+------+

9 rows in set (0.00 sec)

如我们所期待的结果一样。说明到此时,前面的操作完全是正确的。

5)应用 mysql-bin.000002 文件的 482 到 688之间的sql

[[email protected] mysql]#  mysqlbinlog /backup/xtrabackup/mysql-bin.000002 --start-position=482 > bin.sql

([email protected])[(none)]mysql>source /var/lib/mysql/bin.sql

然后在查看 t 表数据:

([email protected])[t]mysql>select * from t;

+------+

| i    |

+------+

|    1 |

|    2 |

|    3 |

+------+

3 rows in set (0.00 sec)

一切完美完成,数据库被我们回复到了最新的状态。



备份原理:

1)innobackupex 是perl写的脚本,它调用xtrabackup来备份innodb数据库。而xtrabackup是C语言写的程序,它调用了innodb的函数库和mysql客户端的函数库。innodb函数库提供了向数据文件应用的redo log的功能,而mysql客户端函数库提供了解析命令行参数的功能。innobackupex备份innodb数据库的功能,都是通过调用 xtrabackup --backup和xtrabackup --prepare来完成的。我们没有必要直接使用xtrabackup来备份,通过innobackupex更方便。xtrabakup 通过跳转到datadir目录,然后通过两个线程来完成备份过程:

1> log-copy thread: 备份开始时,该后台线程一直监控redo log(每秒check一次redo log),将redo log的修改复制到备份之后的文件 xtrabackup_logfile 中。如果redo log生成极快时,有可能log-copy线程跟不上redo log的产生速度,那么在redo log文件切换进行覆盖时,xtrabakcup会报错。

2> data-file-copy thread: 前后有一个复制data file的线程,注意这里并不是简单的复制,而是调用了innodb函数库,像innodb数据库那样打开数据文件,进行读取,然后每次复制一个page,然后对page进行验证,如果验证错误,会最多重复十次。

当数据文件复制完成时,xtrabackup 停止log-copy 线程,并建立一个文件 xtrabackup_checkpoints记录备份的类型,开始时的lsn和结束时的lsn等信息。

而备份生成的 xtrabackup_binlog_info 文件则含义备份完成时对应的binlog的position信息,类似于:mysql-bin.000002        120

 

在备份开始时记录下LSN,然后一个线程复制数据文件,一个线程监控redo log,复制在备份过程中新产生的redo log。虽然我们的到的数据文件显然不是一致性的,但是利用innodb的crash-recovery功能,应用备份过程中产生的redo log文件,就能得到备份完成时那一刻对应的一致性的数据。

 

注意复制数据文件分成了两个过程:

一个是复制innodb事务引擎的数据文件,是不需要持有锁的;另一个是复制非事务引擎的数据文件和table的定义文件.frm,复制这些文件时,是需要先通过FTWRL,然后在进行复制的,所以会导致整个数据库被阻塞。

增量备份时,是通过对表进行全扫描,比较LSN,如果该page的LSN大于上一次别分时的LSN,那么就将该page复制到table_name.ibd.delta文件中。回复时.delta会和redo log应用到全备是的数据文件中。

增量备份在恢复时,除了最后一次增量备份文件之外,其它的增量备份在应用时,只能前滚,不能执行回滚操作,因为没有提交的事务,可能在下一个增量备份中进行了提交,如果你在上一个增量备份时回滚了,那么下一个增量备份应用时,显然就报错了,因为他无法提交事务,该事务以及被回滚了。



 总结:

1)权限

备份需要两个层面的权限,Linux层面的权限,mysql层面的权限。

2)全备和恢复

全备:innobackupex  /backup/xtrabackup/full --user=bkpuser --password=digdeep

应用日志进行prepare: innobackupex --apply-log /backup/xtrabackup/full/2015-11-05_22-38-55/ --user=bkpuser --password=digdeep 

关闭mysqld:

copy-back: innobackupex --copy-back /backup/xtrabackup/full/2015-11-05_22-38-55/ --user=bkpuser --password=digdeep 

修改权限:chown -R mysql:mysql /var/lib/mysql

3)增量备份和恢复:

全备:

innobackupex --user=bkpuser --password=digdeep /backup/xtrabackup/full

第一次增量备份:

innobackupex --incremental /backup/xtrabackup/incr1/ --incremental-basedir=/backup/xtrabackup/full/2015-11-06_11-29-51/ 

--user=bkpuser --password=digdeep 

第二次增量备份:

innobackupex --incremental /backup/xtrabackup/incr2 --incremental-basedir=/backup/xtrabackup/incr1/2015-11-06_11-33-16/ 

--user=bkpuser --password=digdeep

恢复:

应用全备redo log:

innobackupex --apply-log --redo-only /backup/xtrabackup/full/2015-11-06_11-29-51/ --user=bkpuser --password=digdeep

应用第一次增量备份的redo log:

innobackupex --apply-log --redo-only /backup/xtrabackup/full/2015-11-06_11-29-51/ --incremental-dir=/backup/xtrabackup/incr1/2015-11-06_11-33-16/ 

--user=bkpuser --password=digdeep

应用第二次(最后一次)增量备份的redo log:

innobackupex --apply-log /backup/xtrabackup/full/2015-11-06_11-29-51/ --incremental-dir=/backup/xtrabackup/incr2/2015-11-06_11-43-22/ 

--user=bkpuser --password=digdeep

关闭mysqld,

innobackupex --copy-back /backup/xtrabackup/full/2015-11-06_11-29-51/ --user=bkpuser --password=digdeep

4)部分备份 

innobackupex --databases t /backup/xtrabackup/ --user=bkpuser --password=digdeep

innobackupex --apply-log --export /backup/xtrabackup/2015-11-06_15-39-34/ --user=bkpuser --password=digdeep

新建表结构:create table city like t.city;

alter table partial.city discard tablespace;

然后将 city.exp 和 city.ibd 拷贝到 /var/lib/mysql/partial/ 目录下,并修改权限:chown -R mysql:mysql /var/lib/mysql

alter table partial.city import tablespace;

5)point-in-time 恢复

在--copy-back之后,引用binlog文件

mysqlbinlog /backup/xtrabackup/mysql-bin.000002 --start-position=482 > bin.sql

([email protected])[(none)]mysql>source bin.sql

6) innobackupex 选项优化/最佳实践

--ftwrl-wait-timeout=60 防止发生阻塞

--rsync 减少FTWRL时间 缩短备份非事务引擎表的锁定时间

--parallel=4  开并行

--use-memory=4G crash recovery 期间使用的内存



以上是关于使用 xtrabackup 进行MySQL数据库物理备份的主要内容,如果未能解决你的问题,请参考以下文章

MySQL学习笔记之八:使用Xtrabackup进行MySQL热备

MySQL 採用Xtrabackup对数据库进行全库备份

使用xtrabackup进行MySQL数据库备份

使用Xtrabackup进行MySQL备份

使用Xtrabackup进行MySQL备份

xtrabackup进行MySQL数据库备份/还原