MyISAM表固定生成三个文件:.MYD存数据、.MYI存B+Tree索引、.frm存表结构;删.MYD则数据丢失但表定义仍可查,.MYD按插入顺序追加且无事务支持。

MyISAM 表文件到底有几个?每个干啥的
MyISAM 表在磁盘上固定生成三个文件:.MYD(数据)、.MYI(索引)、.frm(表结构定义)。它们彼此独立,删掉 .MYD 就真没数据了,但表还能 SHOW CREATE TABLE 出来——因为 .frm 还在。
-
.MYD是纯数据堆,按插入顺序追加,不支持事务、崩溃恢复弱,断电后容易损坏 -
.MYI里存 B+Tree 索引,主键和二级索引结构一样,都指向.MYD的物理偏移 -
.frm在 MySQL 5.7 及以前是必须的;8.0 后被数据字典取代,但兼容模式下仍可能生成
InnoDB 的 .ibd 文件为什么不能直接复制粘贴
.ibd 是自包含的表空间文件,但不是“即插即用”的镜像——它内部记录了表空间 ID(space_id)、页校验、undo 段指针等运行时元数据。直接拷贝到另一实例,mysqld 启动时会发现 space_id 和数据字典里不匹配,报错 Tablespace is missing for table xxx 或更隐蔽的 InnoDB: Operating system error number 2 in a file operation。
- 跨实例迁移必须用
mysqldump或mysqlpump导出逻辑 SQL,或走FLUSH TABLES WITH READ LOCK+ALTER TABLE ... IMPORT TABLESPACE流程 - 同一实例内重命名表,
.ibd文件名会变,但space_id不变;删除表后该space_id可能被复用,所以旧.ibd即使放回原路径也大概率打不开 -
innodb_file_per_table=ON(默认)才为每张表生成独立.ibd;关掉后所有表共用ibdata1,没法单独操作
查表实际占多少磁盘空间?别只看 ls -lh
.ibd 文件大小 ≠ 实际有效数据量。InnoDB 有预留页、碎片、未 purge 的 undo 日志、B+Tree 空隙,ls -lh 显示的可能是 2GB,但 SELECT SUM(data_length + index_length) FROM information_schema.tables 返回可能只有 300MB。
- 真正反映“可回收空间”的是
DATA_FREE字段:SELECT data_free FROM information_schema.tables WHERE table_name = 'xxx';值大于 0 说明有碎片,OPTIMIZE TABLE或ALTER TABLE ... ENGINE=InnoDB能重建 - MyISAM 的
.MYD基本等于真实数据体积(压缩表除外),DATA_LENGTH字段基本准;但.MYI大小受索引选择性影响大,高频重复值建索引会导致索引膨胀 - 监控时优先采样
information_schema,而不是文件系统,否则误判容量风险高
从 .ibd 或 .MYD 恢复数据?先确认你有没有权限读原始页
没有备份、又丢了 ibdata1 或 frm 文件时,硬解析 .ibd 或 .MYD 是最后手段,但成功率极低:InnoDB 页头有 checksum,MyISAM 的 .MYD 依赖 .MYI 的索引结构才能定位行记录,缺一不可。
- 开源工具如
mysql-utilities的mysqlfrm可尝试从.frm提取建表语句;undrop-for-innodb能扫描.ibd找残留记录,但要求表没被覆盖写过 - MyISAM 更麻烦:
.MYD是定长/变长混合格式,没.MYI就不知道字段偏移和 NULL 标志位在哪,几乎无法还原 - 线上库务必开启
innodb_checksum_algorithm=crc32(默认),避免静默损坏;MyISAM 表定期跑myischk --check,但别在运行中执行
文件结构差异背后是存储引擎设计哲学的根本不同:MyISAM 图快图简单,InnoDB 图稳图一致。想靠文件名或大小做判断,十次有九次踩坑。










