我有一个 MySQL InnoDB,它包含所有数据库表文件,但 MySQL 看不到它们,也没有加载它们。
发生该问题是因为删除了以下三个文件ibdata1
:ib_logfile0
ib_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
答案1
MySQL 无法看到这些文件的原因如下:系统表空间(ibdata1)具有存储引擎特定的数据字典,可让 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 IMPORT TABLESPACE; 在这种情况下,“干净”的.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;
步骤4
带上备份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 及其日志
试一试 !!!
我以前讨论过类似的事情
Apr 23, 2012
:MySQL:如何恢复存储在 .frm 和 .ibd 文件中的表?Sep 28, 2011
:如何恢复文件被移动的 InnoDB 表
警告
如果不知道表结构该怎么办tags
?
有一些工具可以仅使用文件来获取 CREATE TABLE 语句.frm
。我也写了一篇关于此的文章:如何从.frm 文件中提取表模式?在那篇文章中,我将一个 .frm 文件从 Linux 机器复制到 Windows 机器,运行 Windows 工具并得到了声明CREATE TABLE
。
答案2
我也有同样的情况,无法删除或创建特定的 tblname。我的修复程序是:
停止 MySQL。
service mysql stop
删除 ib_logfile0 和 ib_logfile1。
cd /var/lib/mysql; rm ib_logfile0 ib_logfile1
删除 tblname 文件。警告:这将永久删除您的数据
cd /var/lib/mysql/dbname; rm tblname*
启动 MySQL。
service mysql start
答案3
我也遇到过这个问题。我ibdata1
不小心删除了,所有数据都丢失了。
在 Google 和 SO 上搜索了一两天后,我终于找到了一个解决方案,它救了我的命(我有许多包含大量记录的数据库和表格)。
从...备份
/var/lib/mysql
.frm
使用以下方法从文件恢复表架构数据库(还有另一种选择!mysql框架.但对我来说没用)
dbsake frmdump --type-codes /var/lib/mysql/database-name/tbl.frm
使用导出的模式创建新表(新名称)。
用以下命令丢弃新表数据:
ALTER TABLE `tbl-new` DISCARD TABLESPACE;
- 复制旧表的数据并粘贴到新表上并为其设置正确的权限。
cp tbl.ibd [email protected] && chown mysql:mysql [email protected]
- 将数据导入到新表。
ALTER TABLE `tbl-new` IMPORT TABLESPACE;
- 好吧!我们在新表中有了数据,我们可以删除旧表。
DROP TABLE `tbl`;
- 检查旧表
/var/lib/mysql/database-name
是否有数据(.ibd
文件),如果是,则删除。
rm tbl.ibd
- 最后将新表重命名为原始名称
ALTER TABLE `tbl-new` RENAME `tbl`;