90%的mysqldump问题源于权限、字符集或锁表策略:需检查select/lock tables权限,强制指定--default-character-set=utf8mb4防乱码,innodb用--single-transaction避免锁表,myisam则禁用该参数,还原前须手动建库。

直接用 mysqldump 备份,90% 的问题出在权限、字符集或锁表策略上,不是命令写错,而是没对齐上下文。
权限不足导致备份失败:SHOW GRANTS 是第一检查项
执行 mysqldump -u backup -p mydb > b.sql 报错 Access denied; you need (at least one of) the SELECT privilege(s)...,说明账号没拿到对应库的 SELECT 和 LOCK TABLES 权限。
- 先确认当前用户权限:
mysql -u root -p -e "SHOW GRANTS FOR 'backup'@'localhost';" - 最小权限授权(别用 root 直接跑):
GRANT SELECT, LOCK TABLES ON mydb.* TO 'backup'@'localhost'; - 如果加了
--single-transaction,还得补上:GRANT REPLICATION CLIENT ON *.* TO 'backup'@'localhost'; - 改完记得
FLUSH PRIVILEGES;
中文乱码:file -i 和 SET NAMES 必须同时验证
备份文件里中文变 ???,不是数据库存错了,是连接层编码没对齐。即使库是 utf8mb4,mysqldump 默认走 latin1。
- 查库实际编码:
SHOW CREATE DATABASE mydb;看DEFAULT CHARACTER SET - 导出时强制指定:
mysqldump --default-character-set=utf8mb4 -u backup -p mydb > b.sql - 验证输出文件:
file -i b.sql应返回charset=utf-8;head -n 5 b.sql应含SET NAMES utf8mb4 - 漏掉
--default-character-set参数,哪怕库是utf8mb4,也会丢字节
InnoDB 表备份卡住或锁表太久:--single-transaction 不是万能开关
mysqldump 默认对所有表加全局读锁(FLUSH TABLES WITH READ LOCK),InnoDB 表必须显式启用快照机制才能避免锁表。
- 只对 InnoDB 表加:
--single-transaction—— 它依赖 MVCC,要求事务隔离级别为REPEATABLE READ(默认满足) - 绝对不要对 MyISAM 表加
--single-transaction:无效,照样锁全库;只能靠--lock-tables=false+ 业务低峰期操作 - 提速可选:
--skip-triggers --skip-routines --skip-events,尤其触发器/存储过程多的库明显减少导出量 - 大库建议管道压缩:
mysqldump -u backup -p --single-transaction mydb | gzip > b.sql.gz,比生成大文件再gzip更省内存
还原时报 Unknown database 或表不存在:CREATE DATABASE 不是默认行为
mysqldump mydb > b.sql 导出的文件不带 CREATE DATABASE 语句,还原前必须手动建库,否则报错。
- 安全建库命令:
mysql -u backup -p -e "CREATE DATABASE IF NOT EXISTS mydb CHARACTER SET utf8mb4;" - 还原命令:
mysql -u backup -p mydb (注意这里指定了库名) - 想让导出文件自带
CREATE DATABASE,必须加--databases(复数!):mysqldump --databases mydb > b.sql - 如果用了
--all-databases或--databases,还原时不能指定库名,直接mysql -u backup -p
真正容易被忽略的是:--single-transaction 对事务隔离级别的隐式依赖,以及 --databases 这个复数参数——少个 s 就会导致还原流程完全跑偏。










