天天看点

mariadb常用备份与还原工具介绍

一、备份的意义

从数据安全的角度来说,数据库服务器磁盘都会做RAID,Mariadb本身也有主从等容灾机制,但它们都无法完全取代备份。容灾和高可用能帮我们有效的应对物理的、硬件的、机械的故障,但是由我们手工操作导致的逻辑错误、系统本身内生性BUG、恶意攻击等方式破坏了你的数据却无能为力。每一种逻辑错误发生的概率都极低,但是当多种可能性叠加的时候,小概率事件就放大成很大的安全隐患,这时候备份的必要性就凸显了。

二、备份类型

1、根据备份时,数据库服务器是否在线:

冷备:cold backup

温备:warm backup

热备:hot backup

2、根据备份的数据集:

完全备份:full backup

部分备份: partial backup

3、根据备份时的接口(直接备份数据文件还是通过mysql服务器导出数据):

物理备份:直接复制(归档)数据文件的备份方式;physical backup

逻辑备份:把数据从库中提出出来保存为文本文件;logical backup

4、根据备份时是备份整个数据还是仅备份变化的数据:

增量备份:incremental backup

差异备份:differential backup

5、备份策略:

选择备份方式

选择备份时间

考虑到恢复成本

恢复时长

备份成本

锁时间

备份时长

备份负载

6、备份对象

数据

配置文件

代码:存储过程,存储函数,触发器

OS相关的配置文件,如crontab配置计划及相关的脚本,跟复制相关的配,二进制日志文件

三、常见的备份工具

mariadb本身为我们提供了mysqldump、mysqlbinlog备份工具,percona也为我们提供了强大的Xtrabackup,加上开源的mydumper,还有基于主从同步的延迟备份、从库冷备等方式,以及基于文件系统快照的备份,其实将这些方式合理搭配已经能够满足我们的需要了。而备份本身是为了恢复,所以能够让我们在出现故障后迅速、准确恢复的备份方式,就是最适合我们的,当然,同时能够省钱、省事,那就非常完美。下面就几种备份工具进行一些比较,探讨下它们各自的适用场景,及简单的使用做一下说明

1、mysqldump

⑴、mysqldump优缺点

mysqldump是最简单的逻辑备份方式(工作方式单线程)。在备份myisam表的时候,如果要得到一致的数据,就需要锁表,简单而粗暴。而在备份innodb表的时候,加上–master-data=2 –single-transaction 选项,在事务开始时刻,记录下binlog-pos点,然后利用mvcc(多版本并发控制)来获取一致的数据,由于是一个大事务,在写入和更新量很大的数据库上,将产生非常多的undo,显著影响性能,所以要慎用。

<a href="http://s3.51cto.com/wyfs02/M02/23/FC/wKioL1NJY1PwpftQAAF4qal76Cc359.jpg" target="_blank"></a>

优点:简单,可针对单表备份,在完全导出表结构的时候尤其有用。可以做到对不同的存储引擎进行备份(InnoDB热备、MyISAM温备、Aria温备)

缺点:简单粗暴,单线程,备份慢而且恢复,不支持差异或增量备份,如果要进行差异或增量备份要结合binlog日志文件

mydumper是mysqldump的加强版。相比mysqldump:

内置支持压缩,可以节省2-4倍的存储空间。

支持并行备份和恢复,因此速度比mysqldump快很多,但是由于是逻辑备份,仍不是很快,如果要进行差异或增量备份要结合binlog日志文件

部分备份工具

SELECT clause INTO OUTFILE '/path/to/somefile'

LOAD DATA INFILE '/path/from/somefile'

不会备份关系定义,仅备份表中的数据;

逻辑备份工具,快于mysqldump。

⑵、mysqldump命令介绍及简单使用

①命令介绍

mysqldump [options] [db_name [tbl_name ...]]

备份单个库:

mysqldump [options] db_name

恢复时:如果目标库不存在,需要事先手动创建

options说明

--all-databases: 备份所有库

--databases db1 db2 ...: 备份指定的多个库

注意:备份前要加锁

--lock-all-tables:请求锁定所有表之后再备份,对MyISAM、InnoDB、Aria做温备

--single-transaction: 能够对InnoDB存储引擎实现热备;

备份代码:

--events: 备份事件调度器代码

--routines: 备份存储过程和存储函数

--triggers:备份触发器

备份时滚动日志:

--flush-logs: 备份前、请求到锁之后滚动日志;

复制时的同步位置标记:

--master-data=[0|1|2]

0: 不记录

1:记录为CHANGE MASTER语句

2:记录为注释的CHANGE MASTER语句

注意

使用mysqldump备份

请求锁:--lock-all-tables或使用--singe-transaction进行innodb热备;

滚动日志:--flush-logs

选定要备份的库:--databases

记录二进制日志文件及位置:--master-data=

恢复

建议:关闭二进制日志,关闭其它用户连接;

建议备份策略:基于mysqldump

备份部分

mysqldump+二进制日志文件;

完全备份+各二进制日志文件中至此刻的事件,对MySQL配置文件,以及与MySQL相关的OS配置文件在每次修改后都应该直接进行备份;

②、实例

要求如下:

备份所有数据库,要每周日凌晨自动执行;

③解决方案(此方法不唯一)

备份阶段

第一步,先远程登录到数据库上,事先看一下现有的数据库。

<a href="http://s3.51cto.com/wyfs02/M01/23/FC/wKiom1NJaHbjzl5BAAH03wdWkVI320.jpg" target="_blank"></a>

由上图可见,除了hellodb数据库,其它的数据库都是系统自带的,看一下hellodb中有那些表,及当前binlog日志的记录的位置。

<a href="http://s3.51cto.com/wyfs02/M01/24/2C/wKioL1NL446AziAXAAIAEWNmgcs930.jpg" target="_blank"></a>

由于当前数据库只有一个用户数据库,所以我们在乎其表的存储引擎来判断使用什么方式来备份。(是申请锁或是单事务)

<a href="http://s3.51cto.com/wyfs02/M00/23/FD/wKioL1NJaebTRB0wAAN7xg3NH6I301.jpg" target="_blank"></a>

查看表状态发现hellodb中的表全部都是MyISAM的存储引擎,那么就可以使用申请全局锁来备份了。

1

<code># mysqldump -uroot -p </code><code>--all-databases --lock-all-tables --flush-logs --master-data=2 &gt;/tmp/all.sql</code>

<a href="http://s3.51cto.com/wyfs02/M01/23/FC/wKiom1NJa7aiKc0oAAEZ8d6UEkE727.jpg" target="_blank"></a>

这时数据库全部备份完毕(此方法只适用于数据量不是很大,挑选一个相对并发的写请求不是特别多的时间或午夜备份。如果数据量特别大,此方法将不做参考范围)。

假如在这之后我们又在原来的库中建立新的表或插入数据,而在某一次我误操作删除了此数据库。将如何恢复?

<a href="http://s3.51cto.com/wyfs02/M02/24/2C/wKiom1NL5PvhDZJ6AAEIzh4vRzk068.jpg" target="_blank"></a>

由上图可见,原来的hellodb数据库中多了一张表,为不演示恢复效果我将hellodb删除,看怎么样恢复

<a href="http://s3.51cto.com/wyfs02/M00/24/2C/wKioL1NL5XuCCG1mAAE_TpkyEQM706.jpg" target="_blank"></a>

