mysqldump --all-databases 默认跳过 mysql 库是因为当前用户缺乏其 select 权限,且静默忽略不报错;需用 root 或授权账号执行,或手动单独备份 mysql 库。

mysqldump --all-databases 备份时为什么漏掉 mysql 系统库?
默认情况下,mysqldump --all-databases 并不会真正备份所有库——它会跳过 information_schema、performance_schema 和 sys,这没问题;但关键在于:如果当前用户没有 mysql 库的 SELECT 权限,mysql 库也会被静默跳过,且不报错。
常见错误现象:mysqldump --all-databases 生成的 SQL 文件里找不到 CREATE DATABASE `mysql` 或任何 mysql.user 表内容,恢复后权限全丢。
- 必须用具有
SELECT权限(且推荐LOCK TABLES+RELOAD)的账号执行,例如 root 或专用备份账户 - 加
--skip-lock-tables可能导致部分表 dump 不一致,除非明确接受风险 - 若仍漏
mysql,手动补一句:mysqldump --databases mysql --single-transaction > mysql.sql
--all-databases 和 --databases mysql information_schema ... 的区别
--all-databases 是自动发现当前实例中所有「可读」数据库并逐个 dump,而 --databases 是显式列出库名,不检查权限,遇到不可读库直接报错退出。
使用场景:需要可控、可审计的备份范围时,宁愿多写几个库名,也不依赖 --all-databases 的自动扫描逻辑。
-
--all-databases隐含--databases行为,但无法排除某个库(比如不想备份 test_* 开头的库) - 想排除某些库?只能用脚本先查
SHOW DATABASES,过滤后再拼--databases db1 db2 -
--databases支持空格分隔多个库名,但不能带引号或通配符
备份文件里出现 USE 语句但没 CREATE DATABASE?
这是 mysqldump --all-databases 的默认行为:它只在首次进入每个库时输出 USE `db_name`,但是否输出 CREATE DATABASE 取决于有没有加 --add-drop-database 或 --include-databases 类参数。
后果:直接 source 恢复时,若目标实例不存在该库,会报错 Unknown database。
- 加
--add-drop-database会在每个USE前加DROP DATABASE IF EXISTS和CREATE DATABASE - 更稳妥的做法是加
--databases显式指定库,并配合--add-drop-database - 注意:
--add-drop-database必须和--databases同时用才生效,单独对--all-databases无效
gzip 压缩与 --single-transaction 的兼容性问题
很多人习惯写成 mysqldump --all-databases | gzip > backup.sql.gz,这本身没问题;但若加上 --single-transaction,要注意:管道阻塞可能导致事务等待超时,尤其在大库或慢 IO 场景下。
错误现象:mysqldump: Got error: 1205: Deadlock found when trying to get lock 或备份中途断开。
- 优先用
--compress(客户端压缩),而非 shell 管道压缩,减少进程间延迟 - 大库建议拆成单库 dump + 并发压缩,比全库单进程更稳
-
--single-transaction仅对 InnoDB 有效,MyISAM 表仍会锁表;混合引擎库慎用
实际备份命令建议从权限校验开始:先 mysql -e "SHOW DATABASES" 看是否列全,再确认当前用户对 mysql 库有无 SELECT 权限。漏掉权限验证这步,后面所有优化都白搭。










