唯一能暴露权限缺失、字符集错配等隐藏问题的是走通完整恢复流程;必须在mysqldump完成后立即执行md5sum生成校验值并保存为同名.md5文件,恢复前用md5sum -c严格验证,仅显示“backup.sql: OK”才可导入。

备份文件能解压、能导入、甚至没报错,不等于它在灾难时真能用。唯一暴露权限缺失、字符集错配、GTID 不兼容、binlog 断链等隐藏问题的,是走通一次完整恢复流程。
用 md5sum -c 验证备份文件是否被截断或静默损坏
MySQL 自身不校验写入内容,磁盘坏道、NFS 缓存异常、写入中断都可能导致 backup.sql 看似存在,实则末尾缺失几 KB。这类损坏不会在导入初期报错,而是中途突然语法错误或乱码。
- 必须在
mysqldump完成后立刻执行:mysqldump -u root db > backup.sql && md5sum backup.sql > backup.sql.md5 -
backup.sql.md5必须和备份文件同目录、同名,且权限设为600(避免被意外覆盖) - 恢复前执行:
md5sum -c backup.sql.md5,只看到backup.sql: OK才可继续;若显示FAILED,立即停手,查df -h是否磁盘满、dmesg | tail是否有 I/O 错误 - 别用
md5sum backup.sql打屏比对——人眼不可靠,也留不下自动验证痕迹
用 gzip -t 和 zcat | head 快速筛掉损坏压缩包
很多故障卡在第一步:gzip 层已损坏,但没人检查。直接导入只会等到中途报 Invalid or incomplete deflate data 才发现。
-
gzip -t backup.sql.gz返回0表示压缩格式完好;非0就别往下试了 - 进一步确认 SQL 可读:
zcat backup.sql.gz | head -n 30 | grep -q "CREATE DATABASE",能匹配上才算“开头合法” - 若报
gzip: stdin: not in gzip format,说明文件根本不是 gzip(可能是传输中断或重命名错误) - 别用
gzip -d全量解压大文件——既慢又占磁盘;-t是无副作用的真轻量校验
用 tail -n 20 检查 SQL 文件末尾是否完整
md5sum 匹配只能说明文件没被篡改或传输损坏,但无法发现 mysqldump 进程被 kill、磁盘满导致的“半截 SQL”——典型表现是最后一行不是 UNLOCK TABLES; 或缺失 COMMIT;。
- 用
tail -n 20 backup.sql(或zcat backup.sql.gz | tail -n 20)确认结尾有UNLOCK TABLES;和-- Dump completed on行 - 检查是否有明显中断痕迹:比如最后几行全是
INSERT INTO ... VALUES (,((括号未闭合)、或突然出现ERROR 2013等报错残留 - 对 InnoDB 表,可快速扫描是否存在
SET AUTOCOMMIT = 0;开头 +COMMIT;结尾的事务块;缺失COMMIT往往意味着 dump 被强制终止
用 mysqlcheck --check 暴露表结构与权限问题
语法通 ≠ 表结构全。常见漏掉 CREATE TABLE、字段类型被截断、视图 DEFINER 用户不存在等问题,mysqlcheck 能当场暴露。
- 恢复到临时库后执行:
mysqlcheck -u root -p --check test_restore,看到OK才算过第一关 - 若提示
Table 'xxx' doesn't exist,大概率是备份时加了--no-create-info或mysqldump版本太低漏导了某些表 - 对关键业务表,再补一句:
CHECKSUM TABLE important_table;,记下返回值;恢复后在测试库执行同样语句比对,一致才说明内容未变
真正难控的不是命令怎么写,而是校验动作和备份动作之间的时间耦合度——你得确保 mysqldump 进程退出后,md5sum 立刻开始读那个文件,中间不能有 shell 调度延迟、IO 队列堆积或 NFS 缓存干扰。


