现在hellodb己经删除,看如何恢复。

恢复部分

第一步,将服务器离线,导出现在正在使用的binlog日志,还原之前的完全备份

查看完全备份中binlog日志的起始位置。

2

<code>#vim /tmp/all.sql</code>

<code>-- CHANGE MASTER TO MASTER_LOG_FILE=</code><code>'mysql-bin.000002'</code><code>, MASTER_LOG_POS=365;</code>

将此日志中到删除数据库drop database hellodb之前的数据导出到存放起来,以供时间点还原之用

<code># mysqlbinlog --start-position=365 --stop-position=863  mysql-bin.000002 &gt;/tmp/binlogbakup.sql</code>

登录数据库

3

4

5

6

7

<code>[root@localhost bin]# mysql</code>

<code>Welcome </code><code>to</code> <code>the MariaDB monitor.  Commands </code><code>end</code> <code>with</code> <code>; </code><code>or</code> <code>\g.</code>

<code>Your MariaDB </code><code>connection</code> <code>id </code><code>is</code> <code>4</code>

<code>Server version: 10.0.10-MariaDB-log Source distribution</code>

<code>Copyright (c) 2000, 2014, Oracle, SkySQL Ab </code><code>and</code> <code>others.</code>

<code>Type </code><code>'help;'</code> <code>or</code> <code>'\h'</code> <code>for</code> <code>help. Type </code><code>'\c'</code> <code>to</code> <code>clear the </code><code>current</code> <code>input statement.</code>

<code>MariaDB [(none)]&gt;</code>

注:此时要临时关闭二进制日志,关闭其它用户连接;

<code>MariaDB [(none)]&gt; </code><code>set</code> <code>session sql_log_bin=0;</code>

<code>Query OK, 0 </code><code>rows</code> <code>affected (0.00 sec)</code>

导入之前的备份 

<code>MariaDB [(none)]&gt; source /tmp/</code><code>all</code><code>.sql</code>

查看数据库中的表,里面没有我们备份之后建立的表,这时就用到了之前备份的binlog日志了

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

<code>MariaDB [test]&gt; show databases;</code>

<code>+</code><code>--------------------+</code>

<code>| </code><code>Database</code>           <code>|</code>

<code>| hellodb            |</code>

<code>| information_schema |</code>

<code>| mysql              |</code>

<code>| performance_schema |</code>

<code>| test               |</code>

<code>5 </code><code>rows</code> <code>in</code> <code>set</code> <code>(0.05 sec)</code>

<code>MariaDB [test]&gt; use hellodb</code>

<code>Database</code> <code>changed</code>

<code>MariaDB [hellodb]&gt; show tables;</code>

<code>+</code><code>-------------------+</code>

<code>| Tables_in_hellodb |</code>

<code>| classes           |</code>

<code>| coc               |</code>

<code>| courses           |</code>

<code>| scores            |</code>

<code>| students          |</code>

<code>| teachers          |</code>

<code>| toc               |</code>

<code>7 </code><code>rows</code> <code>in</code> <code>set</code> <code>(0.00 sec)</code>

导入binlog日志,完全恢复数据。

<code>MariaDB [hellodb]&gt; source /tmp/binlogbakup.sql</code>

<code>| addressbook       |</code>

<code>8 </code><code>rows</code> <code>in</code> <code>set</code> <code>(0.00 sec)</code>

<code>MariaDB [hellodb]&gt; </code><code>select</code> <code>* </code><code>from</code> <code>addressbook;</code>

<code>+</code><code>--------+---------+----------+----------+-----------------+</code>

<code>| fname  | lname   | phone    | fax      | email           |</code>

<code>| France | D'Souza | 123 4567 | 000 7574 | fdz@</code><code>some</code><code>.domain |</code>

<code>1 row </code><code>in</code> <code>set</code> <code>(0.01 sec)</code>

这回数据就完整了。

附上一个基于mysqldump简单复制单库的myisam的脚本

<code>#!/bin/sh</code>

<code>###############################</code>

<code>#此脚本用来单库完全份</code>

<code>#每个星期日做一次完全备份</code>

<code>#设置用户名和密码</code>

<code>v_user=</code><code>"root"</code>

<code>v_password=</code><code>"mysql"</code>

<code>#mysql安装可执行程序所在位置</code>

<code>MysqlDir=</code><code>/usr/local/mari/bin</code>

<code>#备份数据库</code>

<code>database=</code><code>"hellodb"</code>

<code>#设置备份路径,创建备份文件夹</code>

<code>BackupDir=</code><code>/maria_bak</code>

<code>Full_Backup=$BackupDir</code><code>/Full_backup</code>

<code>mkdir</code> <code>-p $Full_Backup/$(</code><code>date</code> <code>+%Y%m%d)</code>

<code>#开始备份,记录备份开始时间</code>

<code>echo</code> <code>'###'</code><code>$(</code><code>date</code> <code>+</code><code>"%Y-%m-%d %H:%M:%S"</code><code>)</code><code>'###'</code><code>"备份开始"</code><code>&gt;&gt;$Full_Backup</code><code>/full_buckup</code><code>.log</code>

<code>$MysqlDir</code><code>/mysqldump</code> <code>-u$v_user -p$v_password --lock-all-tables --flush-logs --master-data=2 --databases $database&gt;$Full_Backup/$(</code><code>date</code> <code>+%Y%m%d)</code><code>/full_backup</code><code>.sql</code>

<code>#压缩备份文件</code>

<code>gzip</code> <code>$Full_Backup/$(</code><code>date</code> <code>+%Y%m%d)</code><code>/full_backup</code><code>.sql</code>

<code>echo</code> <code>'###'</code><code>$(</code><code>date</code> <code>+</code><code>"%Y-%m-%d %H:%M:%S"</code><code>)</code><code>'###'</code><code>"备份完成"</code><code>&gt;&gt;$Full_Backup</code><code>/full_buckup</code><code>.log</code>

2. 基于文件系统的快照

基于文件系统的快照,是物理备份的一种。在备份前需要进行一些复杂的设置,在备份开始时刻获得快照并记录下binlog pos点,然后采用类似copy-on-write的方式,把快照进行转储。转储快照本身会消耗一定的IO资源,而且在写入压力较大的实例上,保存被更改数据块的前印象也会消耗IO,最终表现为整体性能的下降。而且服务器还要为copy-on-write快照预留较多的磁盘空间,这本身对资源也是一种浪费。因此这种备份方式在生产环境使用的不多。

<a href="http://s3.51cto.com/wyfs02/M00/24/2D/wKiom1NL92TRAaKAAAEyVtHhHes360.jpg" target="_blank"></a>

注:

当刚为数数据文件所在的卷(源卷)创建快照时,此时的快照卷是空的。

当源卷中的数据发生变化后,则将发生变化的那部分数据复制到快照卷上,此时通过快照访问则是未发生变化的数据来自于源卷,变化后的数据来自于快照卷。

快照不是备份,它是仅是提供访问文件的一条通路,当源卷变化的量超出快照卷的大小时,快照卷将崩溃失效。

实例

前提:

首先,mariadb的数据文件在逻辑卷上,如果使用的是支持事务的存储引擎的话,那么要将事务日志与数据文件放在同一个卷上,这样才能保证数据的完整性。

看一下数据文件的属性

<a href="http://s3.51cto.com/wyfs02/M02/24/69/wKiom1NOgaDwFpRzAAJ8Ukod_iQ470.jpg" target="_blank"></a>

