阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

MySQL物理备份 xtrabackup

245次阅读
没有评论

共计 10806 个字符,预计需要花费 28 分钟才能阅读完成。

MySQL 备份之 xtrabackup | innobackupex

Xtrabackup 介绍

MySQL 物理备份 xtrabackup

Xtrabackup 是一个对 InnoDB 做数据备份的工具,支持在线热备份(备份时不影响数据读写),是商业备份工具 InnoDB Hotbackup 的一个很好的
替代品。Xtrabackup 有两个主要的工具:xtrabackup、innobackupex 
1、xtrabackup 只能备份 InnoDB 和 XtraDB 两种数据表,而不能备份 MyISAM 数据表 
2、innobackupex 是参考了 InnoDB Hotbackup 的 innoback 脚本修改而来的.innobackupex 是一个 perl 脚本封装,封装了 xtrabackup。主要
是为了方便的同时备份 InnoDB 和 MyISAM 引擎的表,但在处理 myisam 时需要加一个读锁。并且加入了一些使用的选项。如 slave-info 可以记录备份
恢复后,作为 slave 需要的一些信息,根据这些信息,可以很方便的利用备份来重做 slave。3、官方文档:http://www.percona.com/doc/percona-xtrabackup/2.1/ 

A、Xtrabackup 是什么?

MySQL 物理备份 xtrabackup

在线 (热) 备份整个库的 InnoDB、XtraDB 表 
  在 xtrabackup 的上一次整库备份基础上做增量备份(innodb only) 
  以流的形式产生备份,可以直接保存到远程机器上(本机硬盘空间不足时很有用) 
  MySQL 数据库本身提供的工具并不支持真正的增量备份,二进制日志恢复是 point-in-time(时间点)的恢复而不是增量备份。Xtrabackup 工具支持
对 InnoDB 存储引擎的增量备份,工作原理如下:(1)首先完成一个完全备份,并记录下此时检查点的 LSN(Log Sequence Number)。(2)在进程增量备份时,比较表空间中每个页的 LSN 是否大于上次备份时的 LSN,如果是,则备份该页,同时记录当前检查点的 LSN。首先,在 logfile 中找到并记录最后一个 checkpoint(“last checkpoint LSN”),然后开始从 LSN 的位置开始拷贝 InnoDB 的 logfile 到
xtrabackup_logfile;接着,开始拷贝全部的数据文件.ibd;在拷贝全部数据文件结束之后,才停止拷贝 logfile。因为 logfile 里面记录全部的数据修改情况,所以,即时在备份过程中数据文件被修改过了,恢复时仍然能够通过解析 xtrabackup_logfile 保持数据
的一致。

B、Xtrabackup 可以做什么?

MySQL 物理备份 xtrabackup

