一、完全备份

Xtrabackup是由percona提供的mysql数据库备份工具,据官方介绍,这也是世界上惟一一款开源的能够对innodb和xtradb数据库进行热备的工具。特点:

(1)备份过程快速、可靠;

(2)备份过程不会打断正在执行的事务;

(3)能够基于压缩等功能节约磁盘空间和流量;

(4)自动实现备份检验;

(5)还原速度快;

1、完全备份

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

如果要使用一个最小权限的用户进行备份,则可基于如下命令创建此类用户:

CREATE USER ’bkpuser’@’localhost’ IDENTIFIED BY ’s3cret’;

REVOKE ALL PRIVILEGES, GRANT OPTION FROM ’bkpuser’;

GRANT RELOAD, LOCK TABLES, REPLICATION CLIENT ON *.* TO ’bkpuser’@’localhost’;

FLUSH PRIVILEGES;

使用innobakupex备份时,其会调用xtrabackup备份所有的InnoDB表,复制所有关于表结构定义的相关文件(.frm)、以及MyISAM、MERGE、CSV和ARCHIVE表的相关文件,同时还会备份触发器和数据库配置信息相关的文件。

这些文件会被保存至一个以时间命令的目录中。可以使用--no-timestamp选项来阻止命令自动创建一个以时间命名的目录;如此一来,innobackupex命令将会创建一个BACKUP-DIR目录来存储备份数据。

在备份的同时,innobackupex还会在备份目录中创建如下文件:

(1)xtrabackup_checkpoints 备份类型(如完全或增量)、备份状态(如是否已经为prepared状态)和LSN(日志序列号)范围信息;

每个InnoDB页(通常为16k大小)都会包含一个日志序列号,即LSN。LSN是整个数据库系统的系统版本号,

每个页面相关的LSN能够表明此页面最近是如何发生改变的。

(2)xtrabackup_binlog_infomysql服务器当前正在使用的二进制日志文件及至备份这一刻为止二进制日志事件的位置。

(3)xtrabackup_binlog_pos_innodb二进制日志文件及用于InnoDB或XtraDB表的二进制日志文件的当前position。

(4)xtrabackup_binary备份中用到的xtrabackup的可执行文件;

(5)backup-my.cnf 备份命令用到的配置选项信息;

2、准备(prepare)一个完全备份

一般情况下,在备份完成后,数据尚且不能用于恢复操作,因为备份的数据中可能会包含尚未提交的事务或已经提交但尚未同步至数据文件中的事务。

因此,此时数据文件仍处理不一致状态。“准备”的主要作用正是通过回滚未提交的事务及同步已经提交的事务至数据文件也使得数据文件处于一致性状态。

innobakupex命令的--apply-log选项可用于实现上述功能。如下面的命令:

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

在实现“准备”的过程中,innobackupex通常还可以使用--use-memory选项来指定其可以使用的内存的大小,默认通常为100M。如果有足够的内存可用,可以多划分一些内存给prepare的过程,以提高其完成速度。

3、从一个完全备份中恢复数据 

注意:恢复不用启动MySQL

innobackupex命令的--copy-back选项用于执行恢复操作,其通过复制所有数据相关的文件至mysql服务器DATADIR目录中来执行恢复过程。innobackupex通过backup-my.cnf来获取DATADIR目录的相关信息。

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

当数据恢复至DATADIR目录以后,还需要确保所有数据文件的属主和属组均为正确的用户,如mysql,否则,在启动mysqld之前还需要事先修改数据文件的属主和属组。如:

chown -R  mysql:mysql  /mydata/data/

完整的备份还原过程

准备过程

yum -y install https://www.percona.com/downloads/XtraBackup/Percona-XtraBackup-2.4.12/binary/redhat/6/x86_64/percona-xtrabackup-24-2.4.12-1.el6.x86_64.rpm

service mysqld stop

vim /etc/my.cnf

log-bin=/mydata/binlog/master-bin

