数据库导出脚本|3个参数漏了就白导

脚本能跑通,和导出来的文件能用,是两码事。数据库导出脚本|3个参数漏了就白导——这话不是吓人,是因为命令行里一行 mysqldump 谁都会敲,真正让人半夜被电话叫起来的问题,几乎都不在那行命令本身。文件生成了,几百兆躺在那,看着挺踏实,恢复到测试库一打开:中文全是问号,或者订单表和明细表的行数根本对不上。这篇文章就把这三处最容易漏的参数掰开讲,外加几个脚本层面的阴坑。

数据库

数据库导出脚本|3个参数漏了就白导,第一个是字符集

–default-character-set=utf8mb4 这个参数,太多人觉得不用管,理由特别统一:我库本来就是 utf8mb4 啊。但 mysqldump 走的是它自己那条连接,连接层的字符集不跟着库的设置走,老版本客户端默认还可能给你来个 latin1。结果就是导出时一切安静,导入之后中文变问号、生僻字变方块、emoji 直接消失,而且不报错。更阴的是二次损坏——备份文件头部那几行 SET NAMES,有人恢复的时候顺手改成了别的编码,一改一个准,再想从这份文件里捞回来基本没戏。

也别一把梭全写 utf8mb4。历史遗留库还有 latin1 的,源库到底是什么,去看 SHOW CREATE DATABASE 的输出,或者 select @@character_set_database,别靠记忆。源库、导出的参数、目标库这三个环节的字符集得对得上,对不上就是白导。

一致性这个参数,业务不停机的时候最要紧

–single-transaction。InnoDB 下它会先开一个事务,整份导出都读这个一致性快照,中途别人下单、退款、改库存,你导出来的仍然是同一瞬间的数据。不加它,导出过程就是一边读一边变:几十 G 的库跑上半小时,用户余额和流水、订单和明细,各自处在不同时刻,单独看都对,放一起账就不平。拿这份去恢复,错的不是数据本身,是你的账。

有两个细节顺手说。一是它只管事务引擎,MyISAM 的表得靠 –lock-tables 锁写,混着用的时候心里要有数;二是它和 –lock-all-tables 别同时写,互相打架。另外要连 binlog 位置一起记下来的话,是 –source-data(老版本叫 –master-data),这个参数名字改过,具体写法以你们那版官方文档为准,别照抄别人的脚本。

第三个参数藏在账号里,导入端才炸

用 root 导库,这事不算错,错在导出来的东西把身份也一起带走了。视图、触发器、存储过程里头是带 DEFINER 的,写着 DEFINER=root@localhost 或者 root@%。目标库没有这个账号、或者 host 对不上,导入到一半直接报权限相关的错,前面几十张表白恢复。处理办法就那么几种:导的时候干脆不导触发器,导完把 DEFINER 段替换掉,或者目标端先把同名账号建好。别嫌麻烦,这个坑几乎每个迁移过库的人都踩过。

权限不够也会静默出问题。账号只能读一部分表,mysqldump 会把错误吐到 stderr、退出码非 0,可脚本里要是写成 cmd; next_cmd 而不是 cmd && next_cmd,它照旧往下跑,最后还给你打印一句完成。这种就叫白导——文件是有的,内容是残缺的,谁也不知道缺了哪张表。还有一种情况,受限账号读不到表空间信息,直接报错,加 –no-tablespaces 绕过去就行。

脚本本身的坑,比参数还阴

mysqldump | gzip 这么写最省事,也最容易骗自己。前面失败、后面成功,整条管道的退出码是 gzip 的 0。要么 set -o pipefail,要么老老实实看 PIPESTATUS。set -e 也不一定救你,管道里它盯的是最后一个命令。

再就是环境。crontab 里的 PATH 和你登录 shell 里的不是同一套,mysqldump 可能压根找不到;密码明文写在命令行,ps 一眼看光,弄个 600 权限的 –defaults-extra-file 靠谱得多;临时目录别往 /tmp 扔,很多系统定时清,导到一半文件没了,你还在等它跑完。

跑在云数据库上的还要多看一眼。厂商一般给只读账号加内网地址,脚本得在白名单里,公网硬拉大文件又慢又容易被限速。这一块各家的规则不一样,以服务商控制台和官方页面说明为准,别拿别人的配置直接套。

导完怎么验,别只盯着文件大小

文件尾巴有没有那句 Dump completed,这是最基本的一道。然后 grep 一下 CREATE TABLE 的条数,跟源库的表数量对一对,差得多的直接重导。真要放心,挑几张核心表恢复到临时库,count 一下行数,别信统计信息,那玩意儿本来就有偏差。不方便全量恢复的大库,抽几张关键表验,也比拍脑袋强。

一段能直接抄的模板

mysqldump –defaults-extra-file=/root/.my.cnf –single-transaction –quick –default-character-set=utf8mb4 –routines –triggers –events –hex-blob –source-data=2 shop | gzip > /data/backup/shop_$(date +%F).sql.gz

几个点解释一下。–quick 是不把整张大表读进内存;–hex-blob 让二进制字段不至于把文件搞坏;–routines –triggers –events 把存储过程、触发器、定时事件一起带上,这三个要是不带,恢复完业务逻辑全是空的,表面看数据都在,程序跑起来到处报错。参数顺序无所谓,但别漏。

最后提醒一句,参数别靠脑子记,写死在脚本里,改的时候留个注释说明为什么这么写。备份这东西,没真正恢复过一次,就默认它不可用。

【版权声明】:本站内容若无意侵犯到您的权利,请及时与我们联系将尽快删除相关内容!

赞 (0)
爱家的头像爱家
SPF是什么算法;搞错它邮件容易进垃圾箱
上一篇 2026-11-12 13:42
如何配置服务器以支持多用户同时登录?
下一篇 2024-11-16 21:32

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

广告合作

QQ:14239236

在线咨询: QQ交谈

邮件:asy@cxas.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信