天堂

  :: :: 博问 :: 闪存 :: :: :: 订阅 订阅 :: 管理 ::

原文链接:http://www.mysqlperformanceblog.com/2012/01/25/how-to-recover-a-single-innodb-table-from-a-full-backup/

Sometimes we need to restore only some tables from a full backup maybe because your data loss affect a small number of your tables. In this particular scenario is faster to recover single tables than a full backup. This is easy with MyISAM but if your tables are InnoDB the process is a little bit different story.

有些时候你的一些表丢失了数据,你仅仅只需要从全备中恢复这些表。在这种特殊的场景里,恢复单个表要比恢复全库要快得多。在MYISAM下这个操作非常简单,但是如果你的表全部是INNODB的话,这个过程就会有那么一点差别了。

With Oracle’s stock MySQL you cannot move your ibd files freely from one server to another or from one database to another. The reason is that the table definition is stored in the InnoDB shared tablespace (ibdata) and the transaction IDs and log sequence numbers that are stored in the tablespace files also differ between servers. Therefore our example will be very straightforward: we’ll delete some rows from a table in order to recover the table later.

根据Oracle的存储在MYSQL里你不能把IBD文件在不同的服务器或者数据库之间自由的移动。这是由于表定义存在INNODB的共享表空间(ibdata),事务ID和日志序列号(LSN)存储在表空间文件里,不同的服务也会不同。所以我们的例子将非常直接了当:我们为了稍后恢复表,将从一个表删除部分数据。

Most of these limitations are solved on Percona Server . More info about this in the conclusion section of this post. This post will be focus on how to recover a single tablespace using stock MySQL server.

大多数这些限制都在Percona Server得到了解决。关于这一点的更多信息写在这篇文章的总结小节里。这篇文章将集中于如何使用MYSQL SERVER备份服务器恢复单个表空间

First, you must meet certain prerequisites to be able to restore a ibd tablespace:

  • The ibd file must be from a consistent backup with all insert buffer entries merged  and have no uncommitted transactions in order to not be dependent of the shared tablespace ibdata. That is, shutting down with innodb_fast_shutdown=0. We’ll use XtraBackup to avoid the server shutdown.
  • You must not drop, truncate or alter the schema of the table after the backup has been taken.
  • The variable innodb_file_per_table must be enabled.

首先,你必须符合一定的前提条件才能恢复一个ibd表空间。

  • 为了不依赖ibdata共享表空间,ibd文件必须来自一个所有的insert buffer 都被合并了,也没有未提交的事务的一致的备份。也就是说,使用innodb_fast_shutdown=0关闭服务。我们将使用XtraBackup避免服务器关闭。
  • 备份开始后你不能做drop,truncate 或者修改表结构。
  • innodb_file_per_table参数必须是打开的。

Then, our first step is to get a consistent backup.

First we need to copy all the data to an output directory:

The –export option is the magic trick that will help us to get a consistent backup with complete independent ibd files without shutting down the service. In the second step the use of –export option runs a recovery process on the backup with innodb_fast_shutdown=0 and therefore merging all the insert buffers.

然后,我们的第一步是获得一个一致的备份集。

首先我们需要复制所有的数据到一个导出目录下

神奇的-export 参数能够使我们在不停服务的前提下得到一个独立的idb文件的一致性备份。(在第二步里在 innodb_fast_shutdown=0下使用–export参数执行恢复操作,从而合并全部的插入缓冲)?

# innobackupex --defaults-file=/etc/my.cnf --export /tmp/

Then apply the logs to get a consistent backup: 然后应用日志获取一致性备份

# innobackupex --defaults-file=/etc/my.cnf --apply-log --export /tmp/2012-01-22_14-13-20/

Now we’re going to delete some data from one table. In this case we’re going to delete the salary information from the user 10008:

现在我们在这表里删除一些数据。在这个例子里我们删除salery信息表的10008用户信息。

mysql> SELECT * FROM salaries WHERE emp_no=10008;
 +--------+--------+------------+------------+
 | emp_no | salary | from_date | to_date |
 +--------+--------+------------+------------+
 | 10008 | 46671 | 1998-03-11 | 1999-03-11 |
 | 10008 | 48584 | 1999-03-11 | 2000-03-10 |
 | 10008 | 52668 | 2000-03-10 | 2000-07-31 |
 +--------+--------+------------+------------+
 
mysql> DELETE FROM salaries WHERE emp_no=10008;

The next step is where we are going to save a lot of time and some headaches ;)  Instead of recovering all the InnoDB data we are going to recover only the “salaries” table:

  • Discard the tablespace of the salaries table:

我们执行的下一步就是将要节约很多时间和精力的操作。我们将只恢复"salaries"表,而不去恢复全部INNODB数据。

 mysql> set FOREIGN_KEY_CHECKS=0;
 mysql> ALTER TABLE salaries DISCARD TABLESPACE;
  • Copy the salaries.ibd files from the backup to the database data directory:

从备份里面复制salaries.ibd到数据目录:

# cp /tmp/2012-01-22_14-13-20/employees/salaries.ibd /var/lib/mysql/data/employees/
  • Import the new tablespace:

导入新的表空间

 mysql> set FOREIGN_KEY_CHECKS=0;
 mysql> ALTER TABLE salaries IMPORT TABLESPACE;
 mysql> set FOREIGN_KEY_CHECKS=1;
 mysql> SELECT * FROM salaries WHERE emp_no=10008;
 +--------+--------+------------+------------+
 | emp_no | salary | from_date | to_date |
 +--------+--------+------------+------------+
 | 10008 | 46671 | 1998-03-11 | 1999-03-11 |
 | 10008 | 48584 | 1999-03-11 | 2000-03-10 |
 | 10008 | 52668 | 2000-03-10 | 2000-07-31 |
 +--------+--------+------------+------------+

The salary history from the user is back again! 数据回来了!

Conclusion: 总结

As we learned , you can also recover single InnoDB table as with MyISAM but knowing in advance that there are some prerequisites to comply.

Percona Server relaxes a lot of limitations and is able to import tables from different Server instance, when table was altered or truncated in the meanwhile. Though this only works if table was “exported” with Xtrabackup as this exports essential information from main tablespace which is not stored in .ibd file.  innodb_import_table_from_xtrabackup=1 should be enabled for such advanced import process to work. You can read more about this feature in Percona Server Documentation

In the next blog post I’ll explain how to do recovery using  Percona Data Recovery toolkit.

如我们所知,在完成一些前提条件的情况下,你也可以像MYISAM表一样恢复单个INNODB表。

Percona Server开放了很多的限制,当表被alter或者truncate时,可以从不同的实例里导入。可是这只适用于表用Xtrabackup导出的表,因为那些没有存储ibd文件里的必要信息可以从主表空间导出。。innodb_import_table_from_xtrabackup=1 在工作中应该支持这样的高级导入操作。更多功能介绍:Percona Server Documentation

在下一个博客里我将阐述怎么样用Percona Data Recovery toolkit 做数据恢复。

《完》2 012-09-29 11:06:48

 

posted on 2012-09-28 15:18  zuoxingyu  阅读(515)  评论(0编辑  收藏  举报