Xtrabackup是由percona提供的mysql数据库备份工具,据官方介绍,这也是世界上唯一一款开源的可以对innodb和xtradb数据库进行热备的工具。特色:mysql
(1)备份过程快速、可靠;sql
(2)备份过程不会打断正在执行的事务;数据库
(3)可以基于压缩等功能节约磁盘空间和流量;vim
(4)自动实现备份检验;centos
(5)还原速度快;bash
官方介绍和下载地址:https://www.percona.com/software/percona-xtrabackup服务器
官方有系统rpm包版的软件,能够下载rpm包版的软件直接安装,因为xtrabackup是使用perl脚本编写的因此须要安装perl-DBD-MySQL不然会报依赖。app
[root@MariaDB~]# yum -y install perl-DBD-MySQL [root@MariaDB~]# rpm -ivh percona-xtrabackup-2.2.3-4982.el6.x86_64.rpm
innobackupex: 客户端工具, 以mysql协议连入mysqld,不支持离线备份,可是支持离线恢复ide
使用innobakupex备份时,其会调用xtrabackup备份全部的InnoDB表,复制全部关于表结构定义的相关文件(.frm)、以及MyISAM、MERGE、CSV和ARCHIVE表的相关文件,同时还会备份触发器和数据库配置信息相关的文件。这些文件会被保存至一个以时间命令的目录中。工具
在使用innobackupex进行备份时,还可使用--no-timestamp选项来阻止命令自动建立一个以时间命名的目录;如此一来,innobackupex命令将会建立一个BACKUP-DIR目录来存储备份数据。
示例:
[root@MariaDB~]# innobackupex --user=root --password=centos /backup/ [root@MariaDB~]# ll /backup/ total4 drwxr-xr-x2 root root 4096 Jun 16 02:28 2015-06-16_02-28-54
备份时报了一个错
innobackupex:Error: The xtrabackup child process has died at /usr/bin/innobackupex line2672.
解决方法:修改innodb日志文件大小为5M,修改完成重启服务生效
[root@MariaDB~]# vim /etc/my.cnf innodb_log_file_size= 5M
备份完成以后在/backup目录下就有了以下内容
[root@MariaDB ~]# ll /backup/2015-06-15_23-49-43/ total 18468 -rw-r--r-- 1 root root 356 Jun 15 23:49 backup-my.cnf drwxr-xr-x 2 root root 4096 Jun 15 23:49 hellodb -rw-r----- 1 root root 18874368 Jun 15 23:49ibdata1 drwxr-xr-x 2 root root 4096 Jun 15 23:49 mysql drwxr-xr-x 2 root root 4096 Jun 15 23:49 performance_schema drwxr-xr-x 2 root root 4096 Jun 15 23:49 test -rw-r--r-- 1 root root 23 Jun 15 23:49 xtrabackup_binlog_info -rw-r----- 1 root root 89 Jun 15 23:49 xtrabackup_checkpoints -rw-r--r-- 1 root root 559 Jun 15 23:49 xtrabackup_info -rw-r----- 1 root root 2560 Jun 15 23:49 xtrabackup_logfile
文件说明:
(1)xtrabackup_checkpoints—— 备份类型(如彻底或增量)、备份状态(如是否已经为prepared状态)和LSN(日志序列号)范围信息;
每一个InnoDB页(一般为16k大小)都会包含一个日志序列号,即LSN。LSN是整个数据库系统的系统版本号,每一个页面相关的LSN可以代表此页面最近是如何发生改变的。
[root@MariaDB 2015-06-15_23-49-43]# catxtrabackup_checkpoints backup_type = full-backuped #备份类型,full-backuped表示彻底备份 from_lsn = 0 #日志序列开始 to_lsn = 1597945 #最大日志序列号 last_lsn = 1597945 #当前日志序列号 compact = 0 #表示没有打包
(2)xtrabackup_binlog_info —— mysql服务器当前正在使用的二进制日志文件及至备份这一刻为止二进制日志事件的位置。
[root@MariaDB 2015-06-15_23-49-43]# catxtrabackup_binlog_info mysql-bin.000005 245
(3)backup-my.cnf —— 备份命令用到的配置选项信息和备份无关的不会记录,备份配置文件的话须要单独备份
[root@MariaDB 2015-06-15_23-49-43]# catbackup-my.cnf # This MySQL options file was generated byinnobackupex. # The MySQL server [mysqld] innodb_checksum_algorithm=innodb innodb_log_checksum_algorithm=innodb innodb_data_file_path=ibdata1:10M:autoextend innodb_log_files_in_group=2 innodb_log_file_size=5242880 innodb_fast_checksum=0 innodb_page_size=16384 innodb_log_block_size=512 innodb_undo_tablespaces=0
(4)xtrabackup_info —— 记录了mariadb的版本信息和一些属性信息,还原是检测版本匹配度时用到
[root@MariaDB 2015-06-15_23-49-43]# catxtrabackup_info uuid = 25b79086-1376-11e5-980a-000c29bad792 name = tool_name = innobackupex tool_command = --user=root --password=... /backup/ tool_version = 1.5.1-xtrabackup ibbackup_version = xtrabackup version 2.2.3 basedon MySQL server 5.6.17 Linux (x86_64) (revision id: ) server_version = 5.5.43-MariaDB-log start_time = 2015-06-15 23:49:43 end_time = 2015-06-15 23:49:46 lock_time = 1 binlog_pos = filename 'mysql-bin.000005', position245 innodb_from_lsn = 0 innodb_to_lsn = 1597945 partial = N incremental = N format = file compact = N compressed = N encrypted = N
通常状况下,在备份完成后,数据尚且不能用于恢复操做,由于备份的数据中可能会包含还没有提交的事务或已经提交但还没有同步至数据文件中的事务。所以,此时数据文件仍处于不一致状态。“准备”的主要做用正是经过回滚未提交的事务及同步已经提交的事务至数据文件也使得数据文件处于一致性状态。
innobakupex命令的--apply-log选项可用于实现上述功能。以下面的命令:
[root@MariaDB 2015-06-15_23-49-43]# innobackupex--apply-log /backup/2015-06-15_23-49-43/
若是执行正确,其最后输出的一行信息一般以下:
150615 23:58:59 innobackupex: completed OK!
在实现“准备”的过程当中,innobackupex一般还可使用--use-memory选项来指定其可使用的内存的大小,默认一般为100M。若是有足够的内存可用,能够多划分一些内存给prepare的过程,以提升其完成速度。
innobackupex命令的--copy-back选项用于执行恢复操做,其经过复制全部数据相关的文件至mysql服务器DATADIR目录中来执行恢复过程。innobackupex经过backup-my.cnf来获取DATADIR目录的相关信息。
语法:
# innobackupex --copy-back /path/to/BACKUP-DIR
当数据恢复至DATADIR目录之后,还须要确保全部数据文件的属主和属组均为正确的用户,如mysql,不然,在启动mysqld以前还须要事先修改数据文件的属主和属组。
模拟数据库损坏
删除mariadb数据目录中的全部内容,模拟数据库损坏
[root@MariaDB~]# rm -rf /mydata/data/* [root@MariaDB~]# ll /mydata/data/ total0
恢复数据
[root@MariaDB~]# innobackupex --copy-back /backup/2015-06-15_23-49-43/ [root@MariaDB ~]# chown -R mysql:mysql /mydata/data/ [root@MariaDB~]# ll /mydata/data/ total 28692 drwxr-xr-x2 mysql mysql 4096 Jun 16 00:01hellodb -rw-r--r--1 mysql mysql 18874368 Jun 16 00:01 ibdata1 -rw-r--r--1 mysql mysql 5242880 Jun 16 00:01ib_logfile0 -rw-r--r--1 mysql mysql 5242880 Jun 16 00:01ib_logfile1 drwxr-xr-x2 mysql mysql 4096 Jun 16 00:01 mysql drwxr-xr-x2 mysql mysql 4096 Jun 16 00:01performance_schema drwxr-xr-x2 mysql mysql 4096 Jun 16 00:01 test -rw-r--r--1 mysql mysql 559 Jun 16 00:01xtrabackup_info
恢复完成以后,还须要启动一下Mysql服务,不然Mariadb是是不会记录二进制日志的,这个时候启动起来是从新记录二进制日志的。
[root@MariaDB ~]# service mysqld start
提示:在恢复完成以后应该再次作一次彻底备份,后期的增量备份都依照此次的彻底备份来作。
[root@MariaDB ~]# innobackupex --user root --password centos/backup
每一个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-onlyBASE-DIR
接着执行:
# innobackupex --apply-log --redo-onlyBASE-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指的是第二次增量备份的目录,其它依次类推,即若是有屡次增量备份,每一次都要执行如上操做;
因为上面的彻底备份恢复以后又进行了一次彻底备份,这里再也不进行彻底备份,增量备份直接根据上面的彻底备份进行。
查看lsn日志的起始和结束位置,第一次增量备份的LSN起始位置就是彻底备份LSN的结束位置
[root@MariaDB ~]# cat/backup/2015-06-15_23-45-01/xtrabackup_checkpoints backup_type = full-backuped from_lsn = 0 to_lsn = 1602246 last_lsn = 1602246 compact = 0
修改数据库内容
MariaDB[hellodb]> select * from tb1; +------+ |id | +------+ | 1 | | 2 | | 3 | | 21 | | 22 | | 23 | +------+ MariaDB[hellodb]> delete from tb1 where id=21; MariaDB[hellodb]> delete from tb1 where id=22; MariaDB[hellodb]> select * from tb1; +------+ |id | +------+ | 1 | | 2 | | 3 | | 23 | +------+
第一次增量备份
只须要指向上一次彻底备份的位置和这一次增量备份的存储位置便可
[root@MariaDB ~]# innobackupex --user root--password centos --incremental /backup/ --incremental-basedir=/backup/2015-06-15_23-45-01/
备份完成以后查看checkpoints信息
[root@MariaDB ~]# cat/backup/2015-06-15_23-47-02/xtrabackup_checkpoints backup_type = incremental #备份类型表示为增量 from_lsn = 1602246 #表示备份的起始位置 to_lsn = 1604539 last_lsn = 1604539 compact = 0
再次修改一些数据
MariaDB[hellodb]> insert into tb1 values (1000),(9000); MariaDB[hellodb]> select * from tb1; +------+ |id | +------+ | 1 | | 2 | | 3 | | 23 | |1000 | |9000 | +------+
第二次作增量备份
这是备份是基于第一次增量备份进行
[root@MariaDB ~]# innobackupex --user root--password centos --incremental /backup--incremental-basedir=/backup/2015-06-15_23-47-02/ [root@MariaDB ~]# cat/backup/2015-06-15_23-51-55/xtrabackup_checkpoints backup_type = incremental from_lsn = 1604539 #备份起始位置是第一次增量备份的结束位置 to_lsn = 1604539 last_lsn = 1605623 compact = 0
再次修改一次数据,此次修改没有作备份
MariaDB[hellodb]> insert into tb1 values (88888); MariaDB[hellodb]> select * from tb1; +-------+ |id | +-------+ | 1 | | 2 | | 3 | | 23 | | 1000 | | 9000 | |88888 | +-------+
说明:因为没有实现将bin-log文件和数据目录分开,因此我先导入二进制日志文件中的修改内容。
查看binlog_info日志位置记录位置为1621,那么只须要把1621以后的修改导出为sql文件便可。
[root@MariaDB~]# cat /backup/2015-06-15_23-51-55/xtrabackup_binlog_info mysql-bin.000005 979 [root@MariaDB ~]# mysqlbinlog --start-position=979/mydata/data/mysql-bin.000005 > /backup/timepoint.sql
中止mysqld服务,而后删除数据目录下的全部数据,模拟硬盘损坏
[root@MariaDB~]# service mysqld stop [root@MariaDB~]# rm -rf /mydata/data/*
恢复过程:合并彻底备份
[root@MariaDB ~]# innobackupex --apply-log-redo-only /backup/2015-06-15_23-45-01/
合并第一个增量备份
[root@MariaDB ~]# innobackupex --apply-log-redo-only /backup/2015-06-15_23-45-01/--incremental-dir=/backup/2015-06-15_23-47-02/
合并第二个增量备份
[root@MariaDB ~]# innobackupex --apply-log-redo-only /backup/2015-06-15_23-45-01/--incremental-dir=/backup/2015-06-15_23-51-55/
使用合并后的命令进行恢复
[root@MariaDB ~]# innobackupex --copy-back/backup/2015-06-15_23-45-01/
设置完成以后修改数据目录的属主属组
[root@MariaDB data]# chown -R mysql.mysql ./* [root@MariaDB data]# ll total 18452 drwxr-xr-x 2 mysql mysql 4096 Jun 16 00:01 hellodb -rw-r--r-- 1 mysql mysql 18874368 Jun 16 00:01ibdata1 drwxr-xr-x 2 mysql mysql 4096 Jun 16 00:01 mysql drwxr-xr-x 2 mysql mysql 4096 Jun 16 00:01 performance_schema drwxr-xr-x 2 mysql mysql 4096 Jun 16 00:01 test -rw-r--r-- 1 mysql mysql 632 Jun 16 00:01 xtrabackup_info
设置完成以后启动Mysql服务器
[root@MariaDBdata]# service mysqld start
查看数据库这个时候尚未第二次增量备份以后修改的数据
MariaDB[hellodb]> select * from tb1; +------+ |id | +------+ | 1 | | 2 | | 3 | | 23 | |1000 | |9000 | +------+
将从二进制导出的sql文件,导入到数据库
[root@MariaDB ~]# mysql -u root -p < /backup/timepoint.sql
查看数据就已经恢复了
MariaDB[hellodb]> select * from tb1; +-------+ |id | +-------+ | 1 | | 2 | | 3 | | 23 | | 1000 | | 9000 | |88888 | +-------+
默认状况下,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 TABLEmydatabase.mytable DISCARD TABLESPACE;
接下来,未来自于“导出”表的服务器的mytable表的mytable.ibd和mytable.exp文件复制到当前服务器的数据目录,而后使用以下命令将其“导入”:
mysql> ALTER TABLEmydatabase.mytable IMPORT TABLESPACE;
为了方便称呼,将导出表的服务器称为“源服务器”,导入表的服务器称为目标服务器。
设置以前先作一次全库备份,由于导出表是根据备份进行导出的
[root@MariaDB~]# innobackupex --user root --password centos /backup/
源服务器导出全部innodb存储引擎的表
[root@MariaDB~]# innobackupex --apply-log --export /backup/2015-06-16_00-14-21/
查看hellodb导出的表文件
[root@MariaDB ~]# ls/backup/2015-06-16_00-14-21/hellodb/ classes.frm coc.MYD courses.MYI scores.MYI tb1.cfg teachers.frm toc.MYD classes.MYD coc.MYI db.opt students.frm tb1.exp teachers.MYD toc.MYI classes.MYI courses.frm scores.frm students.MYD tb1.frm teachers.MYI coc.frm courses.MYD scores.MYD students.MYI tb1.ibd toc.frm
目标服务器建立数据库和准备导入的表
建立的表须要和源服务器上面的建立表的时候使用如出一辙的命令;源服务器查看建立表的方法以下
MariaDB[hellodb]> show create table tb1; +-------+---------------------------------------------------------------------------------------+ |Table | Create Table | +-------+---------------------------------------------------------------------------------------+ |tb1 | CREATE TABLE `tb1` ( `id` int(11) DEFAULT NULL )ENGINE=InnoDB DEFAULT CHARSET=utf8 | +-------+---------------------------------------------------------------------------------------+
获取到源服务器建立表的命令后,目标服务器就能够直接复制用来建立表
MariaDB[(none)]> create database mydb; MariaDB[(none)]> use mydb; MariaDB[mydb]> CREATE TABLE `tb1` ( -> `id` int(11) DEFAULT NULL -> ) ENGINE=InnoDB DEFAULT CHARSET=utf8; MariaDB[mydb]> show tables; +----------------+ |Tables_in_mydb | +----------------+ |tb1 | +----------------+
目标服务器须要启用每表一个表空间的选项,此选项我在安装Mariadb时已经开启。
MariaDB[mydb]> show global variables like 'innodb_file%'; +--------------------------+----------+ |Variable_name | Value | +--------------------------+----------+ |innodb_file_format | Antelope | |innodb_file_format_check | ON | |innodb_file_format_max | Antelope | |innodb_file_per_table | ON | #此处为ON表示启用 +--------------------------+----------+ 4rows in set (0.00 sec)
目标服务器删除建立表的表空间
MariaDB[mydb]> ALTER TABLE tb1 DISCARD TABLESPACE;
复制表空间文件到远程服务器
[root@MariaDBhellodb]# scp tb1.frm tb1.ibd 172.16.4.10:/mydata/data/mydb
修改属组和属主为Mysql
[root@MariaDB~]# cd /mydata/data/mydb/ [root@MariaDBmydb]# ll total112 -rw-rw----1 mysql mysql 65 May 27 22:45 db.opt -rw-rw----1 mysql mysql 8556 May 27 22:53 tb1.frm -rw-r-----1 root root 98304 May 27 22:53 tb1.ibd [root@MariaDBmydb]# chown -R mysql:mysql tb1.ibd [root@MariaDBmydb]# ll total112 -rw-rw----1 mysql mysql 65 May 27 22:45 db.opt -rw-rw----1 mysql mysql 8556 May 27 22:53 tb1.frm -rw-r-----1 mysql mysql 98304 May 27 22:53 tb1.ibd
从新导入表空间
MariaDB[mydb]> ALTER TABLE tb1 IMPORT TABLESPACE;
查看数据库状态
MariaDB[mydb]> show table status like 'tb1'\G; ERROR2006 (HY000): MySQL server has gone away Noconnection. Trying to reconnect... Connectionid: 1 Currentdatabase: mydb ***************************1. row *************************** Name: tb1 Engine: InnoDB Version: 10 Row_format: Compact Rows: 8 Avg_row_length: 2048 Data_length: 16384 Max_data_length:0 Index_length: 0 Data_free: 0 Auto_increment: NULL Create_time: 2015-05-27 22:53:24 Update_time: NULL Check_time: NULL Collation: utf8_general_ci Checksum: NULL Create_options: Comment: 1row in set (0.01 sec) ERROR:No query specified
查看表已经有了数据
MariaDB[mydb]> select * from tb1; +------+ |id | +------+ | 1 | | 2 | | 3 | | 23 | |1000 | |9000 | +------+ 6rows in set (0.01 sec)
补充:若是对于MyISAM存储引擎来讲,直接复制三个文件(.frm: 表结构 .MYD:表数据.MYI:表索引)到表目录下便可,MyISAM会自动识别的。