如何确认当前 root 用户的权限范围
直接查
mysql.user表最可靠,避免依赖客户端提示或历史印象:
SELECT Host, User, authentication_string, account_locked, password_expired FROM mysql.user WHERE User = 'root';
注意
Host字段——
'localhost'和
'%'是两个完全独立的账户,权限不互通。很多“root 登不进”问题其实是连到了
'%'而非
'localhost',或者反过来。
重置 root 密码并开放远程访问(MySQL 8.0+)
如果已锁死或忘记密码,需跳过权限验证启动 MySQL:
停掉 mysqld,加--skip-grant-tables --skip-networking启动(仅本机临时用) 连上去后先刷新权限:
FLUSH PRIVILEGES;改密码必须用
ALTER USER(旧版
SET PASSWORD在 8.0+ 已废弃):
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_new_pass';要允许远程登录,得显式创建或更新
'root'@'%':
CREATE USER 'root'@'%' IDENTIFIED BY 'same_or_diff_pass'; GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
别漏掉
FLUSH PRIVILEGES;,否则权限不生效;也别省略
WITH GRANT OPTION,否则该用户无法再授予权限给他人。
GRANT 语句中容易被忽略的权限细节
ALL PRIVILEGES看似全包,但实际不含
GRANT OPTION和
PROXY权限,必须单独加:
GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost';→ 不带授予权,不能帮别人开权限
GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION;→ 才真正等价于旧版“超级用户” 若要用
CREATE USER或
DROP USER,需确保有
CREATE USER权限(它不在
ALL PRIVILEGES里,但
GRANT OPTION会隐含它)
另外,
ON *.*中第一个
*是数据库名,第二个是表名;写成
ON `db_name`.*就只对指定库生效,不是全局。
为什么 root 用户有时仍被拒绝执行某些操作
常见原因不是权限不够,而是 SQL mode、安全变量或插件限制:
开启sql_mode=STRICT_TRANS_TABLES时,
INSERT缺字段可能报错,看起来像权限问题
read_only=ON会让 root 也无法写入(除非同时设
super_read_only=OFF) 使用
caching_sha2_password插件但客户端不支持(如老版本 PHP mysqli),会卡在认证阶段,报错类似
Authentication plugin 'caching_sha2_password' cannot be loadedSELinux 或防火墙拦截了 3306 端口,导致远程连接失败,和权限无关
遇到“明明给了 ALL 还报错”,先查
SHOW VARIABLES LIKE '%read_only%';和
SELECT @@sql_mode;,比反复 GRANT 更快定位。
