Xtrabackup备份导致从库宕机重启,诱因是?

最近,在写一个备份效验平台,在利用xtrabackup进行物理备的过程中,踩到一些问题点(比如stream模式下,DB写入数据过大同时未指定tmpdir,xtrabackup_logfile文件会放在/tmp目录,进而导致跟目录写满;比如flush tables with read lock情况,从库复制线程有update,导致 ftwrl卡住,最终导致内存突降问题),今天我们聊聊,ftwrl,导致DB宕机重启的问题,文章过几天补充发布

Xtrabackup备份为什么导致内存突降耗尽,进而导致备份失败??

最近,在写一个备份平台,正好遇到一些问题,就整体记录一下,先分享标题,正文过段时间再写,各位小伙伴也可以先评论,相信大家都或多或少遇到此类问题

Xtrabackup物理备如何进行单表恢复??

在平时的工作中,经常会遇到各种奇葩需求,比如测试团队提个需求,我需要恢复一个数据库用来压测某个接口,该接口只需要某个实例的某个库某几张表(当然,这个表比较大,小表直接dump就可以),当然,实际遇到的需求多样,那我们怎么从物理全备里快速提取我们需要的表呢??

FLUSH TABLE WITH READ LOCK详解

FLUSH TABLES WITH READ LOCK简称(FTWRL),该命令主要用于备份工具获取一致性备份(数据与binlog位点匹配)。由于FTWRL总共需要持有两把全局的MDL锁,并且还需要关闭所有表对象,因此这个命令的杀伤性很大,执行命令时容易导致库hang住。如果是主库,则业务无法正常访问;如果是备库,则会导致SQL线程卡住,主备延迟。本文将详细介绍FTWRL到底做了什么操作,每个操作的对库的影响,以及操作背后的原因。

FTWRL做了什么操作?

FTWRL主要包括3个步骤:

1.上全局读锁(lock_global_read_lock)
2.清理表缓存(close_cached_tables)
3.上全局COMMIT锁(make_global_read_lock_block_commit)

FTWRL每个操作的影响

上全局读锁会导致所有更新操作都会被堵塞;关闭表过程中,如果有大查询导致关闭表等待,那么所有访问这个表的查询和更新都需要等待;上全局COMMIT锁时,会堵塞活跃事务提交。由于FTWRL主要被备份工具使用,后面会详细解释每个步骤的作用,以及存在的必要性。FTWRL中的第1和第3步都是通过MDL锁实现,关于MDL的实现,我之前总结了MDL锁的文章,这里主要介绍清理表缓存的流程。

清理表缓存

每个表在内存中都有一个table_cache,不同表的cache对象通过hash链表维护。
访问cache对象通过LOCK_open互斥量保护,每个会话打开的表时,引用计数share->ref_count++,
关闭表时,都会去对引用计数share->ref_count–。
若发现是share对象的最后一个引用(share->ref_count==0),并且share有old_version,
则将table_def_cache从hash链表中摘除,调用free_table_share进行处理。关键函数close table流程如下:

1.关闭所有未使用的表对象
2.更新全局字典的版本号
3.对于在使用的表对象,逐一检查,若表还在使用中,调用MDL_wait::timed_wait进行等待
4.将等待对象关联到table_cache对象中
5.继续遍历使用的表对象
6.直到所有表都不再使用,则关闭成功。

清理表缓存函数调用

mysql_execute_command->reload_acl_and_cache->close_cached_tables
->TABLE_SHARE::wait_for_old_version->MDL_wait::timed_wait->
inline_mysql_cond_timedwait

会话操作表流程

1.打开表操作,若发现还有old_version,则进行等待
2.share->ref_count++
3.操作完毕,检查share->ref_count–是否为0
4.若为0,并且检查发现有新版本号,则认为cache对象需要重载
5.将cache对象摘除,调用MDL_wait::set_status唤醒所有等待的线程。

关闭表对象函数调用

dispatch_command->mysql_parse->mysql_execute_command->
close_thread_tables->close_open_tables->close_thread_table->
intern_close_table->closefrm->release_table_share->my_hash_delete->
table_def_free_entry->free_table_share

