MySQL InnoDB丢失表但文件存在


33

我有一个具有所有数据库表文件的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

您是否尝试还原那些文件?日志文件可以保持删除状态。您真的不应该删除ibdata1
Ramhound

我从文件所在的旧mysql版本复制了文件,但表格未显示。
下车,我草坪2013年

Answers:


36

这就是MySQL无法看到这些文件的原因:系统表空间(ibdata1)具有特定于存储引擎的数据字典,该字典可让InnoDB映射出潜在的表使用情况:

InnoDB架构

将InnoDB表从一个地方移动到另一个地方需要诸如以下命令

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

这是MySQL 5.5文档的一部分,解释了需要考虑的内容

.ibd文件的可移植性注意事项

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

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

将表db1.tbl_name重命名为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导入表空间; 在这种情况下,满足以下要求的“干净” .ibd文件备份:

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

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

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

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

考虑到这些注意事项和协议,以下是建议采取的措施

对于此示例,让我们尝试将tags表还原到mydb数据库中

步骤1

确保在其中备份了这些文件.frm.ibd文件/tmp/innodb_data

第2步

获取该CREATE TABLE tags语句并以方式执行CREATE TABLE mydb.tags ...。确保它与原始结构完全相同tags.frm

步骤#3

tags.ibd使用MySQL 删除空

ALTER TABLE mydb.tags DISCARD TABLESPACE;

第四步

携带的备份副本 tags.ibd

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

步骤#5

tags表添加到InnoDB数据字典

ALTER TABLE mydb.tags IMPORT TABLESPACE;

步骤6

测试表的可访问性

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

如果结果正常,那么恭喜您导入了InnoDB表。

步骤7

将来,请不要删除ibdata1及其日志

试试看 !!!

我之前讨论过这样的事情

警告

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

有一些工具可以仅使用.frm文件来获取CREATE TABLE语句。我也写了一篇关于此的文章:如何仅从.frm文件提取表架构?。在那篇文章中,我将一个.frm文件从Linux框中复制到Windows机器上,运行Windows工具并获得了CREATE TABLE声明。


感谢您的回答!我仍在导入一张表的过程中,因为我一直在制造问题,但最终我会到达那里,并且我将让您知道它的工作原理!谢谢!
下车,我草坪2013年

1
当我运行创建时,我得到:错误1813(HY000):表'的表空间weblyizetags存在。请在导入前丢弃表空间。因此,然后我尝试首先运行alter tablespace,并收到此错误:错误1146(42S02):表'weblyize.tags'不存在。我能做什么?
下车我的草坪

谢谢!为了解决我的错误,我创建了一个新数据库,CREATE TABLE ...然后按照您的步骤运行!您免除了我必须从头重写100%的麻烦!它没有导入外键,但是可以,我可以自己做!再次感谢!
下车,我草坪2013年

如果我有100张桌子怎么办?我不会手动对每个表进行操作。如何实现自动化?
Oleg Abrazhaev,

10

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

  1. 停止MySQL。

    service mysql stop
    
  2. 除去ib_logfile0和ib_logfile1。

    cd /var/lib/mysql;
    rm ib_logfile0 ib_logfile1
    
  3. 删除tblname文件。警告:这将永久删除您的数据

    cd /var/lib/mysql/dbname;
    rm tblname*
    
  4. 启动MySQL。

    service mysql start
    

1
谢谢解决此问题,我没有做第3步,我只是删除了日志文件并启动了mysql备份。
杰夫·威尔伯特

你真是太棒了!解决了我的问题。
亚历克斯大奖赛

2

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

经过1-2天的google和SO搜索,最终我找到了一个解决方案,它挽救了我的生命(我拥有如此多的数据库和具有大量记录的表)。

  1. 从备份 /var/lib/mysql

  2. .frm使用dbsake从文件恢复表模式(还有另一种选择!mysqlfrm,但对我不起作用)

dbsake frmdump --type-codes /var/lib/mysql/database-name/tbl.frm
  1. 使用导出的架构创建新表(使用新名称)。

  2. 使用以下命令丢弃新表数据:

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`;
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.