2013-11-13 14:52:59 +0000 2013-11-13 14:52:59 +0000
33
33

MySQL InnoDB表丢失但文件存在

我有一个MySQL InnoDB,里面有所有的数据库表文件,但是MySQL看不到它们,也没有加载它们。

问题的发生是因为我删除了这三个文件。ibdata1ib_logfile0ib_logfile1 因为我在启动mysql时遇到了问题,我读到的是删除它们,因为MySQL会重新生成它们(我知道我应该备份它们,但没有)。

我该怎么做才能让MySQL重新看到这些表?

about_member.frm site_stories.frm
about_member.ibd site_stories.ibd
db.opt stories.frm
FTS_00000000000000bb_BEING_DELETED_CACHE.ibd stories.ibd
FTS_00000000000000bb_BEING_DELETED.ibd story_comments.frm
FTS_00000000000000bb_CONFIG.ibd story_comments.ibd
FTS_00000000000000bb_DELETED_CACHE.ibd story_likes.frm
FTS_00000000000000bb_DELETED.ibd story_likes.ibd
FTS_00000000000000f5_BEING_DELETED_CACHE.ibd story_tags.frm
FTS_00000000000000f5_BEING_DELETED.ibd story_tags.ibd
FTS_00000000000000f5_CONFIG.ibd story_views.frm
FTS_00000000000000f5_DELETED_CACHE.ibd story_views.ibd
FTS_00000000000000f5_DELETED.ibd story_view_totals.frm
member_favorites.frm story_view_totals.ibd
member_favorites.ibd tags.frm
members.frm tags.ibd
members.ibd

答案 (3)

36
36
36
2013-11-14 15:34:22 +0000

下面是MySQL看不到这些文件的原因。系统表空间(ibdata1)有一个Stor-Engine特定的数据字典,让InnoDB映射出潜在的表使用情况。

ALTER TABLE tblname DISCARD TABLESPACE;
ALTER TABLE tblname IMPORT TABLESPACE;

将InnoDB表从一个地方移动到另一个地方需要像

ALTER TABLE mydb.tags DISCARD TABLESPACE;

这样的命令,这里是 MySQL 5.5文档的一部分,解释了需要考虑的问题

.ibd文件的可移植性考虑因素

你不能像MyISAM表文件那样在数据库目录之间自由移动.ibd文件。存储在InnoDB共享表空间的表定义包括数据库名称。存储在表空间文件中的事务ID和日志序列号在不同数据库之间也有所不同。

要将一个.ibd文件和相关联的表从一个数据库移动到另一个数据库,请使用RENAME TABLE语句。

RENAME TABLE db1.tbl_name TO db2.tbl_name; 如果你有一个 “干净 "的.ibd文件的备份,你可以按照以下的方法把它还原到MySQL安装的地方。

自从你复制了.ibd文件后,表必须没有被删除或截断,因为这样做会改变存储在表空间内的表ID。

发布ALTER TABLE语句来删除当前的.ibd文件。

ALTER TABLE tbl_name DISCARD TABLESPACE; 把备份的.ibd文件复制到合适的数据库目录下。

发布这条ALTER TABLE语句来告诉InnoDB为表使用新的.ibd文件。

ALTER TABLE tbl/name IMPORT TABLESPACE; 在这种情况下,一个 "干净的”.ibd文件的备份是满足以下要求的。

.ibd 文件中没有未提交的事务修改。

.ibd 文件中没有未合并的插入缓冲区条目。

清理已经从 .ibd 文件中删除了所有删除标记的索引记录。

mysqld已经将.ibd文件的所有修改页从缓冲池中刷新到文件中。

鉴于这些注意事项和协议,下面是一个建议的行动过程

对于这个例子,让我们尝试将tags表恢复到mydb数据库

STEP #1

确保你有.frm.ibd文件的备份,在/tmp/innodb_data

STEP #2

获取CREATE TABLE tags语句,并以CREATE TABLE mydb.tags ...的方式执行。确保它的结构与原始的tags.frm

STEP #3

使用MySQL

cd /var/lib/mysql/mydb
cp /tmp/innodb_data.tags.ibd .
chown mysql:mysql tags.ibd

删除空的tags.ibd # STEP #4

带入tags.ibd 的备份副本。 ALTER TABLE mydb.tags IMPORT TABLESPACE;

STEP #5

tags表添加到InnoDB数据字典中

SHOW CREATE TABLE mydb.tags\G
SELECT * FROM mydb.tags LIMIT 10;

STEP 6

测试表的可访问性

如果得到正常的结果。恭喜你导入了一个InnoDB表。

STEP 7

以后请不要删除ibdata1和它的日志

试一试吧 !!!

我以前讨论过这样的事情

CAVEAT

如果你不知道tags的表结构怎么办?

有一些工具可以只用.frm文件就能得到CREATE TABLE语句。我也写过一篇关于这个问题的帖子: 如何只从.frm文件中提取表模式? 。在那个帖子里,我把一个.frm文件从Linux盒子复制到Windows机器上,运行Windows工具,得到了CREATE TABLE语句。

10
10
10
2014-01-28 02:08:22 +0000

我有同样的情况,不能删除或创建特定的tblname。我的修复过程是

1、停止MySQL。

2.删除iblogfile0和iblogfile1。删除iblogfile0和iblogfile1。

3.删除tblname文件。删除tblname文件。警告:这将永久删除你的数据

  1. 启动MySQL。
2
2
2
2019-03-27 11:19:13 +0000

我也有这个问题。我不小心删除了ibdata1,我所有的数据都丢失了。

在google和so搜索了1-2天后,我终于找到了一个解决方法,它救了我的命(我有很多数据库和表,有大量的记录)。

1.从/var/lib/mysql备份

2.用dbsake.frm文件中恢复表模式(还有另一个选项!mysqlfrm.但对我来说没用)

dbsake frmdump --type-codes /var/lib/mysql/database-name/tbl.frm

1.用导出的模式创建新表(用新名字)。

  1. 用这个命令丢弃新表数据。
ALTER TABLE `tbl-new` DISCARD TABLESPACE;
  1. 复制旧表的数据并将其粘贴到新表上,并为其设置正确的权限。
cp tbl.ibd tbl@002dnew.ibd && chown mysql:mysql tbl@002dnew.ibd
  1. 将数据导入新表。
ALTER TABLE `tbl-new` IMPORT TABLESPACE;
  1. 好的!我们在新表中有数据,我们可以删除旧表。
DROP TABLE `tbl`;
  1. 检查/var/lib/mysql/database-name,如果旧表有数据(.ibd文件),将其删除。
rm tbl.ibd

1.最后将新表重命名为原来的名称

ALTER TABLE `tbl-new` RENAME `tbl`;
``` 2.检查0x6&,如果旧表有数据(0x6&文件),则删除它。