关闭表导致业务库堵住的典型场景

假设有3个会话,会话A执行大查询,访问t表;然后一个备份会话B正处于关闭表阶段,需要关闭表t;随后会话C也请求访问t表。三个会话按照这个顺序执行,我们会发现备份会话B和会话C访问t表的线程都处于“waiting for table flush”状态。这就是关闭表引起的,这个问题很严重,因为此时普通的select查询也被堵住了。下面简单解释下原因:

1.会话A打开表t,执行中……
2.备份会话B需要清理表t的cache,更新版本号(refresh_version++)
3.会话B发现表t存在旧版本(version != refresh_version),表示还有会话正在访问表t,
等待,加入share对象的等待队列
4.后续会话C同样发现存在旧版本(version != refresh_version),
等待,加入share对象的等待队列
……
5. 大查询执行完毕,调用free_table_share,唤醒所有等待线程。

free_table_share //逐一唤醒所有等待的线程。
{
while ((ticket= it++))
ticket->get_ctx()->m_wait.set_status(MDL_wait::GRANTED);
}

第4步与第5步之间,所有的访问该表的会话都处于“waiting for table flush”状态,唯有大查询结束后,等待状态才能解除。

主备切换场景

在生产环境中,为了容灾一般mysql服务都由主备库组成,当主库出现问题时,可以切换到备库运行,保证服务的高可用。在这个过程中有一点很重要,避免双写。因为导致切换的场景有很多,可能是因为主库压力过大hang住了,也有可能是主库触发mysql bug重启了等。当我们将备库写开启时,如果老主库活着,一定要先将其设置为read_only状态。“set global read_only=1”这个命令实际上也和FTWRL类似,也需要上两把MDL,只是不需要清理表缓存而已。如果老主库上还有大的更新事务,将导致set global read_only hang住,设置失败。因此切换程序在设计时,要考虑这一点。

关键函数:fix_read_only

1.lock_global_read_lock(),避免新的更新事务,阻止更新操作
2.make_global_read_lock_block_commit,避免活跃的事务提交

FTWRL与备份

Mysql的备份方式,主要包括两类,逻辑备份和物理备份,逻辑备份的典型代表是mysqldump,物理备份的典型代表是extrabackup。根据备份是否需要停止服务,可以将备份分为冷备和热备。冷备要求服务器关闭,这个在生产环境中基本不现实,而且也与FTWRL无关,这里主要讨论热备。Mysql的架构支持插件式存储引擎,通常我们以是否支持事务划分,典型的代表就是myisam和innodb,这两个存储引擎分别是早期和现在mysql表的默认存储引擎。我们的讨论也主要围绕这两种引擎展开。对于innodb存储引擎而言,在使用mysqldump获取一致性备份时,我们经常会使用两个参数,–single-transaction和–master-data,前者保证innodb表的数据一致性,后者保证获取与数据备份匹配的一致性位点,主要用于搭建复制。现在使用mysql主备集群基本是标配,所以也是必需的。对于myisam,就需要通过–lock-all-tables参数和–master-data来达到同样的目的。我们在来回顾下FTWRL的3个步骤:

1. 上全局读锁
2. 清理表缓存
3. 上全局COMMIT锁

第一步的作用是堵塞更新,备份时,我们期望获取此时数据库的一致状态,不希望有更多的更新操作进来。对于innodb引擎而言,其自身的MVCC机制,可以保证读到老版本数据,因此第一步对它使多余的。第二步,清理表缓存,这个操作对于myisam有意义,关闭myisam表时,会强制要求表的缓存落盘,这对于物理备份myisam表是有意义的,因为物理备份是直接拷贝物理文件。对于innodb表,则无需这样,因为innodb有自己的redolog,只要记录当时LSN,然后备份LSN以后的redolog即可。第三步,主要是保证能获取一致性的binlog位点,这点对于myisam和innodb作用是一样的。

