日期:2014-05-16  浏览次数:20758 次

使用Percona XtraBackup热备和恢复MySQL(二)

在 使用Percona XtraBackup热备和恢复MySQL(一) ? 这里恢复innodb数据库时写的很简单,但是在实践的时候发现有报错,类似如下:

?

IMPORTANT: Please check that the copy-back run completes successfully.
           At the end of a successful copy-back run innobackupex-1.6.4
           prints "completed OK!".

Original data directory is not empty! at innobackupex-1.6.4 line 544.

?

意思大概是说原始的数据目录不是空的。

?

谷歌找了一下原因,参见:http://www.mysqlperformanceblog.com/2011/12/19/percona-xtrabackup-1-6-4/

?

上面说:

innobackupex did not check that MySQL datadir was empty before –copy-back was run. 
With this bug fix, innobackupex will now error out of the –copy-back operation if the destination is not empty, 
avoiding potential data loss or a strang combination of a restored backup and previous data. Bug Fixed: #737569
 (Valentine Gostev)

?

于是找到了这个bug:https://bugs.launchpad.net/percona-xtrabackup/+bug/737569

?

我用的是percona-xtrabackup-2.0.0,按说这个版本应该解决了这个问题!否则percona也太不厚道了。

?

所以Original data directory is not empty应该是正常的!可以把Preparing之后的ibdata1和ib_logfile*文件分别复制到mysql的my.cnf里面配置的innodb_data_home_dir目录和datadir目录,然后启动mysql即可!

?

在这个bug页面的最下面看到以下内容:

Hello,

partial backup restore is not supported. If you have innodb_file_per_table enabled for tables in these databases - you might want to use --export option to restore data from backup partially.

?

这里提供了一种partial backup restore的方法。

?

倒数第二个评论中也提供了怎么部分恢复多个数据库中的若干个的方案。

So, in my understanding, the workround should be: Make sure "ls /var/lib/mysql/mydb01" shows an empty directory OR not existing before running innobackupex --copy-back

?

继续找了一下innodb_file_per_table 参数的含义:

InnoDB引擎默认将所有的数据库的表数据存储在一个共享空间中:ibdata1。(这就是为什么我测试写入的时候,这个文件的大小高达37G,而且在drop数据库之后,ibdata1文件不会自动收缩)

这样单个数据库或表的备份成为问题,通常只能将数据使用mysqldump导出,然后再导入解决这个问题。

而用XtraBackup的copy-back也只能一个很大的ibdata1文件来恢复数据,而且要求数据目录是空的,只能全库恢复,不能部分恢复!


在MySQL的配置文件[mysqld]部分,增加innodb_file_per_table=1参数。
修改InnoDB为独立表空间模式,使数据库的每个表都生成一个表空间。

?

innodb_file_per_table的优点:

1.每个表都有自已独立的表空间(tablespace)。
2.每个表的数据和索引都会存在自已的表空间中。
3.可以实现单表在不同的数据库中移动。
4.空间可以回收(除drop table操作处,表空不能自已回收)
a)Drop table操作自动回收表空间,如果对于统计分析或是日值表,删除大量数据后可以通过:alter table TableName engine=innodb;回缩不用的空间。
b)对于使innodb-plugin的Innodb使用turncate table也会使空间收缩。
c)对于使用独立表空间的表,不管怎么删除,表空间的碎片不会太严重的影响性能,而且还有机会处理。

?

innodb_file_per_table的缺点:

单表增加过大,如超过100个G。

?

开启innodb_file_per_table的方法:

?

1.在my.cnf中[mysqld]下设置
innodb_file_per_table=1

2.查看是否开启:
mysql> show variables like ‘%per_table%’;

3.Move table from system tablespace to its own tablespace.
SET GLOBAL innodb_file_per_table=1;
ALTER TABLE table_name ENGINE=InnoDB;

4. Move table from its own tablespace to system tablespace.
SET GLOBAL innodb_file_per_table=0;
ALTER TABLE table_name ENGINE=InnoDB;

?

操作完成之后ibdata1的大小不会改变,只是数据库数据目录下每个表从以前的一个.frm文件,多了一个同名的.ibd文件。如果想让ibdata1收缩,只能手动mysqldump出所有数据库的数据到sql文件中,删除原来的ibdata1和ib_logfile*,binlog也可以删掉,相当于在一个空的数据库执行mysqldump出的sql文件。这样,ibdata1就会是my.cnf中配置的初始大小而不会增长。

?