MySQL 8.0+ 启用 --skip-grant-tables 后必须用 ALTER USER 'root'@'localhost' IDENTIFIED WITH caching_sha2_password BY 'newpass' 重置密码,因该模式下所有权限表写操作(含 UPDATE、FLUSH PRIVILEGES)均被内核禁止,仅此语法被特例允许。

MySQL 8.0+ 启动 --skip-grant-tables 后执行 ALTER USER 报 ERROR 1290 怎么办
这不是语法写错,而是 MySQL 8.0+ 的硬性限制:只要启用了 --skip-grant-tables,所有对权限表(mysql.user 等)的 DML 操作都会被服务器主动拒绝,连 UPDATE 和 FLUSH PRIVILEGES 都无效。报错信息明确指向这一点:ERROR 1290 (HY000): The MySQL server is running with the --skip-grant-tables option so it cannot execute this statement。
正确做法不是“绕过限制”,而是用它允许的操作路径——ALTER USER ... IDENTIFIED WITH 语句在跳过权限模式下是特例支持的(仅限重置认证方式),但必须显式指定插件名:
- 确认你连接的是本地 socket(如
mysql -u root --socket=/var/lib/mysql/mysql.sock),避免走 TCP 导致权限校验意外触发 - 执行带插件声明的语句:
ALTER USER 'root'@'localhost' IDENTIFIED WITH caching_sha2_password BY 'YourNewPass123'; - 不要加
FLUSH PRIVILEGES—— 此时它无意义,且可能报错 - 退出后,必须正常重启服务(不是 Ctrl+C 杀进程),否则新密码不会持久化到磁盘
为什么 UPDATE mysql.user SET authentication_string = PASSWORD(...) 在部分 8.0 版本也失败
因为从 MySQL 8.0.11 起,PASSWORD() 函数已被标记为废弃;到 8.0.25+ 完全移除。更关键的是,高版本(如 8.0.33+)已彻底禁止在 --skip-grant-tables 模式下对 mysql 库做任何写操作,哪怕你绕过语法检查,底层也会拦截。
所以别试 UPDATE + FLUSH 组合,它只在极早期 8.0 小版本(如 8.0.11–8.0.19)中短暂可行,现在基本等于无效操作。
- 如果你看到
ERROR 3009 (HY000): Column count of mysql.user is wrong,说明数据字典结构不匹配,先运行mysql_upgrade -u root -p(需能登录)或考虑初始化空实例 -
caching_sha2_password是 8.0 默认认证插件,不能省略;若强行用mysql_native_password,后续客户端可能因不支持而连不上 - Windows 用户注意:
--shared-memory必须和--skip-grant-tables一起用,否则mysql -u root可能因找不到有效连接方式而失败
用 --init-file 方式重置密码为何有时没反应
这个方法依赖 MySQL 启动时自动加载并执行 SQL 文件,但它有严格前提:文件路径必须是绝对路径、内容只能是一条完整语句(不能换行、不能含注释)、且 MySQL 必须以该参数启动(不是服务方式)。
- 常见错误:写成
mysqld --init-file=C:\mysql-init.txt但没加--console或后台运行参数,导致窗口一闪而退,根本没执行 - 文件内容必须是单行纯 SQL:
ALTER USER 'root'@'localhost' IDENTIFIED BY 'newpass';—— 多一个空格、分号后多换行,都可能导致静默失败 - Linux 下路径要用双反斜杠或正斜杠:
--init-file=/tmp/mysql-init.sql,且确保 MySQL 进程有读取权限 - 执行完务必立即删除该文件,否则密码明文留在磁盘上,是严重安全隐患
重置后仍提示 Access denied for user 'root'@'localhost'
这通常不是密码没生效,而是 host 匹配失败。MySQL 8.0 默认只创建 'root'@'localhost',不包含 'root'@'127.0.0.1' 或 'root'@'%'。
- 登录时用
mysql -u root -h localhost -p,不要用-h 127.0.0.1(会走 TCP,可能匹配不到) - 检查是否误删了用户:
SELECT User, Host FROM mysql.user WHERE User = 'root';,确认存在localhost行 - 如果之前用
ALTER USER 'root'@'%' ...修改过,但现在只留了localhost,那从远程连就会失败 - 某些客户端(如 MySQL Workbench)默认尝试
127.0.0.1,此时需显式指定连接 host 为localhost(Unix socket)才能命中
ALTER USER ... IDENTIFIED WITH ... BY ...,其他路径要么失效,要么埋下兼容性雷。


