XtraBackup 基于 InnoDB 的 crash-recovery 功能。它会复制 innodb 的 data file,由于不锁表,复制出来的数据是不一致的,在恢复的时候使用
crash-recovery,使得数据恢复一致。InnoDB 维护了一个 redo log,又称为 transaction log,事务日志,它包含了 innodb 数据的所有改动情况。当 InnoDB 启动的时候,它会先去检
查 data file 和 transaction log,并且会做二步操作:XtraBackup 在备份的时候,一页一页地复制 innodb 的数据,而且不锁定表,与此同时,XtraBackup 还有另外一个线程监视着 transactions log,一旦 log 发生变化,就把变化过的 log pages 复制走。为什么要急着复制走呢?因为 transactions log 文件大小有限,写满之后,就会从头再开始写,所以新数据可能会覆盖到旧的数据。在 prepare 过程中,XtraBackup 使用复制到的 transactions log 对备份出来的 innodb data file 进行 crash recovery。官方原理 
在 InnoDB 内部会维护一个 redo 日志文件,我们也可以叫做事务日志文件。事务日志会存储每一个 InnoDB 表数据的记录修改。当 InnoDB 启动 时,InnoDB 会检查数据文件和事务日志,并执行两个步骤:它应用(前滚)已经提交的事务日志到数据文件,并将修改过但没有提交的数据进行回滚操作。Xtrabackup 在启动时会记住 log sequence number(LSN),并且复制所有的数据文件。复制过程需要一些时间,所以这期间如果数据文件有改动,那么将会使数据库处于一个不同的时间点。这 时,xtrabackup 会运行一个后台进程,用于监视事务日志,并从事务日志复制最新的修改。Xtrabackup
必须持续的做这个操作,是因为事务日 志是会轮转重复的写入,并且事务日志可以被重用。所以 xtrabackup 自启动开始,就不停的将事务日志中每个
数据文件的修改都记录下来。上面就是 xtrabackup 的备份过程。接下来是准备(prepare)过程。在这个过程中,xtrabackup 使用之前复制的事务日志,对各个数据文件执行灾难
恢复(就像 mysql 刚启动时要做的一样)。当这个过程结束后,数据库就可以做恢复还原了。以 上的过程在 xtrabackup 的编译二进制程序中实现。程序 innobackupex 可以允许我们备份 MyISAM 表和 frm 文件从而增加了便捷和功 能。Innobackupex 会启动 xtrabackup,直到 xtrabackup 复制数据文件后,然后执行 FLUSH TABLES WITH READ LOCK 来阻止新的写入进来并把 MyISAM
表数据刷到硬盘上,之后复制 MyISAM 数据文件,最后释放锁。备 份 MyISAM 和 InnoDB 表最终会处于一致,在准备(prepare)过程结束后,InnoDB 表数据已经前滚到整个备份结束的点,而不是回滚到 xtrabackup
刚开始时的点。这个时间点与执行 FLUSH TABLES WITH READ LOCK 的时间点相同,所以 myisam 表数据与 InnoDB 表数据是同步的。类似 oracle 的,InnoDB 的 prepare 过程可以称为 recover(恢复),myisam 的数据复制过程可以称为 restore(还原)。Xtrabackup 和 innobackupex 这两个工具都提供了许多前文没有提到的功能特点。手册上有对各个功能都有详细的介绍。简单介绍下,这些工具提供
了如流(streaming)备份,增量(incremental)备份等,通过复制数据文件,复制日志文件和提交日志到数据文件(前滚)实现了各种复合备份方 式。

C、Xtrabackup 备份原理

MySQL 物理备份 xtrabackup

XtraBackup 以 read-write 模式打开 innodb 的数据文件,然后对其进行复制。其实它不会修改此文件。也就是说,运行 XtraBackup 的用户,必须
对 innodb 的数据文件具有读写权限。之所以采用 read-write 模式是因为 XtraBackup 采用了其内置的 innodb 库来打开文件,而 innodb 库打开文件
的时候就是 rw 的。XtraBackup 要从文件系统中复制大量的数据,所以它尽可能地使用 posix_fadvise(),来告诉 OS 不要缓存读取到的数据,从而提升性能。因为这些
数据不会重用到了,OS 却没有这么聪明。如果要缓存一下的话,几个 G 的数据,会对 OS 的虚拟内存造成很大的压力,其它进程,比如 mysqld 很有可
能被 swap 出去,这样系统就会受到很大影响了。在备份 innodb page 的过程中,XtraBackup 每次读写 1MB 的数据,1MB/16KB=64 个 page。这个不可配置。读 1MB 数据之后,XtraBackup
一页一页地遍历这 1MB 数据,使用 innodb 的 buf_page_is_corrupted()函数检查此页的数据是否正常,如果数据不正常,就重新读取这一页,最多重
新读取 10 次,如果还是失败,备份就失败了,退出。在复制 transactions log 的时候,每次读写 512KB 的数据。同样不可以配置。

D、Xtrabackup 实现细节

MySQL 物理备份 xtrabackup

基于以上原理,xtrabackup 备份恢复工具比较适合数据增长型数据库。对于数据增长型的库,由于数据的增长导致数据备份和恢复的空间和时
间上的压力较大。而 xtrabackup 有增量备份的功能,在短时间内可以通过进行增量备份来保证数据的安全性。而长期来看,仍然需要间断性的进行全库
备份。此外,由于 xtrabackup 对 innodb 的数据库不进行锁定,因此对要求不影响线上服务的数据备份和恢复较适合。而对于数据量无明显增长,且更新为主的数据更新型数据库,xtrabackup 显得过于复杂。xtrabackup 操作反而不如 mysqldump 的性能高。

E、Xtrabackup 应用场景

MySQL 物理备份 xtrabackup

个人理解:1、无需停止数据库进行 InnoDB 热备, 快速、可靠的完成备份 
    2. 备份期间不间断事务处理 
    3. 节省磁盘空间和网络带宽 
    4. 自动对备份文件进行验证 
    5. 快速恢复,保障在线运行时间持久性 
