搞数据库的人,谁没经历过那种心跳骤停的瞬间?MySQL突然崩了,数据表打不开,业务系统直接挂掉,老板在群里@你,客户在电话里骂娘。这时候你最想干的事,就是赶紧把备份的SQL文件倒进去。命令,就是那个能把文件里的数据重新灌进MySQL的家伙。它看起来简单,就一行,但真到了救命的时候,用不好就是给自己挖坑。我干这行快十年了,踩过的坑能装满一个机房,今天就把那些用命换来的实战技巧掰开揉碎讲给你听。

第一个技巧,先把“自动提交”关掉。很多人一上来就敲,结果跑到一半报错,前面的数据全白干了。MySQL默认是自动提交模式,每执行一条INSERT语句就写一次磁盘。你那个备份文件可能有几十万条INSERT,每一条都触发一次磁盘I/O,速度慢得像乌龟爬。更可怕的是,如果中途断电或者内存爆了,前面已经提交的数据还能用,但后半截没跑完的怎么办?数据库处于一个半死不活的状态,你都不知道哪些表是完整的、哪些是残缺的。正确做法是,在执行source之前,先敲一句,然后跑完整个SQL文件后,再手动敲。这样一来,所有数据都在一个事务里,要么全进,要么全不进。出了问题,直接回滚重来,省得你半夜对着屏幕抓头发。
第二个技巧,关掉二进制日志。很多生产环境为了主从复制,开着。你执行source恢复数据的时候,每一条INSERT、UPDATE都会被记录到二进制日志里。一个1GB的SQL文件,恢复进去之后,二进制日志可能膨胀到2GB甚至更多。这不仅拖慢恢复速度,还会让从库也跟着重放这些操作——等于你恢复一次数据,所有从库都得跟着重新跑一遍。如果你的备份文件本来就是从主库导出来的,这些操作已经被记录过了,完全没必要再写一次。所以在执行source之前,临时关掉二进制日志:。恢复完记得再打开,不然主从复制就断了。这个操作需要SUPER权限,一般DBA都有,但如果你的账号权限不够,就得找运维配合了。
第三个技巧,调大。备份文件里那些大字段,比如存了图片base64编码的、存了JSON大对象的,一条INSERT可能就有几十MB。MySQL默认的只有4MB或者16MB,一旦碰到超过这个大小的SQL语句,source直接就报错退出。你想想,跑了两个小时,一条大SQL卡住了,前面的全白费。解决方案很简单,在执行source之前,先跑到MySQL配置文件里把改成256MB甚至1GB。如果不想改配置文件,也可以在MySQL命令行里临时设置:。不过要注意,这个设置只对后续新建的连接生效,你当前这个连接需要重连一下才行。另外,导出备份的时候也可以提前处理,用来生成文件,这样导出的SQL本身就带着大包设置。
第四个技巧,用管道或者拆分文件来处理超大SQL。有的人直接拿着10GB的SQL文件跑source,结果等了三个小时还没跑完,服务器内存飙到90%,OOM被系统kill了。source命令本身没有进度条,你完全不知道它跑到哪一步了,卡了还是死了。这时候有两个办法。一个是直接用管道,把压缩的SQL文件解压后直接喂给mysql客户端,比如。这样省了先解压再导入的步骤,而且可以利用操作系统的管道缓冲,内存占用更可控。另一个办法是把大文件拆成小块。用命令按行数拆分:,然后逐个source这些小文件。拆完之后,你可以用先数一下总行数,跑完一个文件就打个勾,心里有数。更骚的操作是写个脚本,每跑完一个文件就记录进度,万一中间崩了,从断点接着跑就行。
第五个技巧,先跑建表语句,再跑数据。很多备份文件是混在一起的,前面CREATE TABLE,后面INSERT INTO。如果表结构特别复杂,比如有外键约束、有触发器、有存储过程,source跑起来很容易因为依赖顺序问题报错。比如A表引用了B表的外键,但B表还没建,直接报错。解决办法是把备份文件里的建表语句和数据插入语句分开。用或者把CREATE TABLE的部分单独拎出来,先执行一遍,确认所有表结构都建好了,再执行数据插入。如果表之间有循环依赖,那更麻烦,得先关掉外键检查,等数据全跑完了再重新开启。这个操作千万记得,否则你跑完数据发现外键检查失败,一堆孤儿数据,查都查不完。
这五个技巧,每一个都是用惨痛教训换来的。我记得有一次帮一家电商公司恢复数据,他们的备份文件有8GB,直接source跑了四个小时,结果中间网络断了,全白干。后来加了上面这些操作,同样的数据量,四十分钟搞定,而且中途出错了也能快速回滚重来。source命令看着简单,但真正用好它,得理解它背后的执行机制——事务、日志、内存、外键,每一个环节都可能成为瓶颈或者隐患。
说一句,恢复数据之前,最好先在测试环境跑一遍。别拿生产环境当试验田,你永远不知道备份文件里藏着什么坑。备份文件不检验,等于没备份。source命令是你的救命稻草,但前提是你知道怎么用它。把这五个技巧记下来,下次遇到MySQL崩溃,你至少能稳住心态,一步一步把数据捞回来。毕竟,数据就是钱,丢了就是真金白银的损失。