步骤:

第一步,如果对源卷创建快照,那么首先要对数据库申请全局锁,滚动二进制日志,记录二进制日志位置标记

⑴、申请全局锁

<code>MariaDB [(none)]&gt; flush tables </code><code>with</code> <code>read</code> <code>lock;</code>

<code>MariaDB [(none)]&gt; flush logs;</code>

<code>Query OK, 0 </code><code>rows</code> <code>affected (0.02 sec)</code>

<code>MariaDB [(none)]&gt; show master status;</code>

<code>+</code><code>------------------+----------+--------------+------------------+</code>

<code>| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |</code>

<code>| mysql-bin.000012 |      365 |              |                  |</code>

<code>1 row </code><code>in</code> <code>set</code> <code>(0.02 sec)</code>

将此二进制日志信息记录下来

<code># mysql -e 'show master status;'&gt;/maribak/binlog_pos/binlog_$(date +%F_%T).txt</code>

<code># cat /maribak/binlog_pos/binlog_2014-04-14_04\:17\:13.txt</code>

<code>File    Position    Binlog_Do_DB    Binlog_Ignore_DB</code>

<code>mysql-bin.000012    365</code>

此时可以创建快照了

<code># lvcreate -L 200M -s -n databak_snap -p r /dev/mydata/lv1</code>

<code>  </code><code>Logical volume </code><code>"databak_snap"</code> <code>created</code>

第二步,创建完快照后解锁

当快照卷创建完成后,可以对数据库解锁(创建锁与解锁必须是同一会话,也就是说,当创建完锁之后,这个会话不可退出,之后还要在这个会话中对数据库解锁,一但退出,此会话的全局锁将失效)

<code>MariaDB [(none)]&gt; unlock tables;</code>

<code>Query OK, 0 rowsaffected (0.00 sec)</code>

这时数据库又可以正常进行写入操作了

第三步,备份快照

挂载备份之后的快照

<code>[root@bogon mnt]</code><code># mount /dev/mydata/databak_snap  -o ro /mnt</code>

<code>[root@bogon mnt]</code><code># cd /mnt</code>

<code>[root@bogon mnt]</code><code># ll</code>

<code>total 176172</code>

<code>-rw-rw---- 1 mysql mysql    16384 Apr 14 04:11 aria_log.00000001</code>

<code>-rw-rw---- 1 mysql mysql       52 Apr 14 04:11 aria_log_control</code>

<code>-rw-r----- 1 mysql root      1099 Apr 14 04:11 bogon.err</code>

<code>-rw-rw---- 1 mysql mysql        5 Apr 14 04:11 bogon.pid</code>

<code>drwx------ 2 mysql mysql     4096 Apr 14 04:12 employees</code>

<code>-rw-rw---- 1 mysql mysql 79691776 Apr 14 04:14 ibdata1</code>

<code>-rw-rw---- 1 mysql mysql 50331648 Apr 14 04:14 ib_logfile0</code>

<code>-rw-rw---- 1 mysql mysql 50331648 Apr 14 04:14 ib_logfile1</code>

<code>-rw-rw---- 1 mysql mysql        0 Apr 14 04:11 multi-master.info</code>

<code>drwx------ 2 mysql root      4096 Apr 14 04:11 mysql</code>

<code>drwx------ 2 mysql mysql     4096 Apr 14 04:11 performance_schema</code>

<code>drwx------ 2 mysql root      4096 Apr 14 04:11 </code><code>test</code>

复制快照中的内容

<code>[root@bogon mnt]</code><code>#  cp -a * /maribak/databak/</code>

<code>[root@bogon mnt]</code><code># cd /maribak/databak/</code>

<code>[root@bogon databak]</code><code># ll</code>

删除快照卷

<code>#lvremove /dev/mydata/databak_snap</code>

里源卷的数据库employees中添入一些数据。

<code>MariaDB [employees]&gt; </code><code>insert</code> <code>employees </code><code>values</code><code>(99,</code><code>'1998-09-21'</code><code>,</code><code>'JEYY'</code><code>,</code><code>'jose'</code><code>,</code><code>'M'</code><code>,</code><code>'2012-12-24'</code><code>);</code>

<code>MariaDB [employees]&gt; </code><code>insert</code> <code>employees </code><code>values</code><code>(999999,</code><code>'1995-09-21'</code><code>,</code><code>'king'</code><code>,</code><code>'tom'</code><code>,</code><code>'M'</code><code>,</code><code>'2012-12-24'</code><code>);</code>

<code>MariaDB [employees]&gt;</code><code>insert</code> <code>employees </code><code>values</code><code>(5211345,</code><code>'1995-09-21'</code><code>,</code><code>'king'</code><code>,</code><code>'tom'</code><code>,</code><code>'F'</code><code>,</code><code>'2012-12-24'</code><code>);</code>

当备份过完成后,过了几个小时,数据库误删除了一些数据,这时就可用到此次完全备份与即时点还原日志。

<code>MariaDB [employees]&gt; </code><code>delete</code>  <code>from</code> <code>employees  </code><code>where</code> <code>gender=</code><code>'M'</code>

<code>    </code><code>-&gt; ;</code>

<code>Query OK, 179975 </code><code>rows</code> <code>affected (3 </code><code>min</code> <code>52.82 sec)</code>

还原部分

第一步,停止数据库服务,将备份后的数据中的某一张表或整个库替换此数据库中误删除的表或整个库。

<code>[root@bogon employees]</code><code># service mari stop</code>

<code>Shutting down MySQL...............                         [  OK  ]</code>

替换 

<code>[root@bogon employees]</code><code># cp -a /maribak/databak/employees/employees.* .</code>

<code>cp</code><code>: overwrite `.</code><code>/employees</code><code>.frm'? y</code>

<code>cp</code><code>: overwrite `.</code><code>/employees</code><code>.ibd'? y</code>

<code>[root@bogon employees]</code><code># ll</code>

<code>total 237840</code>

<code>-rw-rw---- 1 mysql mysql        61 Apr 14 04:12 db.opt</code>

<code>-rw-rw---- 1 mysql mysql      1571 Apr 14 04:12 departments.frm</code>

<code>-rw-rw---- 1 mysql mysql    114688 Apr 14 04:12 departments.ibd</code>

<code>-rw-rw---- 1 mysql mysql      1999 Apr 14 04:12 dept_emp.frm</code>

<code>-rw-rw---- 1 mysql mysql  31457280 Apr 14 05:03 dept_emp.ibd</code>

<code>-rw-rw---- 1 mysql mysql      1999 Apr 14 04:12 dept_manager.frm</code>

<code>-rw-rw---- 1 mysql mysql    131072 Apr 14 04:55 dept_manager.ibd</code>

<code>-rw-rw---- 1 mysql mysql      1164 Apr 14 04:12 employees.frm</code>

<code>-rw-rw---- 1 mysql mysql  23068672 Apr 14 04:12 employees.ibd</code>

<code>-rw-rw---- 1 mysql mysql      1501 Apr 14 04:12 salaries.frm</code>

<code>-rw-rw---- 1 mysql mysql 146800640 Apr 14 05:03 salaries.ibd</code>

<code>-rw-rw---- 1 mysql mysql      1647 Apr 14 04:12 titles.frm</code>

<code>-rw-rw---- 1 mysql mysql  41943040 Apr 14 05:03 titles.ibd</code>