官方说明:1. 在不停库的情况下,对 InnoDB 数据库进行热备 
    2. 增量备份 MySQL 数据库 
    3. 通过流压缩备份 MySQL 数据到另外一台服务器 
4. 在线 MySQL 服务器之间进行表空间迁移

F、Xtrabackup 优势

Xtrabackup 安装

官网下载:https://www.percona.com/downloads/XtraBackup/LATEST/

本文示例安装包下载

下载链接:https://pan.baidu.com/s/1C88-Ninf0cTG3ghBWdMPEw 密码:0kp1

安装软件

[root@Admin ~]# yum install libev -y 

[root@Admin ~]# rpm -ivh percona-xtrabackup-24-2.4.7-2.el6.x86_64.rpm 

Xtrabackup 实例

创建测试数据

建库:mysql> create database ceshi;

建表:mysql> create table users (id int primary key auto_increment,name varchar(20) not null unique,password varchar(100) not null,address 
varchar(200))ENGINE=MyISAM; 

添加数据:mysql> insert into users (id,name,password,address) values (1,'zhang','1234',null),(2,'wang','4321','湖北武汉 '), (3,'li','5678',' 北京海淀'); 

建库:mysql> create database test2;

建表:mysql> create table articles (id int primary key auto_increment,content longtext not null);

添加数据:mysql> insert into articles (id,content) values (11,'hahahahahaha'),(12,'xixixixixix'),(13,'aiaiaiaia'),(14,'hohoahaoaooo');

全库备份与恢复操作过程

创建备份目录:

[root@Admin ~]# mkdir -p /backup/{full_data,dk_data,zl_data}

注:full_data 全库备份目录
       dk_data  单库备份目录
       zl_data   增量备份目录

全库备份(All DB)

官方备份用法说明:

$ innobackupex --defaults-file=/tmp/other-my.cnf --user=DBUSER --password=DBUSERPASS /path/to/BACKUP-DIR/

官方恢复用法说明:

用法一:$ innobackupex --apply-log /path/to/BACKUP-DIR 
用法二:$ innobackupex --apply-log --use-memory=4G /path/to/BACKUP-DIR

注:–use-memory=4G 该参数在 prepare 的时候使用,控制 prepare 时 innodb 实例使用的内存量

全库备份操作步骤:

第一步:执行备份全库命令

[root@Admin ~]# innobackupex --defaults-file=/etc/my.cnf --user=root --password=123 /backup/full_data
注:--defaults-file:默认配置文件的路径,如果不该参数,xtrabackup 将从依次从以下位置查找配置文件 /etc/my.cnf、/etc/mysql/my.cnf、/usr/local/etc/my.cnf、~/.my.cnf,并读取配置文件中的 [mysqld] 和[xtrabackup]配置段。[mysqld]中只需要指定 datadir、innodb_data_home_dir、innodb_data_file_path、innodb_log_group_home_dir、innodb_log_files_in_group、innodb_log_file_size6 个参数即可让 xtrabackup 正常工作。--user:授权的数据库用户
     --password:数据库用户的密码
     --target-dir=name 备份文件的存放目录路径(即:/backup/full_data)

第二步:恢复准备:

[root@Admin ~]# innobackupex --defaults-file=/etc/my.cnf --user=root --password=123 --apply-log /backup/full_data/2018-10-18_20-58-04

第三步:停库:

[root@Admin ~]# /etc/init.d/mysqld stop

第四步:把备份文件拷贝至原数据目录下并授权:

[root@Admin ~]# rm -rf /data/DB/*        # 把数据目录删除测试

[root@Admin ~]# cp /backup/full_data/2018-10-18_20-58-04/* /data/DB/

[root@Admin ~]# chown -R mysql. /data/DB/

第五步:重启数据库:

[root@Admin ~]# /etc/init.d/mysqld start

第六步:查看数据:

mysql> show databases;

mysql> use ceshi;

mysql> show tables;

mysql> select * from users;

单库备份与恢复操作过程

单库备份跟全库用法是一样的,只不过单库在备份里,要指定要备份的数据库名,即: –databases=LIST

单库备份操作步骤:

全量备份:

