上个月我的办公本在一次断电之后直接开不了机,送修检测说是主板供电出了问题。好在硬盘没坏,把 SSD 拆下来装进移动硬盘盒,还能完整读取。打开之后我第一个想找的不是桌面文件夹,而是里头跑了好几个项目的 MySQL 数据目录——当时手头没有最近的逻辑备份,如果 Data 文件夹也没了,很多本地库就得从头来。好在 datadir 目录完整躺在那儿,于是我花了半天时间,用同版本的 MySQL 8.0 新实例把整份 Data 目录原样接回去,最终所有库和表都恢复正常。
这篇文章就是这次恢复过程的完整复盘。针对的场景是:电脑(或服务器)系统无法启动,但硬盘还能读,MySQL 数据目录 Data 文件夹完整保留,需要通过物理迁移的方式恢复数据库。内容适合本地开发机、内部测试服务器、个人项目等没有条件做完善备份、但极其依赖数据库文件的场景。我会把 8.0 底层文件结构、抢救顺序、实例重建步骤、启动失败排查和上线前收尾全部拆开讲清楚。如果你把 MySQL 装在系统盘且没有单独备库,这篇尤其值得收藏。
1. MySQL 8.0 的 Data 目录里,哪些文件是“缺一不可”,哪些可以删掉再恢复
1.1 datadir 下的文件大盘点
先明确一点:MySQL 8.0 的所有物理文件都集中在配置里 datadir 指向的目录。不管是 Windows 下常见的 C:\ProgramData\MySQL\MySQL Server 8.0\Data,还是自定义的 D:\mysql-data,恢复的核心就是这个文件夹。打开 Data 目录后,你看到的东西是这些:
| 文件/目录 | 迁移时是否必须 | 作用与说明 |
|---|---|---|
mysql.ibd |
必须 | MySQL 8.0 的数据字典和部分系统表。每个库的表结构定义都存在这里,没有它,实例连库表都“不认识” |
ibdata1 |
必须 | InnoDB 系统表空间,传统上承载数据字典的共享信息、部分事务系统数据等。坏掉整个恢复难度直线上升 |
#innodb_redo/ |
强烈建议保留 | 8.0.30 之后 redo log 都放进这个目录。崩溃恢复时靠它把没来得及落盘的数据页重放回来 |
undo_001、undo_002 |
强烈建议保留 | 独立 undo 表空间,保存事务回滚段。异常关机后,启动阶段的事务回滚会依赖它 |
| 各业务库子目录/*.ibd | 必须 | 每个表一个 .ibd 文件,数据行和索引页全在这里。如果没有这张表对应文件,表就救不回来 |
#ib_16384_0.dblwr 等 |
建议保留 | InnoDB doublewrite 缓冲文件,防止半页写损坏用的,属于底层的安全网 |
ib_buffer_pool |
可删可不删 | 缓冲池预热文件,丢了只是第一次启动慢,不影响数据完整性 |
ibtmp1 |
可删 | InnoDB 临时表空间,实例启动会自动重建 |
binlog.00000x、binlog.index |
视情况处理 | 二进制日志。只做数据迁移的话可以删,但如果你后面还想做基于时间点恢复,需要额外规划 |
auto.cnf |
保留即可 | 记录实例的 server_uuid。迁移到新机器如果还要搭主从,确保新环境不和其他实例冲突就行 |
这里最容易判断错的是:只盯着业务库目录拷文件,漏了 mysql.ibd 和 ibdata1。业务库目录里确实全是你的数据,但少了数据字典和系统表空间,新实例把目录放回去也识别不了这些 .ibd 文件属于哪个库哪张表。
1.2 8.0 去掉 .frm 为什么是迁移难度的一次“减负”
用过 MySQL 5.7 及更早版本的人应该对 .frm 文件有印象。5.7 时代每个表在库目录下除了 .ibd 外还配一个 .frm,里面存表结构。直接复制数据目录去另一台实例时,要保证 .frm 和 .ibd 能对上,一旦
