MariaDB之基于Percona Xtrabackup备份大数据库[完整备份与增量备份]
1.Xtrabackup的安装
percona-xtrabackup-2.2.3-4982.el6.x86_64.rpm
lftp 172.16.0.1:/pub/Sources/6.x86_64/Percona> get percona-xtrabackup-2.2.3-4982.el6.x86_64.rpm
yum -y install percona-xtrabackup-2.2.3-4982.el6.x86_64.rpm
二、Xtrabackup完全备份的实现
1、前提准备
(1)创建数据备份目录
[root@node19 ~]# mkdir /backups/
(2)修改二进制日志文件存储路径
[root@node19 ~]# vim /etc/mysql/my.cnf
log-bin=/mydata/binlogs/master-bin
(3) 修改创建的文件的所属主和所属组
[root@node19 ~]#mkdir /mydata/binlogs
[root@node19 ~]#chown –R ysql.mysql /mydata/data/
(4)授权一个最小权限的用户进行复制
MariaDB [(none)]> grant reload,lock tables,replication client on *.* to 'backup'@'localhost' identified by 'backup';
MariaDB [(none)]> flush privileges;
2、完整备份的实现
(1)导入一个数据库,就不自己建库了
MariaDB [hellodb]> set sql_log_bin=0; #导入数据库过程无需记录二进制日志,把以先暂时关闭
MariaDB [hellodb]> source hellodb.sql;
MariaDB [hellodb]> show databases;
+--------------------+
| Database |
+--------------------+
| hellodb |
| information_schema |
| mysql |
| performance_schema |
| test |
+--------------------+
5 rows in set (0.00 sec)
MariaDB [hellodb]> set sql_log_bin=1; #开启二进制日志
MariaDB [(none)]> select @@sql_log_bin;
+---------------+
| @@sql_log_bin |
+---------------+
| 1 |
+---------------+
1 row in set (0.00 sec)
(2)做完整备份
[root@node19 ~]# innobackupex --user=backup --password=backup --host=localhost /backups/ #做完备
innobackupex: Backup created in directory '/backups/2015-01-22_19-47-43' #备份存储路径
innobackupex: MySQL binlog position: filename 'master-bin.000001', position 367 #二进制日志及位置信息
150122 19:47:46 innobackupex: Connection to database server closed
150122 19:47:46 innobackupex: completed OK! #只有到了这里才说明备份成功
[root@node19 ~]#
看一下备份目录中生成的一些文件
[root@node19 backups]# pwd
/backups
[root@node19 backups]# ls
2015-01-22_19-47-43
[root@node19 backups]# cd 2015-01-22_19-47-43/
[root@node19 2015-01-22_19-47-43]# ll
total 12324
-rw-r--r-- 1 root root 357 Jan 22 19:47 backup-my.cnf
drwxr-xr-x 2 root root 4096 Jan 22 19:47 hellodb
-rw-r----- 1 root root 12582912 Jan 22 19:47 ibdata1
drwx------ 2 root root 4096 Jan 22 19:47 mysql
drwxr-xr-x 2 root root 4096 Jan 22 19:47 performance_schema
drwxr-xr-x 2 root root 4096 Jan 22 19:47 test
-rw-r--r-- 1 root root 24 Jan 22 19:47 xtrabackup_binlog_info
-rw-r----- 1 root root 89 Jan 22 19:47 xtrabackup_checkpoints
-rw-r--r-- 1 root root 581 Jan 22 19:47 xtrabackup_info
-rw-r----- 1 root root 2560 Jan 22 19:47 xtrabackup_logfile
三、使用完全备份恢复数据
1、模拟数据误删除
[root@node19 ~]# cd /mydata/data/
[root@node19 data]# ls
aria_log.00000001 aria_log_control hellodb ibdata1 ib_logfile0 ib_logfile1 mysql performance_schema test xtrabackup_info
[root@node19 data]# rm -rf ./*
[root@node19 data]# ls
2、准备一个完全备份
[root@node19 ~]# innobackupex --apply-log /backups/2015-01-22_19-47-43/
xtrabackup: starting shutdown with innodb_fast_shutdown = 1
InnoDB: FTS optimize thread exiting.
InnoDB: Starting shutdown...
InnoDB: Shutdown completed; log sequence number 1626134
150122 19:56:59 innobackupex: completed OK!
注意:不要在备份完成后整理,要在恢复时再去整理
3、从完全备份中恢复数据
在此时恢复数据时,不要启动mysql
[root@node19 ~]# innobackupex --copy-back /backups/2015-01-22_19-47-43/
.
.
.
150122 20:00:55 innobackupex: completed OK! #到了这里就说明恢复成功了
查看下数据目录
[root@node19 data]# pwd
/mydata/data
[root@node19 data]# ll
total 110612
drwxr-xr-x 2 root root 4096 Jan 22 20:00 hellodb
-rw-r--r-- 1 root root 12582912 Jan 22 20:00 ibdata1
-rw-r--r-- 1 root root 50331648 Jan 22 20:00 ib_logfile0
-rw-r--r-- 1 root root 50331648 Jan 22 20:00 ib_logfile1
drwxr-xr-x 2 root root 4096 Jan 22 20:00 mysql
drwxr-xr-x 2 root root 4096 Jan 22 20:00 performance_schema
drwxr-xr-x 2 root root 6 Jan 22 20:00 test
-rw-r--r-- 1 root root 24 Jan 22 20:00 xtrabackup_binlog_pos_innodb
-rw-r--r-- 1 root root 581 Jan 22 20:00 xtrabackup_info
数据是都回来了,可是数据的属主和属组都是root,所以应该将其全部修改为mysql
[root@node19 ~]# chown -R mysql.mysql /mydata/data/
[root@node19 ~]# ll /mydata/data/
total 110612
drwxr-xr-x 2 mysql mysql 4096 Jan 22 20:00 hellodb
-rw-r--r-- 1 mysql mysql 12582912 Jan 22 20:00 ibdata1
-rw-r--r-- 1 mysql mysql 50331648 Jan 22 20:00 ib_logfile0
-rw-r--r-- 1 mysql mysql 50331648 Jan 22 20:00 ib_logfile1
drwxr-xr-x 2 mysql mysql 4096 Jan 22 20:00 mysql
drwxr-xr-x 2 mysql mysql 4096 Jan 22 20:00 performance_schema
drwxr-xr-x 2 mysql mysql 6 Jan 22 20:00 test
-rw-r--r-- 1 mysql mysql 24 Jan 22 20:00 xtrabackup_binlog_pos_innodb
-rw-r--r-- 1 mysql mysql 581 Jan 22 20:00 xtrabackup_info
启动mysql服务,连入mysql验证是否正常
[root@node19 ~]# service mysqld start
Starting MySQL [ OK ]
[root@node19 ~]# mysql
MariaDB [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| hellodb |
| information_schema |
| mysql |
| performance_schema |
| test |
+--------------------+
5 rows in set (0.04 sec)
一个不差,数据完美恢复成功
四、使用innobackupex进行增量备份
每个InnoDB的页面都会包含一个LSN信息,每当相关的数据发生改变,相关的页面的LSN就会自动增长。这正是InnoDB表可以进行增量备份的基础,即innobackupex通过备份上次完全备份之后发生改变的页面来实现。
需要注意的是,增量备份仅能应用于InnoDB或XtraDB表,对于MyISAM表而言,执行增量备份时其实进行的是完全备份。
1、新建一个数据库,达到数据库发生变化的目的
MariaDB [(none)]> create database t1;
Query OK, 1 row affected (0.05 sec)
MariaDB [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| hellodb |
| information_schema |
| mysql |
| performance_schema |
| t1 |
| test |
+--------------------+
6 rows in set (0.00 sec)
2、进行第一次增量备份
[root@node19 ~]# innobackupex --incremental /backups/ --incremental-basedir=/backups/2015-01-22_19-47-43/
.
.
innobackupex: Created backup directory /backups/2015-01-22_20-13-29 #增量备份也产生了一个以时间命名的目录
innobackupex: MySQL binlog position: filename 'master-bin.000001', position 484 #记录的二进制日志及位置
150122 20:13:34 innobackupex: Connection to database server closed
150122 20:13:34 innobackupex: completed OK! #出现OK说明操作成功
其中,/backups/2014-04-21_11-28-06/指的是完全备份所在的目录,此命令执行结束后,innobackupex命令会在/backups目录中创建一个新的以时间命名的目录以存放所有的增量备份数据。另外,在执行过增量备份之后再一次进行增量备份时,其--incremental-basedir应该指向上一次的增量备份所在的目录。
如果每一次都相对于上次的完全备份做增量备份,那就是差异备份!
既然完全备份出来的目录是以日期+时间为命名的,而增量备份也是日期+时间命名的,那应该怎么区分这个备份出来的数据目录是完全备份还是增量备份呢
其实也很多简单,只需进入备份出来的目录看一下它的xtrabackup_checkpoints就知道了
[root@node19 backups]# pwd
/backups
[root@node19 backups]# ls
2015-01-22_19-47-43 2015-01-22_20-13-29
[root@node19 backups]# cd 2015-01-22_19-47-43/
[root@node19 2015-01-22_19-47-43]# ls
backup-my.cnf ib_logfile0 performance_schema xtrabackup_binlog_pos_innodb xtrabackup_logfile
hellodb ib_logfile1 test xtrabackup_checkpoints
ibdata1 mysql xtrabackup_binlog_info xtrabackup_info
[root@node19 2015-01-22_19-47-43]# cat xtrabackup_checkpoints
backup_type = full-prepared #这就是完全备份
from_lsn = 0
to_lsn = 1625632
last_lsn = 1625632
compact = 0
那再看一下刚才备份出来的那个增量备份的目录中的xtrabackup_checkpoints
[root@node19 backups]# ls
2015-01-22_19-47-43 2015-01-22_20-13-29
[root@node19 backups]# cd 2015-01-22_20-13-29/
[root@node19 2015-01-22_20-13-29]# cat xtrabackup_checkpoints
backup_type = incremental #这就是增量备份
from_lsn = 1625632
to_lsn = 1626144
last_lsn = 1626144
compact = 0
3、第二次增量备份
首先再创建一个数据库,再让数据库变化下
MariaDB [(none)]> create database t2;
Query OK, 1 row affected (0.00 sec)
MariaDB [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| hellodb |
| information_schema |
| mysql |
| performance_schema |
| t1 | #第一次增量备份时备份了t1这个库
| t2 | #第一次增量备份时备份了t2这个库
| test |
+--------------------+
7 rows in set (0.00 sec)
基于上一次增量备份再做增量备份(增量不就是这样吗?不是差异啊!)
[root@node19 ~]# innobackupex --incremental /backups/ --incremental-basedir=/backups/2015-01-22_20-13-29/ #指的目录是上一次增量备份的目录哦
innobackupex: Backup created in directory '/backups/2015-01-22_20-25-50'
innobackupex: MySQL binlog position: filename 'master-bin.000001', position 715
150122 20:25:55 innobackupex: Connection to database server closed
150122 20:25:55 innobackupex: completed OK! #看到OK才放心
第二次增量备份后又修改了数据库,但此时修改完后还没来得及做增量备份。像这样的情况,如果数据丢失了,在没做增量备份的情况下,就只能依靠二进制日志文件来恢复了
MariaDB [(none)]> create database t3;
Query OK, 1 row affected (0.00 sec)
MariaDB [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| hellodb |
| information_schema |
| mysql |
| performance_schema |
| t1 | #第一次增量备份时,备份到了t2这个库
| t2 | #第二次增量备份时,备份到了t2这个库
| t3 | #第三次增量备份时,备份到了t3这个库
| test |
+--------------------+
8 rows in set (0.00 sec)
五、增量备份的还原
像准备完全备份一样, 增量备份的还原也需要有一个准备的过程
"准备"(prepare)增量备份与整理完全备份有着一些不同,尤其要注意的是:
(1)需要在每个备份(包括完全和各个增量备份)上,将已经提交的事务进行"重放"。"重放"之后,所有的备份数据将合并到完全备份上。
(2)基于所有的备份将未提交的事务进行"回滚"。
于是,操作就变成了:
1. #innobackupex --apply-log --redo-only BASE-DIR
接着执行:
2. # 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指的是第二次增量备份的目录,其它依次类推,即如果有多次增量备份,每一次都要执行如上操作
1.删除数据目录下的所有文件
[root@node19 ~]# cd /mydata/data/ #删除数据目录下的所有
[root@node19 data]# rm -rf ./* #清空的很彻底
[root@node19 data]# ls
还好有二进制日志,这就是二进制日志为什么要与数据目录分开放的原因,可以做即时点还原
[root@node19 binlogs]# pwd
/mydata/binlogs
[root@node19 binlogs]# ll
total 16
-rw-rw---- 1 mysql mysql 946 Jan 22 20:28 master-bin.000001
-rw-rw---- 1 mysql mysql 346 Jan 22 20:06 master-bin.000002
-rw-rw---- 1 mysql mysql 68 Jan 22 20:06 master-bin.index
-rw-rw---- 1 mysql mysql 6 Jan 22 20:06 master-bin.state
2、数据还原准备过程
现在备份目录中的情况是这样的,第一个文件是完全备份,剩下的那两个是增量备份
[root@node19 backups]# pwd
/backups
[root@node19 backups]# ls
2015-01-22_19-47-43 2015-01-22_20-13-29 2015-01-22_20-25-50
(1)准备第一次完全备份
[root@node19 backups]# ls
2015-01-22_19-47-43 2015-01-22_20-13-29 2015-01-22_20-25-50
[root@node19 backups]# innobackupex --apply-log --redo-only 2015-01-22_19-47-43/ #准备完全备份
.
.
.
InnoDB: Shutdown completed; log sequence number 1626134
150122 20:49:35 innobackupex: completed OK! #完全备份准备OK
(2)准备第一次增量备份
[root@node19 backups]# ls
2015-01-22_19-47-43 2015-01-22_20-13-29 2015-01-22_20-25-50
[root@node19 backups]# innobackupex --apply-log --redo-only /backups/2015-01-22_19-47-43/ --incremental-dir=/backups/2015-01-22_20-13-29/
(3)准备第二次增量备份
[root@node19 backups]#innobackupex --apply-log --redo-only /backups/2015-01-22_19-47-43/ --incremental-dir=/backups/2015-01-22_20-25-50/
3、还原数据
(1)经过上面的三步准备,现在终于可以还原数据了,下面就是见证奇迹的时刻
[root@node19 backups]# ls
2015-01-22_19-47-43 2015-01-22_20-13-29 2015-01-22_20-25-50
[root@node19 backups]#innobackupex --copy-back /backups/2015-01-22_19-47-43/ #用准备好的完全备份恢复数据
(2)查看下恢复回来的数据
经过一次完全和两次增量备份还原,数据已经恢复到了第二次增量备份时的状态
[root@node19 backups]#cd /mydata/data/
[root@node19 data]# ll #第二次增量备份前的数据都回来了,只有后来哪个t3库没有
#此时数据目录中的所有文件的属主属组都是root,所以要修改成mysql
[root@node19 data]# chown -R mysql.mysql *
(3)使用二进制日志文件做即时点恢复
因为我们在做第二次增量备份后,又修改了数据(创建了数据库t3),所以数据只能恢复到第二次增量备份时的状态,想要恢复以后的数据就只能依靠二进制日志做即时点恢复了
①、 查看最后一个增量备份文件的cat xtrabackup_binlog_info,查看它的 二进制日志,这个二进制日志记录数据库最后一次操作为备份的
[root@node19 backups]# ls
2015-01-22_22-05-03 2015-01-22_22-09-22 2015-01-22_22-10-52
[root@node19 2015-01-22_22-10-52]# cat xtrabackup_binlog_info
master-bin.000001 11331
②、 由于二进制日志是没法直接查看的,所以要先把它导出来,然后再看看里面是否有我们后来创建的hhht数据库
[root@node19 binlogs]# pwd
/mydata/binlogs
[root@node19 binlogs]# ll
total 16
-rw-rw---- 1 mysql mysql 946 Jan 22 20:28 master-bin.000001
-rw-rw---- 1 mysql mysql 346 Jan 22 20:06 master-bin.000002
-rw-rw---- 1 mysql mysql 68 Jan 22 20:06 master-bin.index
-rw-rw---- 1 mysql mysql 6 Jan 22 20:06 master-bin.state
[root@node19 binlogs]#mysqlbinlog –-start-position=# master-bin.00000x > a.sql #导出二进制日志
注释:# 是查看增量最后备份文件里 cat xtrabackup_checkpoints
查看其还原点。
③、查看使用二进制日志导出的a.sql
[root@node19 binlogs]#vim a.sql
确实有刚才创建的t3数据库,那就是它了。现在把这个二进制日志文件导出来并附加到数据库中