所以总的来说,FTWRL对于innodb引擎而言,最重要的是获取一致性位点,前面两个步骤是可有可无的,因此如果业务表全部是innodb表,这把大锁从原理上来讲是可以拆的,而且percona公司也确实做了这样的事情,具体大家可以参考blog链接。此外,官方版本的5.5和5.6对于mysqldump做了一个优化,主要改动是,5.5备份一个表,锁一个表,备份下一个表时,再上锁一个表,已经备份完的表锁不释放,这样持续进行,直到备份完成才统一释放锁。5.6则是备份完一个表,就释放一个锁,实现主要是通过innodb的保存点机制。相关的bug可以参考链接:http://bugs.mysql.com/bug.php?id=71017

利用xtrabackup和binlog恢复单表误删数据思路

昨晚,有个朋友说它的DB有张表,被研发误删了一部分数据,咨询我一些恢复的思路:

环境:全备、增备、日志、主从、binlog-format=mixed

由于binlog格式的限制,没法从binlog里面反向解析误删数据,因此,就有了下面的思路,有什么遗漏的或者不到位的地方,欢迎大家指正!!

1.必须有xtrabackup备份

这里包括全备和增备

2.在全备和增备上都执行–apply-log –redo-only操作

执行完此操作后,备份的数据目录里会包含以下几种数据类型文件:

*.frm / *.ibd / *.exp / *.cfg

3.将原来有数据丢失的表重命名为新表

alter table old_table rename old_table_bak

4.创建一个与原表结构一致的新表new_table

5.将新表丢弃表空间

alter table new_table discard tablespace;

