mysqldump报access denied主因是权限缺失而非密码错误,需授予select、lock tables、show view、trigger四类最小权限,全局process权限用于--single-transaction,且必须执行flush privileges生效。

mysqldump报Access denied:不是密码错,是权限缺
直接结论:mysqldump 报 Access denied for user 'xxx'@'localhost',90% 以上不是输错密码,而是账号没被授予 SELECT、LOCK TABLES、SHOW VIEW、TRIGGER 这四类最小必要权限。哪怕你能用该账号登录 MySQL 并执行 SELECT * FROM t1,也不代表能跑 mysqldump——它会额外查 information_schema、尝试锁表、读视图定义、抓触发器元数据。
验证方式很简单:mysql -u root -p -e "SHOW GRANTS FOR 'backup_user'@'localhost';"
如果返回里只有 USAGE 或只含 SELECT,那就确认缺权限了。
- 必须补全的权限(按需组合):
SELECT(读表)、LOCK TABLES(一致性导出)、SHOW VIEW(库中有视图时必加)、TRIGGER(表有触发器时必加) - 不要用
GRANT ALL PRIVILEGES ON *.*,应限定到具体库:GRANT SELECT, LOCK TABLES, SHOW VIEW ON `app_db`.* TO 'backup_user'@'localhost'; - 授完权后必须执行
FLUSH PRIVILEGES;,否则不生效
mysqldump --single-transaction 仍失败?可能缺 PROCESS 权限
当你加了 --single-transaction 参数(InnoDB 推荐),却仍报类似 Access denied; you need (at least one of) the PROCESS privilege(s),说明 mysqldump 正在尝试读取表空间或线程状态信息——这是默认行为,且 PROCESS 是全局权限,不能按库授予。
典型触发场景:
- 使用了 --all-databases 或未加 --no-tablespaces
- 在 GreatSQL、Percona 或某些启用了 tablespace 管理的 MySQL 变种中
- 解决方法:用 root 执行
GRANT PROCESS ON *.* TO 'backup_user'@'localhost'; FLUSH PRIVILEGES; -
PROCESS权限无法限定到单个数据库,必须全局授予 - 若安全要求极高,可改用
--no-tablespaces参数绕过,但需确认目标库是否依赖表空间特性
备份文件为空或只有 CREATE DATABASE?检查连接参数和库名拼写
导出文件大小为几 KB、打开全是注释或只有 CREATE DATABASE 语句,大概率不是权限问题,而是连接或目标识别失败。
- 确保命令中数据库名拼写完全一致(区分大小写,尤其在 Linux 下):
mysqldump -u user -p app_db中的app_db必须真实存在且用户有访问权限 - 避免依赖
localhost自动走 socket:Docker、多实例或 socket 路径异常时,加-h 127.0.0.1强制走 TCP 连接 - 加
--verbose参数看实时输出,配合2>&1 | grep -i error捕获 stderr 中的真实错误 - 若备份系统库(如
mysql),普通用户默认被禁止;要么用 root,要么显式授权:GRANT SELECT ON mysql.* TO 'backup_user'@'localhost';
还原时报 ERROR 1044 或 No database selected?USE 语句不是万能的
还原时出现 ERROR 1044 (42000): Access denied for user ... to database 'xxx' 或 No database selected,常因 dump 文件结构与导入方式不匹配。
-
mysqldump db_name > backup.sql默认不生成USE db_name;,所以不能直接source backup.sql,必须先USE db_name; - 更稳妥的还原方式是命令行指定库名:
mysql -u user -p db_name - 若 dump 文件开头有
CREATE DATABASE,而用户又没CREATE DATABASE权限,会直接失败——此时删掉开头几行或改用已有库名导入 - 权限还原要分开:建库用 root,赋权用
GRANT CREATE, INSERT, ALTER ON db_name.* TO 'user'@'host';
真正容易被忽略的是:权限必须“精准+全局+刷新”。比如 PROCESS 权限漏掉、FLUSH PRIVILEGES 忘执行、或者误以为 GRANT SELECT ON <em>.</em> 就够了——其实 mysqldump 会跨库查元数据,SELECT 权限必须覆盖 information_schema(通常自动允许)和目标库,其他权限则严格按作用域生效。