innodb_file_per_table = 1

service mysqld start

mysql

SHOW BINARY LOGS;

sed -i 's/MyISAM/InnoDB/' hellodb.sql

mysql -uroot -p < hellodb.sql 

mysql

SHOW TABLE STATUS FROM hellodb; 

use hellodb;

CREATE TABLE t1 (Name char(20));

完全备份

innobackupex --user=root /mydata/backups/

scp -r /mydata/backups/2018-11-16_06-40-14/ root@192.168.130.64:/mydata/backups

新机器准备完全备份

innobackupex --apply-log /mydata/backups/2018-11-16_06-40-14/

新机器恢复

service mysqld stop

rm -rf /mydata/data/*

innobackupex --copy-back /mydata/backups/2018-11-16_06-40-14/

chown -R mysql.mysql /mydata/data/

service mysqld start

mysql

use hellodb;

show tables;

二、使用innobackupex进行增量备份

每个InnoDB的页面都会包含一个LSN信息,每当相关的数据发生改变,相关的页面的LSN就会自动增长。这正是InnoDB表可以进行增量备份的基础,即innobackupex通过备份上次完全备份之后发生改变的页面来实现。

要实现第一次增量备份,可以使用下面的命令进行:

innobackupex --incremental /backup --incremental-basedir=BASEDIR

其中,BASEDIR指的是完全备份所在的目录,此命令执行结束后,innobackupex命令会在/backup目录中创建一个新的以时间命名的目录以存放所有的增量备份数据。

另外,在执行过增量备份之后再一次进行增量备份时,其--incremental-basedir应该指向上一次的增量备份所在的目录。

需要注意的是,增量备份仅能应用于InnoDB或XtraDB表,对于MyISAM表而言,执行增量备份时其实进行的是完全备份。

“准备”(prepare)增量备份与整理完全备份有着一些不同,尤其要注意的是:

(1)需要在每个备份(包括完全和各个增量备份)上,将已经提交的事务进行“重放”。“重放”之后,所有的备份数据将合并到完全备份上。

(2)基于所有的备份将未提交的事务进行“回滚”。

于是,操作就变成了:

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

接着执行:

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

而后是第二个增量:

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

其中BASE-DIR指的是完全备份所在的目录,而INCREMENTAL-DIR-1指的是第一次增量备份的目录,INCREMENTAL-DIR-2指的是第二次增量备份的目录,其它依次类推,即如果有多次增量备份,每一次都要执行如上操作;

准备过程

yum -y install https://www.percona.com/downloads/XtraBackup/Percona-XtraBackup-2.4.12/binary/redhat/6/x86_64/percona-xtrabackup-24-2.4.12-1.el6.x86_64.rpm

service mysqld stop

vim /etc/my.cnf

log-bin=/mydata/binlog/master-bin

innodb_file_per_table = 1

service mysqld start

sed -i 's/MyISAM/InnoDB/' hellodb.sql

mysql

SET SESSION sql_log_bin=0;

SOURCE /root/hellodb.sql

SET SESSION sql_log_bin=1;

SHOW TABLE STATUS FROM hellodb; 

use hellodb;

CREATE TABLE t1 (Name char(20));

SHOW BINARY LOGS;

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

| Log_name       | File_size |

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

| log-bin.000001 |       126 |

| log-bin.000002 |       126 |

| log-bin.000003 |       204 |

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

3 rows in set (0.00 sec)

完全备份

innobackupex --user=root /mydata/backups/

ls /mydata/backups/               

2018-11-16_04-38-46

新增数据

mysql

USE hellodb;

INSERT INTO t1 VALUES (1),(2),(3);

SHOW BINARY LOGS;      

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

| Log_name       | File_size |

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

| log-bin.000001 |       126 |

| log-bin.000002 |       126 |

| log-bin.000003 |       401 |

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

3 rows in set (0.00 sec)

第一次增量备份

innobackupex --incremental /mydata/backups/ --incremental-basedir=/mydata/backups/2018-11-16_04-38-46

ls /mydata/backups/

2018-11-16_04-38-46  2018-11-16_04-40-04

新增数据

mysql

USE hellodb;

INSERT INTO t1 VALUES (4),(5),(6);

 SHOW BINARY LOGS;   

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

| Log_name       | File_size |

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

| log-bin.000001 |       126 |

| log-bin.000002 |       126 |

| log-bin.000003 |       598 |

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

3 rows in set (0.00 sec)

第二次增量备份

ls /mydata/backups/

2018-11-16_07-11-31  2018-11-16_07-38-45

innobackupex --incremental /mydata/backups/ --incremental-basedir=/mydata/backups/2018-11-16_04-40-04

ls /mydata/backups/

2018-11-16_04-38-46  2018-11-16_04-40-04  2018-11-16_04-41-47

新增数据

mysql

USE hellodb;

INSERT INTO t1 VALUES (7),(8),(9);

mysqlbinlog --start-position=598 /mydata/binlog/log-bin.000003 > /mydata/backups/binlog.pos

scp -r /mydata/backups/2018-11-16_04-* root@192.168.130.65:/mydata/backups

新机器准备完全备份

增量备份

innobackupex --user=root /mybackups

use hellodb;

create table t1 (id init);

insert into t1 values(1),(2);

innodbackupex --incremental  /mybacckups --incremental-basedir=/mybackups/完全备份

create database mydb;

use mydb;

create table test 1(Name Char(10));

innodbackupex --incremental  /mybacckups --incremental-basedir=/mybackups/第一次增量

use hellodb;

insert into t1 values (3),(4);

模拟数据库损坏

service mysqld stop

cd /mydata/data

rm -rf ./*

新机器准备完全备份

innobackupex --apply-log --redo-only /mydata/backups/2018-11-16_04-38-46/

innobackupex --apply-log --redo-only /mydata/backups/2018-11-16_04-38-46/ --incremental-dir=/mydata/backups/2018-11-16_04-40-04/

innobackupex --apply-log --redo-only /mydata/backups/2018-11-16_04-38-46/ --incremental-dir=/mydata/backups/2018-11-16_04-41-47/

新机器恢复

service mysqld stop

rm -rf /mydata/data/*

innobackupex --copy-back /mydata/backups/2018-11-16_04-38-46/

chown -R mysql.mysql /mydata/data

service mysqld start

mysql

use hellodb;

mysql> select * from t1;

+------+

| Name |

+------+

| 1    |

| 2    |

| 3    |

| 4    |

| 5    |

| 6    |

+------+

6 rows in set (0.01 sec)

SET SESSION sql_log_bin=0;

SOURCE /mydata/backups/binlog.pos

SET SESSION sql_log_bin=1;

mysql> select * from t1;

+------+

| Name |

+------+

| 1    |

| 2    |

| 3    |

| 4    |

| 5    |

| 6    |

| 7    |

| 8    |

| 9    |

+------+

9 rows in set (0.00 sec) 

 

三、Xtrabackup的“流”及“备份压缩”功能

Xtrabackup对备份的数据文件支持“流”功能,即可以将备份的数据通过STDOUT传输给tar程序进行归档,而不是默认的直接保存至某备份目录中。要使用此功能,仅需要使用--stream选项即可。如:

innobackupex --stream=tar  /backup | gzip > /backup/`date +%F_%H-%M-%S`.tar.gz

例如: 

innobackupex --stream=tar /mydata/backups/2018-11-16_04-38-46/ | gzip > /mydata/backups/`date +%F_%H_%M-%S`.tar.gz

甚至也可以使用类似如下命令将数据备份至其它服务器:

innobackupex --stream=tar  /backup | ssh user@www.magedu.com  "cat -  > /backups/`date +%F_%H-%M-%S`.tar" 

例如:

innobackupex --stream=tar /mydata/backups/2018-11-16_04-38-46/ | ssh root@192.168.130.65 "cat - > /mydata/backups/`date +%F_%H-%M-%S`.tar"

此外,在执行本地备份时,还可以使用--parallel选项对多个文件进行并行复制。此选项用于指定在复制时启动的线程数目。

当然,在实际进行备份时要利用此功能的便利性,也需要启用innodb_file_per_table选项或共享的表空间通过innodb_data_file_path选项存储在多个ibdata文件中。

对某一数据库的多个文件的复制无法利用到此功能。其简单使用方法如下:

innobackupex --parallel  /path/to/backup

同时,innobackupex备份的数据文件也可以存储至远程主机,这可以使用--remote-host选项来实现:

innobackupex --remote-host=root@www.magedu.com  /path/IN/REMOTE/HOST/to/backup

四、导入或导出单张表

默认情况下,InnoDB表不能通过直接复制表文件的方式在mysql服务器之间进行移植,即便使用了innodb_file_per_table选项。

而使用Xtrabackup工具可以实现此种功能,不过,此时需要“导出”表的mysql服务器启用了innodb_file_per_table选项

(严格来说,是要“导出”的表在其创建之前,mysql服务器就启用了innodb_file_per_table选项),并且“导入”表的服务器同时启用了innodb_file_per_table和innodb_expand_import选项。

(1)“导出”表

导出表是在备份的prepare阶段进行的,因此,一旦完全备份完成,就可以在prepare过程中通过--export选项将某表导出了:

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

此命令会为每个innodb表的表空间创建一个以.exp结尾的文件,这些以.exp结尾的文件则可以用于导入至其它服务器。

(2)“导入”表

要在mysql服务器上导入来自于其它服务器的某innodb表,需要先在当前服务器上创建一个跟原表表结构一致的表,而后才能实现将表导入:

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

然后将此表的表空间删除:

mysql> ALTER TABLE mydatabase.mytable  DISCARD TABLESPACE;

接下来,将来自于“导出”表的服务器的mytable表的mytable.ibd和mytable.exp文件复制到当前服务器的数据目录,然后使用如下命令将其“导入”:

mysql> ALTER TABLE mydatabase.mytable  IMPORT TABLESPACE;

准备工作

yum -y install https://www.percona.com/downloads/XtraBackup/Percona-XtraBackup-2.4.12/binary/redhat/6/x86_64/percona-xtrabackup-24-2.4.12-1.el6.x86_64.rpm

service mysqld stop

vim /etc/my.cnf

log-bin=/mydata/binlog/master-bin

innodb_file_per_table = 1

service mysqld start

sed -i 's/MyISAM/InnoDB/' hellodb.sql

mysql

SHOW GLOBAL VARIABLES LIKE 'innodb_file_per_table';

SET SESSION sql_log_bin=0;

SOURCE /root/hellodb.sql

SET SESSION sql_log_bin=1;

SHOW TABLE STATUS FROM hellodb; 

导入单张表

innobackupex --uesr=root /mydata/backups/

innobackupex --apply-log --export /mydata/backups/2018-05-30_08-22-18/

USE hellodb;

SHOW CREATE TABLE students;(复制表的创建命令)

scp students.exp students.ibd root@192.168.130.65:/mydata/backups 

新机器上创建新表

CREATE DATABASE mydb;

USE mydb;

使用SHOW CREATE TABLE students;显示的命令创建新表students;

SHOW GLOBAL VARIABLES LIKE 'innodb_file_per_table';

DESC students;

SELECT * FROM students;

新机器上导入单张表

ALTER TABLE students DISCARD TABLESPACE;

cd /mydata/backups/

chown -R mysql.mysql students.*

cp /mydata/backups/2018-05-30_08-22-18/hellodb/students.ibd /mydata/data/mydb/

cp /mydata/backups/2018-05-30_08-22-18/hellodb/students.exp /mydata/data/mydb/

mysql

USE mydb;

ALTER TABLE students IMPORT TABLESPACE;