[root@Admin ~]# innobackupex --defaults-file=/etc/my.cnf --user=root --password=123 --database=ceshi /backup/dk_data
注:如果是备份从库的话,需要添加参数:--slave-info,即:[root@Admin ~]# innobackupex --defaults-file=/etc/my.cnf --user=root --password=123 --slave-info --database=ceshi /tmp

删除 ceshi 库,方便后面测试是否恢复成功:

mysql> drop database ceshi;

恢复单库操作步骤:

  • 1) 关闭数据库
    [root@Admin ~]# /etc/init.d/mysqld stop
  • 2) 恢复日志文件   apply-log
    [root@Admin ~]# innobackupex --defaults-file=/etc/my.cnf --user=root --password=123 --apply-log /backup/dk_data/2018-10-18_21-10-51
  • 3) 把备份文件拷贝至原数据目录下
    [root@Admin ~]# cp -ap /backup/dk_data/2018-10-18_21-10-51/ceshi/ /data/DB/
  • 4) 检查数据目录的所有者和权限是否正确
    [root@Admin ~]# chown -R mysql. /data/DB/
  • 5) 重启 mysql
    [root@Admin ~]# /etc/init.d/mysqld start
  • 6) 检查数据
    mysql> show databases;
    
    mysql> use ceshi;
    
    mysql> show tables;
    
    mysql> select * from users;
    
    mysql> show create table users\G

单库增量备份与恢复操作过程

单库增量备份操作步骤:

增量的备份:

  • 1)首先对单库执行一次全备
    [root@Admin ~]# innobackupex --defaults-file=/etc/my.cnf --user=root --password=123 --database=ceshi /backup/dk_data/
  • 2)插入数据
    mysql> select * from users;
    mysql> insert into users (id,name,password,address) values (4,'liu','1122',null),(5,'zou','4311','湖南长沙 '), (6,'zhou','6789',' 北京八 宝山 '), (7,'ding','7891',' 深圳西丽');
  • 3)  对单库进行增量备份
    [root@Admin ~]# innobackupex --defaults-file=/etc/my.cnf --user=root --password=123  --database=ceshi --incremental --incremental-basedir=/backup/dk_data/2018-10-18_21-33-20 /backup/zl_data
    注:--incremental 指备份类型为增量备份,做增量备份之前首先要做一次全量备份,所以 
         --incremental-basedir=/backup/dk_data/2014-05-30_23-26-22  的目录 就是 --incremental-basedir=BASEDIR  
         /backup/zl_data 就是 --incremental-basedir=INCREMENTAL-DIR-1 
         INCREMENTAL-DIR- 1 是指第一次的增量备份,INCREMENTAL-DIR- 2 是指第二次的增量备份,以此类推。

增量的恢复:

  • 1) 关闭数据库
    [root@Admin ~]# /etc/init.d/mysqld stop
  • 2) 恢复全备份日志文件(回滚未完成的日志)
    [root@Admin ~]# innobackupex --defaluts-file=/etc/my.cnf --user=root --password=123 --apply-log --redo-only /backup/dk_data/2018-10-18_21-33-20
    加选项:--apply-log-only 作用是: 只应用 redo log,不对数据的 rollback,起到先合并事务日志#
  • 3) 恢复增量备份日志文件
    [root@Admin ~]# innobackupex --defaluts-file=/etc/my.cnf --user=root --password=123 --apply-log --red-only /backup/dk_data/2018-10-18_21-33-20 --incremental-dir=/backup/zl_data/2018-10-18_22-17-33
    注:其中 BASE-DIR 是指全备目录,INCREMENTAL-DIR- 1 是指第一次的增量备份,INCREMENTAL-DIR- 2 是指第二次的增量备份,以此类推。BASE-DIR:/backup/dk_data/2014-05-30_11-56-51 
     INCREMENTAL-DIR-1:/backup/zl_data/2014-05-31_03-01-33 
     以上语句执行成功之后,最终数据在 BASE-DIR(即全备目录)下
  • 4) 恢复增量备份数据文件(拷贝数据)
    [root@Admin ~]# \cp -afp /backup/dk_data/2018-10-18_21-33-20/* /data/DB/
  • 5) 授权
    [root@Admin ~]# chown -R mysql. /data/DB/
  • 6) 启动数据库
    [root@Admin ~]# /etc/init.d/mysqld start
  • 7) 检查数据
    mysql> show databases;
    
    mysql> select * from ceshi.users;