注:此时文件的属性要与原文件的一致

第二步,启动服务

<code>[root@bogon employees]</code><code># service mari start</code>

<code>Starting MySQL..                                           [  OK  ]</code>

查看完全备份信息

<code>MariaDB [employees]&gt; </code><code>select</code> <code>* </code><code>from</code> <code>employees </code><code>where</code> <code>hire_date &gt;</code><code>'2000-01-01'</code><code>;</code>

<code>+</code><code>--------+------------+------------+------------+--------+------------+</code>

<code>| emp_no | birth_date | first_name | last_name  | gender | hire_date  |</code>

<code>|  47291 | 1960-09-09 | Ulf        | Flexer     | M      | 2000-01-12 |</code>

<code>|  60134 | 1964-04-21 | Seshu      | Rathonyi   | F      | 2000-01-02 |</code>

<code>|  72329 | 1953-02-09 | Randi      | Luit       | F      | 2000-01-02 |</code>

<code>| 205048 | 1960-09-12 | Ennio      | Alblas     | F      | 2000-01-06 |</code>

<code>| 222965 | 1959-08-07 | Volkmar    | Perko      | F      | 2000-01-13 |</code>

<code>| 226633 | 1958-06-10 | Xuejun     | Benzmuller | F      | 2000-01-04 |</code>

<code>| 227544 | 1954-11-17 | Shahab     | Demeyer    | M      | 2000-01-08 |</code>

<code>| 422990 | 1953-04-09 | Jaana      | Verspoor   | F      | 2000-01-11 |</code>

<code>| 424445 | 1953-04-27 | Jeong      | Boreale    | M      | 2000-01-03 |</code>

<code>| 428377 | 1957-05-09 | Yucai      | Gerlach    | M      | 2000-01-23 |</code>

<code>| 463807 | 1964-06-12 | Bikash     | Covnot     | M      | 2000-01-28 |</code>

<code>| 499553 | 1954-05-06 | Hideyuki   | Delgrande  | F      | 2000-01-22 |</code>

并没有备份后插入的数据,所以在用到binlog日志了,查看当前的binlog的位置

<code>MariaDB [employees]&gt; show master status;</code>

<code>| mysql-bin.000013 |      326 |              |                  |</code>

<code>1 row </code><code>in</code> <code>set</code> <code>(0.00 sec)</code>

跨文件了~~~,没关系统,先还原同一个日志文件中的数据,再恢复这个日志中的数据,在mysql-bin.000012中找到delect之前的位置,并使用mysqlbinlog将其导出,临时性关闭binlog日志功能,恢复此间数据。

<code># mysqlbinlog /mysql/binlog/mysql-bin.000012</code>

<code>..........省略中........</code>

<code># at 1108</code>

<code>#140414  4:53:25 server id 1  end_log_pos 1146  GTID 0-1-7138</code>

<code>/*!100001 SET @@session.gtid_seq_no=7138*</code><code>//</code><code>*!*/;</code>

<code>BEGIN</code>

<code>/*!*/;</code>

<code># at 1146</code>

<code>#140414  4:53:25 server id 1  end_log_pos 1254  Query   thread_id=6 exec_time=233   error_code=0</code>

<code>SET TIMESTAMP=1397422405/*!*/;</code>

<code>delete  from employees  where gender=</code><code>'M'</code>

从日志中看标识到1108即可恢复到删除之前,将此区间导出

<code>[root@bogon binlog_pos]</code><code># mysqlbinlog --start-position=365 --stop-position=1108 /mysql/binlog/mysql-bin.000012 &gt;zengliang.sql</code>

<code>[root@bogon binlog_pos]</code><code># ls</code>

<code>binlog_2014-04-14_04:17:13.txt  zengliang.sql</code>

在数据中临时关闭binlog日志功能。

<code>MariaDB [employees]&gt; </code><code>set</code> <code>session sql_log_bin=0;</code>

<code>Query OK, 0 </code><code>rows</code> <code>affected (0.01 sec)</code>

<code>MariaDB [employees]&gt; source /maribak/binlog_pos/zengliang.sql;</code>

查看一下原来的数据

<code>+</code><code>---------+------------+------------+------------+--------+------------+</code>

<code>| emp_no  | birth_date | first_name | last_name  | gender | hire_date  |</code>

<code>|      99 | 1998-09-21 | JEYY       | jose       | M      | 2012-12-24 |</code>

<code>|   47291 | 1960-09-09 | Ulf        | Flexer     | M      | 2000-01-12 |</code>

<code>|   60134 | 1964-04-21 | Seshu      | Rathonyi   | F      | 2000-01-02 |</code>

<code>|   72329 | 1953-02-09 | Randi      | Luit       | F      | 2000-01-02 |</code>

<code>|  205048 | 1960-09-12 | Ennio      | Alblas     | F      | 2000-01-06 |</code>

<code>|  222965 | 1959-08-07 | Volkmar    | Perko      | F      | 2000-01-13 |</code>

<code>|  226633 | 1958-06-10 | Xuejun     | Benzmuller | F      | 2000-01-04 |</code>

<code>|  227544 | 1954-11-17 | Shahab     | Demeyer    | M      | 2000-01-08 |</code>

<code>|  422990 | 1953-04-09 | Jaana      | Verspoor   | F      | 2000-01-11 |</code>

<code>|  424445 | 1953-04-27 | Jeong      | Boreale    | M      | 2000-01-03 |</code>

<code>|  428377 | 1957-05-09 | Yucai      | Gerlach    | M      | 2000-01-23 |</code>

<code>|  463807 | 1964-06-12 | Bikash     | Covnot     | M      | 2000-01-28 |</code>

<code>|  499553 | 1954-05-06 | Hideyuki   | Delgrande  | F      | 2000-01-22 |</code>

<code>|  999999 | 1995-09-21 | king       | tom        | M      | 2012-12-24 |</code>

<code>| 5211345 | 1995-09-21 | king       | tom        | F      | 2012-12-24 |</code>

<code>15 </code><code>rows</code> <code>in</code> <code>set</code> <code>(0.31 sec)</code>

全部都回来了,退出会话,再次登录后,binlog日志将开始记录了。(以上操作,均要在 设置了skip-networking的情况下操作,完全恢复后,在配置文件中[mysqld]中将skip-networking注释掉,记得再来一次完全备份后,mariadb又可重新工作了)

3. Xtrabackup

⑴、简介

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

备份过程快速、可靠;

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

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

自动实现备份检验;

还原速度快;

⑵、安装

其最新版的软件可从 http://www.percona.com/software/percona-xtrabackup/ 获得

⑶、原理说明

它的工作原理如下:

<a href="http://s3.51cto.com/wyfs02/M01/24/6A/wKiom1NOrx6DxnjfAAGL2YqCTtk029.jpg" target="_blank"></a>

由于mysql中不可避免的含有myisam表,同时innobackup并不备份表结构等文件,因此想要完整的备份mysql实例,就少不了要执行flush tables with read lock,而这个语句会被任何查询(包括select)阻塞,在阻塞过程中,它又反过来阻塞任何查询(包括select)。如果碰巧备份实例上有长查询先于flush tables with read lock执行,数据库就会hang住。而当flush tables with read lock获得全局锁后,虽然查询可以执行,但是仍会阻塞更新,所以,我们希望flush tables with read lock从发起到结束,持续的时间越短越好。

⑷、实例:

