译者序:曾经因为想要从完全备份文件中恢复某个InnoDB表而在搜索引擎中到处翻。这篇文章给了我们一个非常好的指导。另外,本文还涉及了为什么InnoDB不能拷贝数据库文件等话题。
有时,数据丢失的问题出现在某些表中,我们只需要从完全备份中恢复这少部分表。在这个特殊的场景中,恢复单张表要比做一次完全恢复要快得多。在MyISAM环境中,恢复单张表要容易得多,但是如果你的环境为InnoDB,这项任务就显得不那么容易了。
在Oracle原版MySQL中,我们不能任意地在数据库或服务器之间移动ibd文件。究其根源,表定义存储在InnoDB共享表空间(ibdata),而事务ID和日志序列号保存在表空间文件中,这些对于每个服务器来说都是不一样的。因此,我们的例子非常简单:先删除将要恢复表中部分行。
下述的限制在Percona Server中均已解除。 访问本文的结论一节获取更多信息。本文重点讨论 原版MySQL如何恢复单张表 。
-
首先,要完成单个ibd表空间,必须满足下述先决条件:
-
-
ibd文件必须是为all insert buffer entries merged[1]_,且不含有任何未提交事务一致性备份,为独立于共享ibdata表空间。也就是说,关闭服务时使用 innodb_fast_shutdown =0选项。我们使用了XtraBackup 可以避免关闭服务。
-
备份开始后,不允许drop、truncate或者alter表结构(schema)。
-
选项innodb_file_per_table必须打开。
导出所有数据到某个目录
—export是一个神奇的选项,将有助于我们获得一个具有完全独立ibd文件、不需要关闭服务的一致备份。下一步在–export选项上运行以innodb_fast_shutdown=0进行备份的恢复过程,因此,合并所有的插入缓冲区。 ::
# innobackupex –defaults-file=/etc/my.cnf –export /tmp/
接着应用日志得到一个一致的备份:
# innobackupex --defaults-file=/etc/my.cnf --apply-log --export /tmp/2012-01-22_14-13-20/
现在,将要删除部分数据。这个例子中,我们删除user 10008的salary信息:
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;
-
下面的步骤将节省不少时间与脑细胞:-p我们只恢复salaries表而不是所有InnoDB数据。
-
-
Discard salaries表的表空间:
mysql> ALTER TABLE salaries DISCARD TABLESPACE;
-
从备份目录拷贝salaries.ibd文件到数据目录:
# cp /tmp/2012-01-22_14-13-20/employees/salaries.ibd /var/lib/mysql/data/employees/
-
导入新的表空间:
mysql> ALTER TABLE salaries IMPORT TABLESPACE;
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 |
+--------+--------+------------+------------+
user的salary记录又回来了!
结论:
如刚才所演示的,某个InnoDB表空间可以像MyISAM一样进行单独恢复操作。需要留意的是,这需要一些先决条件。
Percona Server解除了很多限制,比如:alter或truncate表的同时,在另外一个服务器实例中导入该表。虽然这仅适用于使用Xtrabackup导出的表,导出的数据中含有本来没有存在.ibd文件中的主要表空间的基本信息。
要想刚才所述的功能工作的话, innodb_import_table_from_xtrabackup=1 选项必须打开。访问 Percona Server扩展导出文档 获取更详细的信息。
zz:http://www.himysql.com/mysql/how-to-recover-a-single-innodb-table-from-a-full-backup.html