根本原因是写入被硬中断导致文件系统元数据与磁盘内容不一致,而非文件被清空;常见于ext4/xfs未启用data=ordered模式或mysqld被kill-9中断,MyISAM本身无原子写入保障。

MyISAM 表在突然断电时出现 .MYI 或 .MYD 文件大小为 0,根本原因不是“文件被清空”,而是写入过程被硬中断,导致文件系统元数据与实际磁盘内容不一致——常见于 ext4/xfs 等日志型文件系统未启用 data=ordered 或 data=writeback 模式,或 MySQL 进程被 kill -9 中断后缓存未落盘。
MySQL 的 MyISAM 引擎本身不提供原子写入保障,它依赖操作系统和文件系统的同步行为。当断电发生时:
-
mysqld正在向.MYI(索引文件)追加或重写索引块,但只完成了部分 write() 系统调用,内核页缓存还没 flush 到磁盘 - 文件系统记录的 inode 中的 size 字段可能已被提前更新(例如 truncate 后未写完),而实际磁盘扇区仍是全零或旧垃圾数据
- 更典型的情况是:
.MYI文件头被覆写为全零(如 magic number 被擦除),myisamchk -s读取时直接判定 “not a MyISAM-table” 或 “file is empty”,ls -l显示 size=0,但stat可能显示 blocks > 0 —— 这说明文件系统分配了空间,但数据没写进去
为什么不是所有文件都变 0?因为损坏具有随机性:
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
-
.FRM是只读结构定义,通常不会被修改,所以极少变 0 -
.MYD(数据文件)若正处在 INSERT … SELECT 或 LOAD DATA 过程中,也可能截断为 0,但概率低于.MYI—— 因为索引更新更频繁、更细粒度 - 如果断电瞬间恰好卡在
myisam_log日志回放阶段(极少见),还可能残留临时文件tbl_name.TMD,其 size 也可能为 0
别误判为磁盘故障 —— 先用 file /var/lib/mysql/db/tbl.MYI 看输出是否为 “data” 或 “empty”,再用 hexdump -C -n 32 /var/lib/mysql/db/tbl.MYI 查前 32 字节:正常 MyISAM 文件开头是 0x01 0x00 0x00 0x00(版本号+header length),全零即确认头部损毁
修复时不能跳过校验直接 myisamchk -r —— 对 size=0 的 .MYI,该命令会报 Can't open file 并退出;必须先恢复文件长度(从备份拷回原始 .MYI),或改用 --safe-recover --force 强制从 .MYD 提取行重建索引(前提是 .MYD 未损毁且非零)