利用Xtrabackup实现完全与增量备份

步骤

前提

授权一个仅可以备份操作的用户

<code>MariaDB [(none)]&gt; </code><code>grant</code> <code>reload,lock tables,replication client </code><code>on</code> <code>*.* </code><code>to</code> <code>'bakupuser'</code><code>@</code><code>'localhost'</code> <code>identified </code><code>by</code> <code>'bakuppass'</code><code>;</code>

<code>Query OK, 0 </code><code>rows</code> <code>affected (1.34 sec)</code>

①、完全备份

命令格式:

<code># innobackupex --user=DBUSER --password=DBUSERPASS  /path/to/BACKUP-DIR/</code>

说明:

使用innobakupex备份时,其会调用xtrabackup备份所有的InnoDB表,复制所有关于表结构定义的相关文件(.frm)、以及MyISAM、MERGE、CSV和ARCHIVE表的相关文件,同时还会备份触发器和数据库配置信息相关的文件。这些文件会被保存至一个以时间命令的目录中。

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

xtrabackup_checkpoints —— 备份类型(如完全或增量)、备份状态(如是否已经为prepared状态)和LSN(日志序列号)范围信息;每个InnoDB页(通常为16k大小)都会包含一个日志序列号,即LSN。LSN是整个数据库系统的系统版本号,每个页面相关的LSN能够表明此页面最近是如何发生改变的。xtrabackup_binlog_info —— mysql服务器当前正在使用的二进制日志文件及至备份这一刻为止二进制日志事件的位置。

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

xtrabackup_binary —— 备份中用到的xtrabackup的可执行文件;

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

在使用innobackupex进行备份时,还可以使用--no-timestamp选项来阻止命令自动创建一个以时间命名的目录;如此一来,innobackupex命令将会创建一个BACKUP-DIR目录来存储备份数据。

====================================正式开始=====================================

完全备份部分

对当前的mariadb数据库做一次完备份

<code>MariaDB [(none)]&gt; show databases;</code>

<code>| employees          |</code>

<code>5 </code><code>rows</code> <code>in</code> <code>set</code> <code>(0.07 sec)</code>

<code># innobackupex --user=bakupuser --password=bakuppass --host=localhost /maribak/</code>

<code>………………过程信息……………………</code>

<code>innobackupex: Backup created </code><code>in</code> <code>directory </code><code>'/maribak/2014-04-14_07-17-33'</code>

<code>innobackupex: MySQL binlog position: filename </code><code>'mysql-bin.000013'</code><code>, position 542</code>

<code>140414 07:17:57  innobackupex: Connection to database server closed</code>

<code>140414 07:17:57  innobackupex: completed OK!</code>

最后显示的信息:

备份的位置(以时间命令的目录下)

binlog日志的当前位置

备份的状态

看一下备份目录中的文件

27

28

29

30

31

32

33

34

35

36

37

<code># ll</code>

<code>total 208932</code>

<code>-rw-r--r-- 1 root root       357 Apr 14 07:17 backup-my.cnf</code>

<code>drwx------ 2 root root      4096 Apr 14 07:17 employees</code>

<code>-rw-r----- 1 root root 213909504 Apr 14 07:17 ibdata1</code>

<code>drwx------ 2 root root      4096 Apr 14 07:17 mysql</code>

<code>drwxr-xr-x 2 root root      4096 Apr 14 07:17 performance_schema</code>

<code>drwxr-xr-x 2 root root      4096 Apr 14 07:17 </code><code>test</code>

<code>-rw-r--r-- 1 root root        13 Apr 14 07:17 xtrabackup_binary</code>

<code>-rw-r--r-- 1 root root        23 Apr 14 07:17 xtrabackup_binlog_info</code>

<code>-rw-r----- 1 root root        93 Apr 14 07:17 xtrabackup_checkpoints</code>

<code>-rw-r----- 1 root root      2560 Apr 14 07:17 xtrabackup_logfile</code>

<code># cat backup-my.cnf #备份命令用到的配置选项信息</code>

<code># This MySQL options file was generated by innobackupex.</code>

<code># The MySQL server</code>

<code>[mysqld]</code>

<code>innodb_checksum_algorithm=innodb</code>

<code>innodb_log_checksum_algorithm=innodb</code>

<code>innodb_data_file_path=ibdata1:10M:autoextend</code>

<code>innodb_log_files_in_group=2</code>

<code>innodb_log_file_size=50331648</code>

<code>innodb_fast_checksum=0</code>

<code>innodb_page_size=16384</code>

<code>innodb_log_block_size=512</code>

<code>innodb_undo_tablespaces=0</code>

<code>[root@bogon 2014-04-14_07-17-33]</code><code># cat xtrabackup_binary</code>

<code>xtrabackup_56</code>

<code>#xtrabackup版本信息</code>

<code>[root@bogon 2014-04-14_07-17-33]</code><code># cat xtrabackup_binlog_info</code>

<code>mysql-bin.000013    542</code>

<code>#binlog日志位置及标记</code>

<code>[root@bogon 2014-04-14_07-17-33]</code><code># cat xtrabackup_checkpoints</code>

<code>backup_type = full-backuped  </code><code>#备份的类型(默认为完全备份)</code>

<code>from_lsn = 0    </code><code>#日志序列号(数据文件的LSN存储在数据文件的第1个页面,即ID为0的页面的头部,是整个文件的LSN。)</code>

<code>to_lsn = 885197721 </code><code>#到那一个日志序列号</code>

<code>last_lsn = 885197721 </code><code>#最后一个日志序列号(指的是结束位置在那里)</code>

<code>compact = 0</code>

==========================================到此完全备份完成==============================

为了演示效果我会将数据目录清空。

<code>[root@bogon maribak]</code><code># cd /mariadb/data</code>

<code>[root@bogon data]</code><code># ll</code>

<code>total 307248</code>

<code>-rw-rw---- 1 mysql mysql     16384 Apr 14 05:03 aria_log.00000001</code>

<code>-rw-rw---- 1 mysql mysql        52 Apr 14 05:03 aria_log_control</code>

<code>-rw-r----- 1 mysql root       2680 Apr 14 05:12 bogon.err</code>

<code>-rw-rw---- 1 mysql mysql         5 Apr 14 05:12 bogon.pid</code>

<code>drwx------ 2 mysql mysql      4096 Apr 14 04:12 employees</code>

<code>-rw-rw---- 1 mysql mysql 213909504 Apr 14 05:37 ibdata1</code>

<code>-rw-rw---- 1 mysql mysql  50331648 Apr 14 05:37 ib_logfile0</code>

<code>-rw-rw---- 1 mysql mysql  50331648 Apr 14 05:37 ib_logfile1</code>

<code>-rw-rw---- 1 mysql mysql         0 Apr 14 04:11 multi-master.info</code>

<code>drwx------ 2 mysql root       4096 Apr 14 04:11 mysql</code>

<code>drwx------ 2 mysql mysql      4096 Apr 14 04:11 performance_schema</code>

<code>drwx------ 2 mysql root       4096 Apr 14 04:11 </code><code>test</code>

<code>[root@bogon data]</code><code># rm -rf *</code>

<code>[root@bogon data]</code><code># pwd</code>

<code>/mariadb/data</code>

<code>[root@bogon data]</code><code># ls</code>

<code>[root@bogon data]</code><code>#</code>

完全恢复部分

准备(prepare)一个完全备份

