之前群里有位小伙伴遇到一个问题: 表存在却打不开
2026-04-10T02:02:49.557934Z 2 [Warning] InnoDB: Cannot open table db1/t1 from the internal data dictionary of InnoDB though the .frm file for the table exists. Please refer to http://dev.mysql.com/doc/refman/5.7/en/innodb-troubleshooting.html for how to resolve the issue.出现这样的报错, 通常表示数据库目录下存在相关的frm文件, 但是数据字典(ibdata1)中未记载相关表信息; 也就是说存在手动拷贝的frm文件到数据库目录下的操作.
咨询发现是: 因为某种原因只剩下db目录了, 然后重新初始化数据库, 把db目录拷贝过去,然后启动数据库,使用show tables能看到相关表,但查询不了.

从报错来看就是: 没有创建表, 所以无法查询. 那么我们只需要创建表就可以了. 故有2种方案:
获取表结构, 由于是5.x环境, 表结构是存储在frm中的,所以我们可以使用mysqlfrm,dbsake,ibd2sql等工具来获取表结构, 我这里就使用ibd2sql了(自己写的用着顺手)
python3 main.py /data/mysql_3306/mysqldata/db1/*然后就是创建表并导入表空间了
-- 见表
CREATE TABLE IF NOT EXISTS `db2`.`t20260407_02` (
`id` int DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci;
-- 去掉表空间
alter table `db1`.`t20260407_02` discard tablespace;
-- 拷贝有数据的表空间过来
system cp -ra /root/db1/t20260407_02.ibd /data/mysql_3306/mysqldata/db1
-- 导入表空间
alter table `db1`.`t20260407_02` import tablespace;
-- 验证数据
select * from `db1`.`t20260407_02` limit 1;
然后对需要的表都这么干,就完事了. 比较麻烦, 建议写个脚本(让AI写个也行)
我们知道ibd2sql可以解析mysql 5.x/8.x版本的数据文件为DDL/SQL, 那么我们直接解析并导入数据库就行.
# 一条命令一步到位
python3 main.py /root/db1/* --ddl --sql | mysql -h127.0.0.1 -uroot -p123456
本次是对5.x版本只剩下db目录还是很容易恢复数据的, 毕竟有ibd2sql,实际上就算rm整个目录了, 也可以使用ibd2sql恢复(支持win/linux等磁盘恢复).
会一门技术很重要, 备份也很重要.
题外话: 在某国产操作系统使用我们之前写的抓包脚本来对某国产数据库(mysql系)进行抓包分析问题的时候,需要将脚本中的socket.ntohs(0x0800) 修改为socket.ntohs(0x03), 不然就没得发送的包了.(centos等无需修改)
https://github.com/ddcw/ddcw/blob/master/python/Grace_AuditMySQL.py
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。