6.拷贝备份目录中的 *.ibd/*.cfg/*.exp到mysql的数据目录

mysql> system cp *.{ibd,exp,cfg} /db/mysql5.6/data/test/

7.导入表空间:

alter table new_table import tablespace

注:此时你执行查询时,是可以正常查询,但数据肯定不是最新的

8.由于数据不是最新的,所以需要用到binlog,但是binlog针对单表需要使用脚本过滤,太麻烦,下面介绍一个简单办法

这是使用偷懒的方法,重新授予一个用户,仅对此表有select,insert,delete,update的权限

GRANT SELECT, INSERT, UPDATE, DELETE ON `test`.`t1` TO ‘test_user’@’localhost’ identified by ‘123456’;

9.执行binlog恢复,具体根据需要进行处理,这里简单说明

mysqlbinlog –no-defaults -vv –base64-output=decode-rows -d test mysql-bin.000001 | mysql -S /tmp/mysqld.sock -utest_user-p123456 -f

注:

这里的 -f 参数:恢复时,忽略后面的错误,强制导入

xtrabackup实现多实例备份实践

多实例备份,我一直未曾去学习使用它,最近,因公司报表机数据增长太快,dump备份太慢,也很容易卡住,因此,决定弃用dunp备份,改用xtrabackup备份,实现增备、全备;

目前,DB存在3307,3308,3309 三个实例,使用的mysqld_multi部署的多实例;

这里,如果需要使用xtrabackup备份多实例的话,需要针对每个实例,将配置文件独立写出一份,放在/home/backup/conf目录下

我们备份的目录为:/home/backup

备份的最新检查点放在:/home/backup/last_backup

备份存放路径:/home/backup/BackupDir_xtrabackup

备份日志存放路径:/home/backup/log

具体目录结构如下:

[root@slave1 home]# tree /home/backup
/home/backup
├── BackupDir_xtrabackup
├── backup_xtrabackup.sh
├── conf
│ ├── my3307.cnf
│ ├── my3308.cnf
│ └── my3309.cnf
├── last_backup
└── log

percona xtrabackup 官方文档地址:

https://www.percona.com/doc/percona-xtrabackup/2.2/innobackupex/innobackupex_script.html

下面,简单讲一下,xtrbackup备份多实例的使用

xtrbackup常用的几个参数:

–user: mysql用户

–password: 用户密码

–defaults-file: 指定my.cnf文件路径,若不指定则读取mysql默认的my.cnf文件,这里我们会指定我们在conf目录独立出的各个实例的文件

–socket:mysql实例对应的socket文件

全备示例:

innobackupex –user=root –password=123456 –socket=/tmp/mysql3307.sock –defaults-file=/home/backup/conf/my3307.cnf /home/backup/BackupDir_xtrabackup/3307/

当备份日志出现:innobackupex: completed OK! 则代表备份成功。

备份结束后,备份目录会出现几个文件,下面,我们解释一下:

backup-my.cnf:主要是记录innobackupex中使用到Mysql参数。

xtrabackup_checkpoints:记录备份类型及开始及结束的lsn位置。backup_type 有两种full-prepared (全备)、incremental (增备)。

xtrabackup_info:记录mysql相关信息。

xtrabackup_logfile: xtrabackup自己的日志文件,新版本中不直接可见。

xtrabackup_binlog_info :这个会记录你备份结束时,主上binlog的位置,可以用于重建主从

增量备份,由于是基于全备执行,而且,方法比较简单,这里就不演示

下面描述一下,恢复需要注意的问题:

1. 对全量备份进行操作

了解两个参数 :

–apply-log :创建新的事务日志,从backup-my.cnf文件中读取innodb配置信息。

–redo-only:只读已提交的事务,在最后一次增量合并时,不需要填写这个参数。

全量备份恢复前准备

innobackupex –apply-log –redo-only /home/backup/BackupDir_xtrabackup/3307/……

2. 将第一次增量备份的数据合并到全量备份中

innobackupex –apply-log –redo-only /home/backup/BackupDir_xtrabackup/3307/…full –incremental-dir= /home/backup/BackupDir_xtrabackup/3307/…..inc

3.将第二次全量备份的数据合并到全量备份中(最后一个增量备份)

innobackupex –apply-log /home/backup/BackupDir_xtrabackup/3307/…full –incremental-dir= /home/backup/BackupDir_xtrabackup/3307/…..inc

注:最后一次的合并操作中不需要添加–redo-only参数。

4.这里需要对全备,再做一次apply-log,网上很多都没有这步,但官方文档上有

innobackupex –apply-log /home/backup/BackupDir_xtrabackup/3307/…full

5.停止mysql服务

恢复时需要停掉MySQL,并且数据目录必须为空,所以,我们需要多原有的数据目录进行备份,最简单方式:mv data data_1011_bak

然后,再新建一个数据目录:mkdir data

6. 恢复数据。

innobackupex –defaults-file=/home/backup/conf/my3307.cnf –copy-back /home/backup/BackupDir_xtrabackup/3307/…full

7.权限设置

恢复完成后,需要对数据目录设置mysql权限

chown -R mysql:mysql /data/

8.启动mysql实例

9. 查看是否恢复成功,这里恢复算完成了,但是,实际情况下,我们还需要根据xtrbackup_binlog_info的信息去恢复 binlog的部分数据,这个环节网上也没有提到,所以,刚才对数据目录的备份就十分有用,这里,就不做演示,相信基于binlog的恢复,应该都十分熟练了

利用mysqldump实现mysql数据库全量备份和增量备份脚本

mysqldump实现全量备份,增量备份脚本,

增量备份,其实就是复制日志

全备脚本:
#! /bin/bash
# mysql 全量备份脚本,建议在slave上运行,并开启log_slave_updates=1
mkdir /backup
cd /backup
datadir=`date +”%y-%m-%d”`
mkdir -p $datadir/data
path=/usr/local/mysql/data
for i in `mysql -uroot -p123456 -e “show databases” |grep -v “Database”`
do
mysqldump -uroot -p123456 –defaultes-character-set=utf8 -q –lock-all-tables –flush-logs -E -R –triggers -B $i |gzip > /backup/$datadir/data/${i}_${datadir}.sql.gz
#mysqldump -uroot -ptiancity –opt –single-transaction –flush-logs -E -R -C –triggers $i |gzip > “/backup/$datadir/data/${i}_${datadir}.sql.gz”
done
binlog_rm=`tail -n 1 /app/mysql/data/mysql-bin.index |sed ‘s/\/app\/mysql\/data\///’`
mysql -uroot -p123456 -e “purge binary logs to ‘$binlog_rm'”

增备脚本:
#! /bin/bash
# mysql 增量备份脚本,其实就是复制二进制日志,
cd /backup
datadir=`date +”%y-%m-%d”`
mkdir -p $datadir/data
path=/usr/local/mysql/data
mysqladmin -uroot -p12334 flush-logs
# mysql -uroot -p12334 -e “flush logs”
binlog_cp=`head -n -1 $path/mysql-bin.index |sed ‘s/\/app\/mysql\/data\///’`
for i in $binlog_cp
do
cp $path/$i /backup/$datadir/data/
done
binlog_rm=`tail -n 1 /app/mysql/data/mysql-bin.index |sed ‘s/\/app\/mysql\/data\///’`
mysql -uroot -p12334 -e “purge binary logs to ‘$binlog_rm'”

数据库崩溃,利用备份和日志进行灾难恢复

在实际的工作中,我们可能经常会遇到数据库宕机,数据丢失的情况,下面,我将演示一个模拟环境

1.数据库正常启动插入数据:

  1. [root@client103 ~]# mysql -uroot -pkongzhong  
  2. mysql> use test;  
  3. mysql> insert into a select * from a;  
  4. #注: 这里不演示建表,默认大家都懂  
  5. # 下面进行一次全备  
  6. [root@client103 ~]#  innobackupex –user=root –password=kongzhong –defaults-file=/etc/my.cnf –port=3306  /tmp/backup/ >/tmp/backup/innoback.log 2>&1  
  7.   
  8. # 再次插入数据  
  9. mysql> insert into a select * from a;  
  10. # 实行增量备份  
  11. [root@client103 ~]#  innobackupex –user=root –password=kongzhong –defaults-file=/etc/my.cnf –port=3306 –incremental –incremental-basedir=/tmp/backup/2014-02-27_13-24-51/  /tmp/backup/  
  12.   
  13. # 再次插入数据  
  14. mysql> insert into a select * from a;  
  15. # 此时大家记录一下现在的总行数(一会还原需要核对数据的)  
  16. # 此时数据库宕机  
  17. #模拟宕机操作为:  
  18. # 1.将数据目录的下的二进制日志,复制到 /tmp/backup,一会需要重演日志(此步非常重要,复制操作默认大家会了)  
  19. # 2.删除数据目录下的所有文件,此时数据库就崩溃了(如果关闭数据库,是关不了,记得杀掉进程,kill -9 ….)  

2.数据库宕机后执行恢复操作

  1. # 全备应用日志  
  2. [root@client103 ~]# innobackupex –apply-log /tmp/backup/2014-02-27_13-24-51/  
  3. # 增备应用日志  
  4. [root@client103 ~]# innobackupex –apply-log /tmp/backup/2014-02-27_13-24-51/ –incremental-dir=/tmp/backup/2014-02-27_13-32-44/  
  5. # 应用完日志,利用全备恢复数据  
  6. [root@client103 ~]# innobackupex –copy-back /tmp/backup/2014-02-27_13-24-51/  
  7. # 修改数据目录权限为mysql:mysql  
  8. [root@client103 ~]# chown mysq:mysql /var/lib/mysql -R  
  9. # 启动数据库  
  10. [root@client103 ~]# /etc/init.d/mysql start  
  11. # 登陆数据库,查看数据行数,发现数值与崩溃前是不一致的,所以需要利用日志恢复  
  12. [root@client103 ~]# mysql -uroot -pkongzhong  
  13. mysql> use test;  
  14. mysql>  select count(*) from a;  
  15. # 查看最后一次增备完成时的日志文件名和pos号(备份时自动记录的)  
  16. [root@client103 ~]# cat /tmp/backup/2014-02-27_13-32-44/xtrabackup_binlog_info   
  17. mysql-103-bin.000005    3694  
  18. # 所以,我们使用二进制执行恢复时,起始点为3694  
  19. # 利用日志恢复  
  20. [root@client103 ~]# mysqlbinlog –start-pos=3694 /tmp/backup/mysql-103-bin.000005  |mysql -uroot -pkongzhong  
  21. # 此时在登陆数据库查看数据是否相符,请自行测试  
  22. mysql> use test;  
  23. mysql>  select count(*) from a;  

使用Xtrabackup来实现mysql数据库的备份和恢复

一.Xtrabackup概述:
      Xtrabackup是由percona提供的mysql数据库备份工具,支持在线热备份.据官方介绍,这也是世界上惟一一款开源的能够对innodb和xtradb数据库进行热备的工具,同时也支持mariadb.下载Xtrabackup,需要下载相应数据库版本和相应系统的rpm包或源代码,个人认为,rpm包安装完全可以解决问题,就没必要用源码编译安装了.
      Xtrabackup有两个主要的工具:xtrabackup、innobackupex[个人推荐使用此方式]
   注解:
    (1).xtrabackup只能备份InnoDB和XtraDB 两种数据表
    (2).innobackupex则封装了xtrabackup,同时可以备份MyISAM数据表
    Innobackupex完整备份后生成了几个重要的文件:
     xtrabackup_binlog_info:记录当前最新的LOG Position
     xtrabackup_binlog_pos_innodb:innodb log postion
     xtrabackup_checkpoints: 存放备份的起始位置beginlsn和结束位置endlsn,增量备份需要这个lsn[增量备份可以在这里面看from和to两个值的变化]
二.Xtrabackup特点:
    (1)备份过程快速、可靠
    (2)备份过程不会打断正在执行的事务
    (3)能够基于压缩等功能节约磁盘空间和流量
    (4)自动实现备份检验
    (5)还原速度快
三.Xtrabackup的安装:
    percona官方网站:http://www.percona.com/downloads/   请到此网站下载对应数据库版本的源码包或RPM包
   [root@client103 ~]# rpm -ivh percona-xtrabackup-20-2.0.8-587.rhel6.x86_64.rpm
四.innobackupex相关参数说明:
   注:xtrabackup命令只备份数据文件,并不备份数据表结构(.frm),所以使用xtrabackup恢复的时候,你必须有对应表结构文件(.frm),所以,个人推荐采用innobackupex命令[此命令相当于冷备份,复制数据目录的索引,数据,结构文件,但会有短暂的锁表(时间依赖于MyISAM大小)]
参数说明如下:
    –defaults-file:指定my.cnf参数文件的位置[此配置文件里必须指定datadir]
    –apply-log:同xtrabackup的–prepare参数,一般情况下,在备份完成后,数据尚且不能用于恢复操作,因为备份的数据中可能会包含尚未提交的事务或已经提交但尚未同步至数据文件中的事务。因此,此时数据 文件仍处理不一致状态。–apply-log的作用是通过回滚未提交的事务及同步已经提交的事务至数据文件使数据文件处于一致性状态。
    –copy-back:做数据恢复时将备份数据文件拷贝到MySQL服务器的datadir
    –remote-host=HOSTNAME: 通过ssh将备份数据存储到进程服务器上
    –stream=[tar]:备份文件输出格式, 该文件可在XtarBackup binary文件中获得. 在使用参数stream=tar备份的时候,你的xtrabackup_logfile可能会临时放在/tmp目录下,如果你备份的时候并发写入较大的话,xtrabackup_logfile可能会很大(5G+),很可能会撑满你的/tmp目录,可以通过参数–tmpdir指定目录来解决这个问题.
    –tmpdir=DIRECTORY:当有指定–remote-host or –stream时, 事务日志临时存储的目录, 默认采用MySQL配置文件中所指定的临时目录tmpdir
    –redo-only –apply-log:强制备份日志时只redo,跳过rollback,这在做增量备份时非常必要
    –use-memory=*:该参数在prepare的时候使用,控制prepare时innodb实例使用的内存
    –databases=LIST:列出需要备份的databases,如果没有指定该参数,所有包含MyISAM和InnoDB表的database都会被备份
    –slave-info:备份从库, 加上–slave-info备份目录下会多生成一个xtrabackup_slave_info 文件, 这里会保存主日志文件以及偏移, 文件内容类似于:CHANGE MASTER TO MASTER_LOG_FILE=”, MASTER_LOG_POS=0
    –socket=SOCKET:指定mysql.sock所在位置,以便备份进程登录mysql.
五.使用innobackupex命令来实现数据库备份:

1.完全备份与恢复:

  1. # 指定备份某一数据库  
  2. [root@client103 ~]# innobackupex –user=root –password=kongzhong –defaults-file=/etc/my.cnf –port=3306 –databases=a /tmp/backup/ >/tmp/backup/innoback.log 2>&1  
  3. # 备份所有的数据库  
  4. [root@client103 backup]# innobackupex –user=root –password=kongzhong –defaults-file=/etc/my.cnf –port=3306  /tmp/backup/ >/tmp/backup/innoback.log 2>&1  
  5. # 注:还原时,需要清空数据目录,所以建议备份的话,执行全库备份  
  6. # 备份完成后,应用日志,是备份的数据保持一致[ /tmp/backup/2014-01-11_14-46-21/:为备份存放的位置]  
  7. [root@client103 ~]# innobackupex –apply-log /tmp/backup/2014-01-11_14-46-21/   
  8. # 利用刚才的备份进行数据库还原  
  9. [root@client103 ~]# innobackupex –copy-back /tmp/backup/2014-01-11_14-46-21/   
  10. ### 备份到远程机器上[这里的ssh的话,需要实现两边的key同步,不需要输入密码,否则无法实现,此方法一般应该不用,待检验] ###  
  11. [root@client103 ~]# innobackupex –user=root –password=kongzhong –defaults-file=/etc/my.cnf –port=3306  –databases=a –stream=tar /tmp/backup/ |ssh root@192.168.1.100 cat “>”/tmp/backup  

2.增量备份与恢复:

  1. # 全备  
  2. [root@client103 ~]# innobackupex –user=root –password=kongzhong –defaults-file=/etc/my.cnf –port=3306  /tmp/backup/ >/tmp/backup/innoback.log 2>&1  
  3. # 基于全备的增量备份  
  4. [root@client103 ~]# innobackupex –user=root –password=kongzhong –defaults-file=/etc/my.cnf –port=3306 –incremental –incremental-basedir=/tmp/backup/全备的文件名/ /tmp/backup/  
  5. # 基于增量备份的增量备份  
  6. [root@client103 ~]# innobackupex –user=root –password=kongzhong –defaults-file=/etc/my.cnf –port=3306 –incremental –incremental-basedir=/tmp/backup/增量备份的文件名/ /tmp/backup/  
  7. # 备份应用日志,保证数据一致  
  8. # 全备应用日志  
  9. [root@client103 ~]# innobackupex  –apply-log /tmp/backup/2014-01-11_15-37-31/  
  10. # 第一次的增量备份应用日志,应用完日志后,将合并到全备上,恢复使用全备恢复  
  11. [root@client103 ~]# innobackupex  –apply-log /tmp/backup/2014-01-11_15-37-31/ –incremental-dir=/tmp/backup/2014-01-11_15-45-06/  
  12. # 将第二次增量备份应用日志并合并到全备上  
  13. [root@client103 ~]# innobackupex  –apply-log /tmp/backup/2014-01-11_15-37-31/ –incremental-dir=/tmp/backup/2014-01-11_15-46-33/  
  14. # 此时两次增量备份其实都合并到全备上了,恢复是只需要使用全备进行恢复就可以了  
  15. # 模拟数据故障[删除数据库的数据目录,执行如下命令还原]  
  16. [root@client103 ~]# innobackupex –copy-back /tmp/backup/2014-01-11_15-37-31/  
  17. # 恢复后的数据默认权限是有问题的,所以需要修改数据目录权限,如下  
  18. [root@client103 ~]# chown -R mysql:mysql /var/lib/mysql/  
  19. # 此时数据恢复完成,重启数据库服务,进行测试就可以了。大家自行测试,有问题留言反馈!  
3.简述备份和恢复的步骤:
(1).备份:
    a.全备
    b.基于全备的多次增量备份
(2).恢复:
    a.全备
    b.基于全备的多次增量备份
    c.全备应用日志,保证数据一致
    d.合并多次增量备份到全备上
    e.利用全备恢复数据
    f.恢复完成后,修改数据目录的权限
    g.重启mysql服务