一般情况下,在备份完成后,数据尚且不能用于恢复操作,因为备份的数据中可能会包含尚未提交的事务或已经提交但尚未同步至数据文件中的事务。因此,此时数据文件仍处理不一致状态。“准备”的主要作用正是通过回滚未提交的事务及同步已经提交的事务至数据文件也使得数据文件处于一致性状态。

命令说明:

<code># innobackupex --apply-log  /path/to/BACKUP-DIR</code>

innobakupex命令的--apply-log选项可用于实现上述功能

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

============================================正式开始====================================

准备工作开始

<code># innobackupex --apply-log /maribak/2014-04-14_07-17-33</code>

<code>[notice (again)]</code>

<code>  </code><code>If you use binary log and don't use any hack of group commit,</code>

<code>  </code><code>the binary log position seems to be:</code>

<code>InnoDB: Last MySQL binlog </code><code>file</code> <code>position 0 1281, </code><code>file</code> <code>name </code><code>/mysql/binlog/mysql-bin</code><code>.000012</code>

<code>xtrabackup: starting </code><code>shutdown</code> <code>with innodb_fast_shutdown = 1</code>

<code>InnoDB: FTS optimize thread exiting.</code>

<code>InnoDB: Starting </code><code>shutdown</code><code>...</code>

<code>InnoDB: Shutdown completed; log sequence number 885203607</code>

<code>140414 07:46:45  innobackupex: completed OK!</code>

==================================准备工作完成=================================

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

恢复不用启动MySQL

<code># innobackupex --copy-back  /path/to/BACKUP-DIR</code>

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

<code># innobackupex --copy-back /maribak/2014-04-14_07-17-33</code>

<code>innobackupex: Starting to copy InnoDB log files</code>

<code>innobackupex: </code><code>in</code> <code>'/maribak/2014-04-14_07-17-33'</code>

<code>innobackupex: back to original InnoDB log directory </code><code>'/mariadb/data'</code>

<code>innobackupex: Copying </code><code>'/maribak/2014-04-14_07-17-33/ib_logfile0'</code> <code>to </code><code>'/mariadb/data/ib_logfile0'</code>

<code>innobackupex: Copying </code><code>'/maribak/2014-04-14_07-17-33/ib_logfile1'</code> <code>to </code><code>'/mariadb/data/ib_logfile1'</code>

<code>innobackupex: Finished copying back files.</code>

<code>140414 07:57:48  innobackupex: completed OK!</code>

如果出现ok表示恢复完毕了。

回到数据目录下看一下文件的属性,确保文件的所有属性都是正确的用户,并可以以身份来访问与运行,如果不是,请修改其文件属性

<code>total 307244</code>

<code>-rw-rw---- 1 mysql mysql     16384 Apr 14 07:59 aria_log.00000001</code>

<code>-rw-rw---- 1 mysql mysql        52 Apr 14 07:59 aria_log_control</code>

<code>-rw-r----- 1 mysql root       1044 Apr 14 07:59 bogon.err</code>

<code>drwxr-xr-x 2 root  root       4096 Apr 14 07:57 employees</code>

<code>-rw-r--r-- 1 root  root  213909504 Apr 14 07:57 ibdata1</code>

<code>-rw-r--r-- 1 root  root   50331648 Apr 14 07:57 ib_logfile0</code>

<code>-rw-r--r-- 1 root  root   50331648 Apr 14 07:57 ib_logfile1</code>

<code>drwxr-xr-x 2 root  root       4096 Apr 14 07:57 mysql</code>

<code>drwxr-xr-x 2 root  root       4096 Apr 14 07:57 performance_schema</code>

<code>drwxr-xr-x 2 root  root       4096 Apr 14 07:57 </code><code>test</code>

<code>-rw-r--r-- 1 root  root         36 Apr 14 07:57 xtrabackup_binlog_pos_innodb</code>

<code>[root@bogon data]</code><code># chown -R mysql.mysql *</code>

<code>-rw-r----- 1 mysql mysql      1044 Apr 14 07:59 bogon.err</code>

<code>drwxr-xr-x 2 mysql mysql      4096 Apr 14 07:57 employees</code>

<code>-rw-r--r-- 1 mysql mysql 213909504 Apr 14 07:57 ibdata1</code>

<code>-rw-r--r-- 1 mysql mysql  50331648 Apr 14 07:57 ib_logfile0</code>

<code>-rw-r--r-- 1 mysql mysql  50331648 Apr 14 07:57 ib_logfile1</code>

<code>drwxr-xr-x 2 mysql mysql      4096 Apr 14 07:57 mysql</code>

<code>drwxr-xr-x 2 mysql mysql      4096 Apr 14 07:57 performance_schema</code>

<code>drwxr-xr-x 2 mysql mysql      4096 Apr 14 07:57 </code><code>test</code>

<code>-rw-r--r-- 1 mysql mysql        36 Apr 14 07:57 xtrabackup_binlog_pos_innodb</code>

启动mariadb

<code>]# mysql</code>

<code>5 </code><code>rows</code> <code>in</code> <code>set</code> <code>(0.37 sec)</code>

<code>MariaDB [(none)]&gt; use employees</code>

<code>MariaDB [employees]&gt; </code><code>select</code> <code>* </code><code>from</code> <code>employees </code><code>where</code> <code>hire_date &gt;</code><code>'2001-01-01'</code><code>;</code>

<code>+</code><code>---------+------------+------------+-----------+--------+------------+</code>

<code>| emp_no  | birth_date | first_name | last_name | gender | hire_date  |</code>

<code>|      99 | 1998-09-21 | JEYY       | jose      | M      | 2012-12-24 |</code>

<code>|  999999 | 1995-09-21 | king       | tom       | M      | 2012-12-24 |</code>

<code>| 5211345 | 1995-09-21 | king       | tom       | F      | 2012-12-24 |</code>

<code>3 </code><code>rows</code> <code>in</code> <code>set</code> <code>(0.72 sec)</code>

数据都恢复回来了。

==========================================到此完全备份、恢复完成======================

②增量备份

使用innobackupex进行增量备份

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

<code># innobackupex --incremental /backup --incremental-basedir=BASEDIR</code>

命令说明

其中,BASEDIR指的是完全备份所在的目录,此命令执行结束后,innobackupex命令会在/backup目录中创建一个新的以时间命名的目录以存放所有的增量备份数据。另外,在执行过增量备份之后再一次进行增量备份时,其--incremental-basedir应该指向上一次的增量备份所在的目录。

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

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

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

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

于是,操作就变成了:

<code># innobackupex --apply-log --redo-only BASE-DIR</code>

接着执行:

<code># innobackupex --apply-log --redo-only BASE-DIR --incremental-dir=INCREMENTAL-DIR-1</code>

而后是第二个增量:

<code># innobackupex --apply-log --redo-only BASE-DIR --incremental-dir=INCREMENTAL-DIR-2</code>

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

==================================增加备份正式开始====================================

首先,在还原后的数据库中插入一些数据。

<code>MariaDB [employees]&gt; </code><code>insert</code> <code>employees </code><code>values</code><code>(0000001,</code><code>'1998-09-21'</code><code>,</code><code>'essun'</code><code>,</code><code>'com'</code><code>,</code><code>'M'</code><code>,</code><code>'2012-12-24'</code><code>);</code>

<code>Query OK, 1 row affected (0.10 sec)</code>