使用 innobackupex 加 binlog 日志恢复数据到最新

创建测试数据

建库:mysql> create database db01;
建表:mysql> create table db01.t1(id int, name varchar(10)) engine=myisam;
增加数据:mysql> insert into db01.t1 values(1,'mona');

建表:mysql> create table db01.t2(id int, name varchar(10)) engine=innodb;
增加数据:mysql> insert into db01.t2 values(2,'tom');

查看当前表里的数据

mysql> select * from t1;
+------+------+
| id   | name |
+------+------+
|    1 | mona |
+------+------+
1 row in set (0.02 sec)

mysql> select * from t2;
+------+------+
| id   | name |
+------+------+
|    2 | tom  |
+------+------+
1 row in set (0.00 sec)

开启二进制日志

[root@Admin ~]# vim /etc/my.cnf
log-bin=mysql-bin

[root@Admin ~]# /etc/init.d/mysqld restart

备份操作步骤:

1、创建备份目录

[root@Admin ~]# mkdir -p /backup/innobackupex

2、使用 innobackupex 对数据库做全库备份

[root@Admin ~]# innobackupex --defaults-file=/etc/my.cnf --user=root --password=123 /backup/innobackupex/

3、数据库更新

mysql> insert into db01.t1 values(2,'jack');

mysql> insert into db01.t2 values(2,'aaa');

mysql> update db01.t1 set name='harry' where id=1;

查看数据

mysql> select * from t1;
+------+-------+
| id   | name  |
+------+-------+
|    1 | harry |
|    2 | jack  |
+------+-------+
2 rows in set (0.00 sec)

mysql> select * from t2;
+------+------+
| id   | name |
+------+------+
|    2 | tom  |
|    2 | aaa  |
+------+------+
2 rows in set (0.00 sec)

4、预备过程

[root@Admin ~]# innobackupex --apply-log /backup/innobackupex/2018-10-19_12-13-06/

5、备份二进制日志

查看备份目录里面的日志文件是从哪里开始记录的,再做相应的备份
[root@Admin ~]# cat /backup/innobackupex/2018-10-19_12-13-06/xtrabackup_binlog_info mysql-bin.000004 1119 [root@Admin ~]# mysqlbinlog --start-position=1119 /data/DB/mysql-bin.000004 > /backup/innobackupex/update.sql 这里备份只是备份改变后的数据就可以了

6、恢复演练

  • 1> 删除所有的数据文件
    [root@Admin ~]# rm -rf /data/DB/*
  • 2> 停止数据库
    [root@Admin ~]# killall -9 mysqld
  • 3> 使用 innobackupex 做恢复
    [root@Admin ~]# innobackupex --defaults-file=/etc/my.cnf --copy-back /backup/innobackupex/2018-10-19_12-13-06/
  • 4> 数据目录权限恢复
    [root@Admin ~]# chown mysql. /data/DB/ -R
  • 5> 启动数据库查并查看恢复数据
    [root@Admin ~]# /etc/init.d/mysqld start
    
    恢复后可以看见数据库里面的文件是最初始化时候的,也就是备份完成时的内容
    mysql> select * from db01.t1;
    +------+------+
    | id   | name |
    +------+------+
    |    1 | mona |
    +------+------+
    1 row in set (0.00 sec)
    
    mysql> select * from db01.t2;
    +------+------+
    | id   | name |
    +------+------+
    |    2 | tom  |
    +------+------+
    1 row in set (0.00 sec)
  • 6> 使用 binlog 日志恢复到最新状态
    可以直接在数据库里面 source 备份的日志文件(因为备份的日志文件里面是 sql 语句)mysql> source /backup/innobackupex/update.sql
    
    恢复完成后再次查看数据,可以发现已经恢复到最新状态的数据
    mysql> select * from db01.t2;
    +------+------+
    | id   | name |
    +------+------+
    |    2 | tom  |
    |    2 | aaa  |
    +------+------+
    2 rows in set (0.00 sec)
    
    mysql> select * from db01.t1;
    +------+-------+
    | id   | name  |
    +------+-------+
    |    1 | harry |
    |    2 | jack  |
    +------+-------+
    2 rows in set (0.00 sec)

     

 

正文完
星哥说事-微信公众号
post-qrcode
 
星锅
版权声明:本站原创文章,由 星锅 2022-01-28发表,共计10806字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中