如何通过多选导出操作高效备份特定数据库?
- 内容介绍
- 相关推荐
本文共计1059个文字,预计阅读时间需要5分钟。
相关专题:
mysqldump 一次导出多个数据库:用 --databases 而不是 -B 的别名陷阱
直接给结论:想备份多个指定库(比如 user_db、order_db、log_db),必须用 mysqldump --databases user_db order_db log_db,而不是加 -b 后再拼接——两者行为一致,但 -b 容易让人误以为能“批量读取列表”,实际它只是 --databases 的简写,不支持从文件或管道读库名。
常见错误现象:mysqldump -B $(cat db_list.txt) 看似合理,但一旦 db_list.txt 里有空格、特殊字符或换行异常,命令就直接报错 Unknown database 'xxx' 或跳过部分库。
- 必须确保每个库名是独立参数,不能靠 shell 展开“蒙混过关”
- 库名中含短横线(如
api-v2)没问题,但若含反引号或引号,需手动转义 -
--databases模式下,导出文件会自动包含CREATE DATABASE IF NOT EXISTS和USE语句,恢复时不用提前建库
跳过某些表导出:用 --ignore-table 要写全名,且不支持通配符
备份多个库时,常想排除日志表、临时表(比如所有库里的 audit_log 表),但 --ignore-table 必须写成 db_name.table_name 格式,而且每张表要单独写一次参数。
例如:排除 user_db.audit_log 和 order_db.tmp_report,命令得这么写:
mysqldump --databases user_db order_db log_db \ --ignore-table=user_db.audit_log \ --ignore-table=order_db.tmp_report
容易踩的坑:
- 写成
--ignore-table=audit_log(缺库名)→ 直接忽略失败,该表仍会被导出 - 想用
--ignore-table=*.audit_log→ 不支持通配符,报错退出 - 多个
--ignore-table参数顺序无关,但漏写一个库前缀,就等于没忽略
导出文件按库拆分:不用脚本也能实现,靠 --result-file 配合循环
如果希望每个库一个 SQL 文件(如 user_db.sql、order_db.sql),mysqldump 本身不支持单次命令生成多个文件,但不必写复杂脚本——用 shell 循环最稳。
使用场景:运维需要把不同业务库分发给不同团队,或避免单文件过大导致恢复失败。
- 简单安全的做法:
for db in user_db order_db log_db; do mysqldump --databases "$db" > "${db}.sql" done
- 不要用
mysqldump --all-databases | split之类方式——无法精准切分,且丢失库级元信息 - 若库名来自文件,用
while read -r db; do ...,注意read默认裁剪首尾空格,带空格的库名要用IFS=保护
权限和连接问题:备份多库时 SELECT 权限必须覆盖全部目标库
执行 mysqldump --databases A B C 时,用户账号必须对 A、B、C 每个库都有 SELECT(以及 SHOW VIEW、LOCK TABLES 等辅助权限),缺一个就会中断并报错 Access denied for user ... to database 'B'。
为什么这点容易被忽略?因为连上 MySQL 后,SHOW DATABASES 只显示你有权限看到的库,但 mysqldump 是逐个库尝试连接并查询,不会跳过无权限库。
- 检查权限用:
SHOW GRANTS FOR 'backup_user'@'%'; - 授予权限示例:
GRANT SELECT, SHOW VIEW, LOCK TABLES ON `user_db`.* TO 'backup_user'@'%';(每个库都要单独授权) - 用
--single-transaction时,还要求引擎为 InnoDB,否则会退化为锁表,影响线上
最麻烦的其实是权限分散在不同账号下——没法用一个命令统一备份,只能分账号执行,或改用具有全局权限的专用备份账号。
本文共计1059个文字,预计阅读时间需要5分钟。
相关专题:
mysqldump 一次导出多个数据库:用 --databases 而不是 -B 的别名陷阱
直接给结论:想备份多个指定库(比如 user_db、order_db、log_db),必须用 mysqldump --databases user_db order_db log_db,而不是加 -b 后再拼接——两者行为一致,但 -b 容易让人误以为能“批量读取列表”,实际它只是 --databases 的简写,不支持从文件或管道读库名。
常见错误现象:mysqldump -B $(cat db_list.txt) 看似合理,但一旦 db_list.txt 里有空格、特殊字符或换行异常,命令就直接报错 Unknown database 'xxx' 或跳过部分库。
- 必须确保每个库名是独立参数,不能靠 shell 展开“蒙混过关”
- 库名中含短横线(如
api-v2)没问题,但若含反引号或引号,需手动转义 -
--databases模式下,导出文件会自动包含CREATE DATABASE IF NOT EXISTS和USE语句,恢复时不用提前建库
跳过某些表导出:用 --ignore-table 要写全名,且不支持通配符
备份多个库时,常想排除日志表、临时表(比如所有库里的 audit_log 表),但 --ignore-table 必须写成 db_name.table_name 格式,而且每张表要单独写一次参数。
例如:排除 user_db.audit_log 和 order_db.tmp_report,命令得这么写:
mysqldump --databases user_db order_db log_db \ --ignore-table=user_db.audit_log \ --ignore-table=order_db.tmp_report
容易踩的坑:
- 写成
--ignore-table=audit_log(缺库名)→ 直接忽略失败,该表仍会被导出 - 想用
--ignore-table=*.audit_log→ 不支持通配符,报错退出 - 多个
--ignore-table参数顺序无关,但漏写一个库前缀,就等于没忽略
导出文件按库拆分:不用脚本也能实现,靠 --result-file 配合循环
如果希望每个库一个 SQL 文件(如 user_db.sql、order_db.sql),mysqldump 本身不支持单次命令生成多个文件,但不必写复杂脚本——用 shell 循环最稳。
使用场景:运维需要把不同业务库分发给不同团队,或避免单文件过大导致恢复失败。
- 简单安全的做法:
for db in user_db order_db log_db; do mysqldump --databases "$db" > "${db}.sql" done
- 不要用
mysqldump --all-databases | split之类方式——无法精准切分,且丢失库级元信息 - 若库名来自文件,用
while read -r db; do ...,注意read默认裁剪首尾空格,带空格的库名要用IFS=保护
权限和连接问题:备份多库时 SELECT 权限必须覆盖全部目标库
执行 mysqldump --databases A B C 时,用户账号必须对 A、B、C 每个库都有 SELECT(以及 SHOW VIEW、LOCK TABLES 等辅助权限),缺一个就会中断并报错 Access denied for user ... to database 'B'。
为什么这点容易被忽略?因为连上 MySQL 后,SHOW DATABASES 只显示你有权限看到的库,但 mysqldump 是逐个库尝试连接并查询,不会跳过无权限库。
- 检查权限用:
SHOW GRANTS FOR 'backup_user'@'%'; - 授予权限示例:
GRANT SELECT, SHOW VIEW, LOCK TABLES ON `user_db`.* TO 'backup_user'@'%';(每个库都要单独授权) - 用
--single-transaction时,还要求引擎为 InnoDB,否则会退化为锁表,影响线上
最麻烦的其实是权限分散在不同账号下——没法用一个命令统一备份,只能分账号执行,或改用具有全局权限的专用备份账号。