<code>MariaDB [employees]&gt; </code><code>insert</code> <code>employees </code><code>values</code><code>(0000002,</code><code>'1998-09-21'</code><code>,</code><code>'essun'</code><code>,</code><code>'com'</code><code>,</code><code>'M'</code><code>,</code><code>'2012-12-24'</code><code>);</code>

<code>Query OK, 1 row affected (0.01 sec)</code>

<code>MariaDB [employees]&gt; </code><code>insert</code> <code>employees </code><code>values</code><code>(0000003,</code><code>'1998-09-21'</code><code>,</code><code>'essun'</code><code>,</code><code>'com'</code><code>,</code><code>'M'</code><code>,</code><code>'2012-12-24'</code><code>);</code>

<code>MariaDB [employees]&gt; </code><code>insert</code> <code>employees </code><code>values</code><code>(0000004,</code><code>'1998-09-21'</code><code>,</code><code>'essun'</code><code>,</code><code>'com'</code><code>,</code><code>'M'</code><code>,</code><code>'2012-12-24'</code><code>);</code>

<code>MariaDB [employees]&gt; </code><code>insert</code> <code>employees </code><code>values</code><code>(0000005,</code><code>'1998-09-21'</code><code>,</code><code>'essun'</code><code>,</code><code>'com'</code><code>,</code><code>'M'</code><code>,</code><code>'2012-12-24'</code><code>);</code>

结果如下:

<code>MariaDB [employees]&gt; </code><code>select</code> <code>* </code><code>from</code> <code>employees </code><code>where</code> <code>hire_date &gt;</code><code>'2012-01-01'</code><code>;</code>

<code>|       1 | 1998-09-21 | essun      | com       | M      | 2012-12-24 |</code>

<code>|       2 | 1998-09-21 | essun      | com       | M      | 2012-12-24 |</code>

<code>|       3 | 1998-09-21 | essun      | com       | M      | 2012-12-24 |</code>

<code>|       4 | 1998-09-21 | essun      | com       | M      | 2012-12-24 |</code>

<code>|       5 | 1998-09-21 | essun      | com       | M      | 2012-12-24 |</code>

<code>8 </code><code>rows</code> <code>in</code> <code>set</code> <code>(0.24 sec)</code>

增量备份开始

<code># innobackupex </code><code>--incremental /maribak/   --incremental-basedir=/maribak/2014-04-14_07-17-33/</code>

<code>innobackupex: Backup created </code><code>in</code> <code>directory </code><code>'/maribak/2014-04-14_08-33-50'</code>

<code>innobackupex: MySQL binlog position: filename </code><code>'mysql-bin.000014'</code><code>, position 1371</code>

<code>140414 08:34:03  innobackupex: </code><code>Connection</code> <code>to</code> <code>database</code> <code>server closed</code>

<code>140414 08:34:03  innobackupex: completed OK!</code>

<code>#cd maribak/</code>

<code># ls</code>

<code>2014-04-14_07-17-33  2014-04-14_08-33-50</code>

<code>#cd 2014-04-14_07-17-33 #上一次的完全备份</code>

<code># cat xtrabackup_checkpoints</code>

<code>backup_type = </code><code>full</code><code>-prepared</code>

<code>from_lsn = 0</code>

<code>to_lsn = 885197721</code>

<code>last_lsn = 885197721</code>

<code>#cd 2014-04-14_08-33-50</code>

<code>#cat xtrabackup_checkpoints  #这次增量备份</code>

<code>backup_type = incremental</code>

<code>from_lsn = 885197721</code>

<code>to_lsn = 885227214</code>

<code>last_lsn = 885227214</code>

====================================到此增量备份完成==================================

如果在此增量之后,又增加了数据,如果数据量不是很大的话,基于二进制做即时还原会更快一些。此时又插入了一些数据

<code>MariaDB [employees]&gt; </code><code>insert</code> <code>employees </code><code>values</code><code>(0000007,</code><code>'1998-09-21'</code><code>,</code><code>'sfsdf'</code><code>,</code><code>'org'</code><code>,</code><code>'M'</code><code>,</code><code>'2012-12-24'</code><code>);</code>

<code>MariaDB [employees]&gt; </code><code>insert</code> <code>employees </code><code>values</code><code>(0000009,</code><code>'1998-09-21'</code><code>,</code><code>'sfsdf'</code><code>,</code><code>'me'</code><code>,</code><code>'M'</code><code>,</code><code>'2012-12-24'</code><code>);</code>

<code>MariaDB [employees]&gt; </code><code>insert</code> <code>employees </code><code>values</code><code>(0000010,</code><code>'1998-09-21'</code><code>,</code><code>'sdfdf'</code><code>,</code><code>'NET'</code><code>,</code><code>'F'</code><code>,</code><code>'2012-12-24'</code><code>);</code>

<code>Query OK, 1 row affected (0.02 sec)</code>

<code>MariaDB [employees]&gt; </code><code>insert</code> <code>employees </code><code>values</code><code>(0000011,</code><code>'1998-09-21'</code><code>,</code><code>'sdfdf'</code><code>,</code><code>'GOV'</code><code>,</code><code>'F'</code><code>,</code><code>'2012-12-24'</code><code>);</code>

基于增量的数据还原

第一步,删除数据文件

<code>aria_log.00000001  bogon.err  employees  ib_logfile0  multi-master.info  performance_schema  xtrabackup_binlog_pos_innodb</code>

<code>aria_log_control   bogon.pid  ibdata1    ib_logfile1  mysql              </code><code>test</code>

<code>[root@bogon data]</code><code># ls /mysql/binlog/ #binlog日志文件所在位置,并没有与数据文件存放在一起</code>

<code>mysql-bin.000001  mysql-bin.000004  mysql-bin.000007  mysql-bin.000010  mysql-bin.000013</code>

<code>mysql-bin.000002  mysql-bin.000005  mysql-bin.000008  mysql-bin.000011  mysql-bin.000014</code>

<code>mysql-bin.000003  mysql-bin.000006  mysql-bin.000009  mysql-bin.000012  mysql-bin.index</code>

第二步,开始准备还原的数据

<code># innobackupex --apply-log --redo-only /maribak/2014-04-14_07-17-33/</code>

<code>notice (again)]</code>

<code>140414 08:56:10  innobackupex: completed OK!</code>

<code>#以上为完全备份准备完成</code>

<code># innobackupex --apply-log --redo-only /maribak/2014-04-14_07-17-33/ --incremental-dir=/maribak/2014-04-14_08-33-50/</code>

<code>innobackupex: Copying </code><code>'/maribak/2014-04-14_08-33-50/performance_schema/events_statements_summary_by_host_by_event_name.frm'</code> <code>to </code><code>'/maribak/2014-04-14_07-17-33/performance_schema/events_statements_summary_by_host_by_event_name.frm'</code>

<code>innobackupex: Copying </code><code>'/maribak/2014-04-14_08-33-50/performance_schema/events_stages_history_long.frm'</code> <code>to </code><code>'/maribak/2014-04-14_07-17-33/performance_schema/events_stages_history_long.frm'</code>

<code>140414 08:59:03  innobackupex: completed OK!</code>

<code>#以上为完全与增量整合完毕</code>

<code>#查看一下整合后的日志序列号</code>

<code>#cat /maribak/2014-04-14_07-17-33/xtrabackup_checkpoints</code>

<code>backup_type = full-prepared</code>

