能恢复,但必须立刻停止写入,且仅适用于myisam表:需确认.myd文件未被覆盖,立即停服务、卸载分区,用extundelete或debugfs恢复文件,再通过myisamchk修复并验证完整性。

能恢复,但必须立刻停止写入,并且只在 MyISAM 表上才有可能从文件层面抢救——InnoDB 不适用这套流程。
确认误删的是 MyISAM 表且文件未被覆盖
MyISAM 的数据物理存储为三个独立文件:.frm(表结构)、.MYD(数据)、.MYI(索引)。误删后,只要这些文件没被新数据覆盖,就有机会找回。
- 立即执行
sudo systemctl stop mysql,防止 MySQL 自动清理或重用磁盘空间 - 检查文件系统是否还在原位置:
ls -l /var/lib/mysql/数据库名/表名.*,如果.MYD文件已消失,但磁盘剩余空间没明显增长,说明可能只是被 unlink,内容还在 - 不要重启服务器、不要运行
fsck、不要写入任何大文件——这些都会加速覆盖
用 extundelete 或 debugfs 恢复 .MYD 文件
Linux 文件系统(如 ext3/ext4)删除文件时,只是清除了 inode 中的链接,原始数据块可能仍在。关键看是否已被覆盖。
- 卸载对应分区(如
/dev/sda1),或至少确保 MySQL 和所有写进程已停:sudo umount /var/lib/mysql(若挂载点独立) - 运行
sudo extundelete /dev/sda1 --inode 0列出可恢复的 inode,再用--restore-inode或--restore-file尝试恢复表名.MYD - 若
extundelete不支持当前文件系统,改用debugfs:先sudo debugfs /dev/sda1,再用lsdel查找已删除的.MYD,用dump <inode> ./recovered.MYD</inode>提取 - 恢复出的
.MYD文件需配合原.frm(如有备份)或从其他同结构表复制,.MYI通常需重建
修复并加载恢复的 MyISAM 文件
即使成功找回 .MYD,也不能直接放回目录启动 MySQL——校验和、索引、行计数都可能不一致。
- 把恢复的
.MYD放到对应数据库目录下,保持文件名一致;若无.frm,从备份或同结构表拷贝一份 - 运行
myisamchk -r -v /var/lib/mysql/数据库名/表名强制修复(-r表示 recover,-v显示详情) - 修复失败常见于:索引损坏严重、
.MYI缺失且无法重建、.MYD被部分覆盖——此时只能用myisamchk --safe-recover尝试更保守的恢复 - 修复完成后,启动 MySQL,用
SELECT COUNT(*) FROM 表名和CHECK TABLE 表名验证数据完整性
为什么不能指望 binlog 或 ROLLBACK?
MyISAM 不支持事务,所以 ROLLBACK 对它完全无效;binlog 虽然记录了 DROP TABLE 或 DELETE,但它不存数据快照,无法还原被删的行内容。
-
SHOW VARIABLES LIKE 'log_bin'返回ON只说明日志开启,但DELETE FROM 表名这类语句在STATEMENT格式下只记语句本身,没数据;即使ROW格式,也只记录删除前的行镜像——前提是日志没过期且你有权限读取 - MyISAM 表的
REPAIR TABLE命令仅适用于文件已存在但结构损坏的情况,对已删除的文件毫无作用 - 别试图用
INSERT INTO ... SELECT从其他库“猜”数据——MyISAM 没 MVCC,没 undo log,也没 flashback query 功能
真正有效的抢救窗口往往只有几分钟:从发现误删到停服务、卸载分区、运行恢复工具。一旦 .MYD 所在的数据块被覆盖,就再无软件层面的补救余地。











