远程备份用户必须显式指定host(如'192.168.10.5'),不能依赖localhost;reload为全局权限需on .授予,lock tables为库级权限须按业务库逐个授予(如on app_db.),二者不可混用on .*,且无论是否使用--single-transaction,lock tables均不可省略。

远程备份用户必须显式指定 host,不能依赖 localhost
MySQL 的权限是「用户+host」联合判定的,'backup_user'@'localhost' 和 'backup_user'@'%' 是两个完全不同的账号。远程备份时,连接来源是外部 IP(比如 192.168.10.5 或公网地址),若只授了 @'localhost' 权限,mysqldump -h 192.168.10.10 会直接报 Access denied for user——不是权限不够,而是根本没匹配到账号。
正确做法是:创建时明确用实际客户端 IP 或通配符(慎用):
CREATE USER 'bkp_remote'@'192.168.10.5' IDENTIFIED BY 'strong_pass_2026';
或者仅限内网段:
CREATE USER 'bkp_remote'@'192.168.10.%' IDENTIFIED BY 'strong_pass_2026';
不建议直接用 @'%',除非有防火墙或网络层严格限制访问源。
RELOAD 和 LOCK TABLES 权限必须分开授权,且作用域不同
RELOAD 是全局权限,只能授在 *.* 上;LOCK TABLES 是库级权限,必须按业务库显式授予。混用 ON *.* 授两者,看似省事,实则违反最小权限原则,且可能被云数据库(如阿里云 RDS)拒绝执行。
-
RELOAD:用于FLUSH TABLES WITH READ LOCK等操作,只允许写GRANT RELOAD ON *.* TO 'bkp_remote'@'192.168.10.5'; -
LOCK TABLES:必须限定到具体库,例如GRANT LOCK TABLES ON `app_db`.* TO 'bkp_remote'@'192.168.10.5'; - 如果备份多个库,每个库都要单独授
LOCK TABLES,不能靠ON *.*覆盖
漏掉任意一个,mysqldump 在启用 --master-data 或回退到全局锁时就会卡在 Access denied; you need (at least one of) the RELOAD privilege(s) 或 LOCK TABLES privilege(s)。
远程场景下 LOCK TABLES 权限常被误判为“可省略”
有人看到文档说 --single-transaction 可避免锁表,就以为远程备份可以不给 LOCK TABLES。这是危险误解:
-
--single-transaction仅对 InnoDB 表生效,一旦库中混有 MyISAM 表,mysqldump会自动 fallback 到LOCK TABLES,此时缺权限直接失败 - 即使全是 InnoDB,若事务开启失败(如长事务阻塞、隔离级别异常),
mysqldump仍会尝试加锁,报错信息往往不提示原因,只显示Access denied for user ... when using LOCK TABLES - 远程链路延迟更高,事务一致性更难保障,保留
LOCK TABLES是兜底必需项
所以无论是否加 --single-transaction,只要用 mysqldump 做远程逻辑备份,LOCK TABLES 必须授,且必须按库授。
RELOAD 权限在远程备份中最容易被忽略的副作用
RELOAD 看似只是让 FLUSH 命令能跑通,但它实际还影响 --master-data 和 --flush-logs 的行为:
- 没有
RELOAD,--master-data=2会失败并报Couldn't execute 'FLUSH /*!40101 LOCAL */ TABLES',无法获取 binlog 位置,导致后续增量恢复断点丢失 -
--flush-logs(常用于备份前滚动日志)也依赖RELOAD,否则跳过但不报错,容易误以为成功 - 某些 MySQL 版本(尤其是 5.7 早期)在
--single-transaction失败后,会静默尝试FLUSH TABLES WITH READ LOCK,此时缺RELOAD会导致备份中途退出,而错误日志里只有一行模糊的mysqldump: Got error: 1227
真正该警惕的不是“要不要加”,而是“加了之后是否真生效”——务必用 SHOW GRANTS FOR 'bkp_remote'@'192.168.10.5'; 验证输出里确实包含两行独立的 RELOAD ON *.* 和 LOCK TABLES ON `xxx`.*。跨库备份时,每库一行 LOCK TABLES 缺一不可。