所以说,只有需要恢复数据时,才可开始准备数据,因为其间可能有多个增量需要整合!

=============================准备工作到此完毕===================================

开始还原

<code># innobackupex --copy-back /maribak/2014-04-14_07-17-33/</code>

<code>140414 09:06:26  innobackupex: completed OK!</code>

<code>total 307216</code>

<code>drwxr-xr-x 2 root root      4096 Apr 14 09:06 employees</code>

<code>-rw-r--r-- 1 root root 213909504 Apr 14 09:06 ibdata1</code>

<code>-rw-r--r-- 1 root root  50331648 Apr 14 09:06 ib_logfile0</code>

<code>-rw-r--r-- 1 root root  50331648 Apr 14 09:06 ib_logfile1</code>

<code>drwxr-xr-x 2 root root      4096 Apr 14 09:06 mysql</code>

<code>drwxr-xr-x 2 root root      4096 Apr 14 09:06 performance_schema</code>

<code>drwxr-xr-x 2 root root      4096 Apr 14 09:06 </code><code>test</code>

<code># chown -R mysql.mysql *</code>

<code>drwxr-xr-x 2 mysql mysql      4096 Apr 14 09:06 employees</code>

<code>-rw-r--r-- 1 mysql mysql 213909504 Apr 14 09:06 ibdata1</code>

<code>-rw-r--r-- 1 mysql mysql  50331648 Apr 14 09:06 ib_logfile0</code>

<code>-rw-r--r-- 1 mysql mysql  50331648 Apr 14 09:06 ib_logfile1</code>

<code>drwxr-xr-x 2 mysql mysql      4096 Apr 14 09:06 mysql</code>

<code>drwxr-xr-x 2 mysql mysql      4096 Apr 14 09:06 performance_schema</code>

<code>drwxr-xr-x 2 mysql mysql      4096 Apr 14 09:06 </code><code>test</code>

查看binlog日志的标记,导出binlog日志并附加到数据库中

<code># cat /maribak/2014-04-14_07-17-33/xtrabackup_binlog_info</code>

<code>mysql-bin.000014    1371</code>

<code>#mysqlbinlog --start-position=1371 /mysql/binlog/mysql-bin.000014 &gt; /maribak/zengliang.sql</code>

<code># service mari start</code>

<code>Starting MySQL                                             [  OK  ]</code>

<code>MariaDB [(none)]&gt; </code><code>set</code> <code>sql_log_bin=0;</code>

<code>Query OK, 0 rows affected (0.00 sec)</code>

<code>MariaDB [(none)]&gt; </code><code>source</code> <code>/maribak/zengliang</code><code>.sql</code>

<code>MariaDB [employees]&gt; </code><code>select</code> <code>* from employees.employees where hire_date &gt;</code><code>'2012-01-01'</code><code>;</code>

<code>+---------+------------+------------+-----------+--------+------------+</code>

<code>|       7 | 1998-09-21 | sfsdf      | org       | M      | 2012-12-24 |</code>

<code>|       9 | 1998-09-21 | sfsdf      | me        | M      | 2012-12-24 |</code>

<code>|      10 | 1998-09-21 | sdfdf      | NET       | F      | 2012-12-24 |</code>

<code>|      11 | 1998-09-21 | sdfdf      | GOV       | F      | 2012-12-24 |</code>

<code>12 rows </code><code>in</code> <code>set</code> <code>(0.24 sec)</code>

============================================增量备份演示完毕===========================

附加一些高级应用

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

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

<code># innobackupex --stream=tar  /backup | gzip &gt; /backup/`date +%F_%H-%M-%S`.tar.gz</code>

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

<code># innobackupex --stream=tar  /backup | ssh [email protected]  "cat -  &gt; /backups/`date +%F_%H-%M-%S`.tar"</code>

此外,在执行本地备份时,还可以使用--parallel选项对多个文件进行并行复制。此选项用于指定在复制时启动的线程数目。当然,在实际进行备份时要利用此功能的便利性,也需要启用innodb_file_per_table选项或共享的表空间通过innodb_data_file_path选项存储在多个ibdata文件中。对某一数据库的多个文件的复制无法利用到此功能。其简单使用方法如下:

<code># innobackupex --parallel  /path/to/backup</code>

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

<code># innobackupex [email protected]  /path/IN/REMOTE/HOST/to/backup</code>

导入或导出单张表

默认情况下,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选项将某表导出了:

<code># innobackupex --apply-log --export /path/to/backup</code>

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

(2)“导入”表

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

<code>MariaDB [(none)]&gt; CREATE TABLE mytable (...)  ENGINE=InnoDB</code>

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

<code>MariaDB [(none)]&gt;ALTER TABLE mydatabase.mytable  DISCARD TABLESPACE;</code>

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

<code>MariaDB [(none)]&gt; ALTER TABLE mydatabase.mytable  IMPORT TABLESPACE;</code>

使用Xtrabackup对数据库进行部分备份

Xtrabackup也可以实现部分备份,即只备份某个或某些指定的数据库或某数据库中的某个或某些表。但要使用此功能,必须启用innodb_file_per_table选项,即每张表保存为一个独立的文件。同时,其也不支持--stream选项,即不支持将数据通过管道传输给其它程序进行处理。

此外,还原部分备份跟还原全部数据的备份也有所不同,即你不能通过简单地将prepared的部分备份使用--copy-back选项直接复制回数据目录,而是要通过导入表的方向来实现还原。当然,有些情况下,部分备份也可以直接通过--copy-back进行还原,但这种方式还原而来的数据多数会产生数据不一致的问题,因此,无论如何不推荐使用这种方式。

(1)创建部分备份

创建部分备份的方式有三种:正则表达式(--include), 枚举表文件(--tables-file)和列出要备份的数据库(--databases)。

(a)使用--include

使用--include时,要求为其指定要备份的表的完整名称,即形如databasename.tablename,如:

<code># innobackupex --include='^mageedu[.]tb1'  /path/to/backup</code>

(b)使用--tables-file

此选项的参数需要是一个文件名,此文件中每行包含一个要备份的表的完整名称;如:

<code># echo -e 'mageedu.tb1\nmageedu.tb2' &gt; /tmp/tables.txt</code>

<code># innobackupex --tables-file=/tmp/tables.txt  /path/to/backup</code>

(c)使用--databases

此选项接受的参数为数据名,如果要指定多个数据库,彼此间需要以空格隔开;同时,在指定某数据库时,也可以只指定其中的某张表。此外,此选项也可以接受一个文件为参数,文件中每一行为一个要备份的对象。如:

<code># innobackupex --databases="mageedu testdb"  /path/to/backup</code>

(2)整理(preparing)部分备份

prepare部分备份的过程类似于导出表的过程,要使用--export选项进行:

<code># innobackupex --apply-log --export  /pat/to/partial/backup</code>

此命令执行过程中,innobackupex会调用xtrabackup命令从数据字典中移除缺失的表,因此,会显示出许多关于“表不存在”类的警告信息。同时,也会显示出为备份文件中存在的表创建.exp文件的相关信息。

(3)还原部分备份

还原部分备份的过程跟导入表的过程相同。当然,也可以通过直接复制prepared状态的备份直接至数据目录中实现还原,不要此时要求数据目录处于一致状态。

===============================================完===================================

本文转自 jinlinger 51CTO博客,原文链接:http://blog.51cto.com/essun/1396832,如需转载请自行联系原作者