删数据库文件前必须确认mysqld已停止,否则可能导致启动失败或实例崩溃;物理备份须包含ibdata1、ib_logfile*等全部InnoDB系统文件,遗漏将致数据不可用。

删数据库文件前必须确认 mysqld 已停止
直接删 ibdata1、ib_logfile0 或某个库的 xxx.ibd 文件,而 mysqld 还在跑,轻则启动失败,重则整个实例崩溃。MySQL 启动时会校验这些文件的元数据和 LSN,残留锁或未刷盘日志会导致 recovery 失败,报错类似 InnoDB: Database page corruption on disk 或 Cannot continue operation。
- 先执行
systemctl stop mysql(或service mysqld stop),确认进程已退出:ps aux | grep mysqld应无有效进程 - 不要只 kill -9 进程就以为停了——InnoDB 可能正写 checkpoint,得等彻底退出
- 若用 Docker,别只
docker stop就删文件;进容器看mysqladmin ping是否响应,再查/var/lib/mysql/下是否有mysql.sock或mysqld.pid
物理备份必须包含全部 InnoDB 系统文件
只 tar 包 /var/lib/mysql/your_db/ 目录是无效备份。InnoDB 是共享表空间架构(尤其 innodb_file_per_table=OFF 时),ibdata1 存着数据字典、undo log、系统表;ib_logfile* 是 redo 日志,启动 recovery 必需。漏掉任一,恢复后可能表存在但查不到数据,或 SHOW TABLES 不显示。
- 完整备份命令示例:
tar -czf mysql-202405-backup.tgz /var/lib/mysql/ibdata1 /var/lib/mysql/ib_logfile* /var/lib/mysql/mysql/ /var/lib/mysql/your_old_db/ /var/lib/mysql/ib_buffer_pool - 注意:如果启用了
innodb_redo_log_encrypt,还得备份keyring_file_data或对应 keyring 插件配置,否则还原后无法读 redo - 备份后务必校验:
tar -tzf mysql-202405-backup.tgz | head -20看路径是否全,再tar -tzf ... | wc -l和原目录find /var/lib/mysql -type f | wc -l对比数量
删除旧版本文件时区分“可删”和“强依赖”
不是所有带日期或版本号的文件都能删。比如 mysql-bin.000001 是 binlog,删了主从同步就断;auto.cnf 里存着 server-uuid,删了再启可能被从库拒绝连接;ca.pem/server-cert.pem 是 SSL 证书,删了加密连接直接失败。
- 安全可删:
your_old_db_202203.ibd(明确命名的老库文件)、ibtmp1(临时表空间,停库后删不影响,重启自建)、mysql-slow.log(慢日志,非核心) - 严禁手删:
ibdata1、ib_logfile0、mysql/全目录、performance_schema/、sys/、auto.cnf、server-key.pem - 不确定的先
mv到临时目录(如/tmp/mysql-old-stash/),观察一周无异常再rm -rf
删完重启前检查 my.cnf 的 innodb_force_recovery
删过文件又恢复过备份,启动时容易卡在 InnoDB 初始化阶段。此时若配置了 innodb_force_recovery > 0,MySQL 会跳过某些 recovery 步骤强行启动,但可能导致数据不一致——比如跳过 undo 回滚,让已删除的记录“复活”。这个参数只该用于紧急导出数据,绝不能长期开着运行。
- 启动前检查:
grep innodb_force_recovery /etc/my.cnf,如果不是注释状态,必须删掉或设为=0 - 若启动失败且报
Operating system error number 2 in a file operation,大概率是删了文件但没清掉datadir下的 socket/pid 文件,或 selinux 拦截了访问,别急着加 force_recovery - 真正需要 force_recovery 时,从
=1开始试,每级最多试 1 分钟,到=6仍失败就该怀疑备份损坏
实际操作中最容易被忽略的是:删文件后忘记同步修改 my.cnf 里的 datadir 路径,或迁移后没改 SELinux 上下文(chcon -R -t mysqld_db_t /var/lib/mysql/)。这些不会报错,但 MySQL 会静默降级为只读模式,连 CREATE TABLE 都拒绝。


















