mysqldump报error 1045或access denied,根本原因是mysql 8.0.32+启用--single-transaction时强制触发flush tables with read lock,必须显式授予reload权限,并执行flush privileges生效;仅select和lock tables不足,且需确保host精确匹配、权限按库限定。

mysqldump报ERROR 1045或Access denied,其实是缺RELOAD权限
不是密码错、不是输错用户名,而是mysqldump在启用--single-transaction时,MySQL 8.0.32+ 版本会**强制触发FLUSH TABLES WITH READ LOCK(即FTWRL)**,这一步必须有RELOAD权限。哪怕你只备份InnoDB表,只要用的是官方MySQL 8.0.32及以上,默认就会走FTWRL + STWCS双阶段,没RELOAD就直接报错。
- 检查当前用户是否真有
RELOAD:用root登录后执行SHOW GRANTS FOR 'backup_user'@'localhost';,看输出里有没有RELOAD - 别只给
SELECT, LOCK TABLES——这两项不够,RELOAD是8.0.32+的硬性新增依赖 - 远程备份时注意host匹配:
'backup_user'@'%'和'backup_user'@'localhost'是两个不同账号,权限不互通
GRANT RELOAD时必须搭配LOCK TABLES和SELECT
RELOAD本身不读数据、不锁表,它只是让mysqldump能执行FLUSH类命令。但实际备份流程中,FLUSH TABLES WITH READ LOCK之后还要读表、查视图、锁对象,所以必须配套授权:
-
SELECT:读取所有表内容(必需) -
LOCK TABLES:配合RELOAD完成全局读锁(尤其当--single-transaction降级失败时) -
SHOW VIEW:如果库中有视图,缺这个会卡在元数据查询阶段 - 不要用
GRANT ALL PRIVILEGES ON *.*——最小范围限定到目标库,例如:GRANT SELECT, RELOAD, LOCK TABLES, SHOW VIEW ON `app_db`.* TO 'backup_user'@'localhost';
FLUSH PRIVILEGES没执行,新权限就是无效的
授完权不运行FLUSH PRIVILEGES;,MySQL不会加载新权限配置。这是最常被跳过的一步,导致反复试错。
- 执行完
GRANT语句后,**必须在同一连接里立即执行FLUSH PRIVILEGES;** - 确认生效:再跑一遍
SHOW GRANTS FOR 'backup_user'@'localhost';,确保输出包含刚加的权限 - 如果用脚本批量授权,记得把
FLUSH PRIVILEGES;写在最后——它不能被事务包裹,也不能省略
用Percona Server绕过RELOAD依赖(仅限8.0.32+)
如果你用的是MySQL官方版8.0.32或更新,又不想开RELOAD(比如安全策略禁止),可以换用Percona Server for MySQL 8.0.32-24+。它的mysqldump修复了这个回归问题:
- 对纯InnoDB库,
--single-transaction只发START TRANSACTION WITH CONSISTENT SNAPSHOT,不再触发FTWRL - 开启GTID时,加
--set-gtid-purged=OFF即可完全规避RELOAD需求 - 注意:Percona版不改变权限模型本身,只是优化了命令下发逻辑——所以换版本前先验证你的备份脚本参数是否兼容
真正麻烦的不是加权限,而是误以为“--single-transaction就不用锁”而漏掉RELOAD;更麻烦的是授了权却忘了FLUSH PRIVILEGES;,然后花半小时排查网络或密码问题。











