「MySQL 修改 root 密码」这条搜索词下流传着大量老写法——SET PASSWORD ... = PASSWORD('newpass')、UPDATE mysql.user SET Password=...——这些在 MySQL 5.7.6 之后陆续失效,8.0 里更是直接报语法错误。PASSWORD() 函数在 8.0 已被移除,mysql.user.Password 列也已改名为 authentication_string。本文按版本把可用的方法梳理清楚,并给出忘记 root 密码时的两种重置方案。
一、动手前先确认版本
SELECT VERSION();
-- 5.7.6 / 8.0 是两条分界线:
-- PASSWORD() 函数:5.7.6 起废弃,8.0 移除
-- mysql.user.Password 列:5.7.6 起改名 authentication_string版本决定用哪种写法:
| 版本 | 推荐写法 |
|---|---|
| MySQL 5.7.6+ / 8.0 | ALTER USER ... IDENTIFIED BY |
| MySQL 5.6 及更早 | SET PASSWORD ... = PASSWORD(...) 或 UPDATE 授权表 |
二、常规修改方式
方式 1:ALTER USER(5.7.6+ / 8.0 首选)
-- 已用 root 登录的情况下修改自己的密码
ALTER USER 'root'@'localhost' IDENTIFIED BY 'NewPass@2026';
-- 用有权限的账号修改别的 root 记录(注意 host 部分要匹配实际记录)
ALTER USER 'root'@'%' IDENTIFIED BY 'NewPass@2026';
FLUSH PRIVILEGES; -- 用 ALTER USER 时其实不需要,加上也无害ALTER USER 是当前官方推荐的方式,它直接操作账号,不需要 FLUSH PRIVILEGES。
方式 2:SET PASSWORD
-- 5.7.6+ / 8.0:等号右边写明文,不能再用 PASSWORD() 包起来
SET PASSWORD FOR 'root'@'localhost' = 'NewPass@2026';
-- 修改当前登录账号自己的密码
SET PASSWORD = 'NewPass@2026';
-- 5.6 及更早的写法(8.0 执行会报错)
SET PASSWORD FOR 'root'@'localhost' = PASSWORD('NewPass@2026');语法本身在 5.7 / 8.0 仍可用,但已被弱化、官方建议改用 ALTER USER,新写的脚本直接用方式 1 即可。
方式 3:mysqladmin(不用先登录)
# root 当前没有密码
mysqladmin -u root password 'NewPass@2026'
# root 已有密码:用 -p 带上旧密码,新密码作为 password 的参数
mysqladmin -u root -p'OldPass' password 'NewPass@2026'
# 建议写成一行的形式,避免 -p 与密码之间出现空格被当成库名
注意网上常见的 mysqladmin -u root password oldpass "newpass" 是错误写法——旧密码必须通过 -p 选项传入,不能作为位置参数。mysqladmin 改密码后同样不需要 FLUSH PRIVILEGES。
方式 4:直接 UPDATE 授权表(仅 5.6 及更早,或应急)
-- MySQL 5.6 及更早
USE mysql;
UPDATE user SET Password = PASSWORD('NewPass@2026') WHERE User = 'root';
FLUSH PRIVILEGES;
-- MySQL 5.7.6+:列名已改为 authentication_string
UPDATE user SET authentication_string = 'NewPass@2026' WHERE User = 'root';
FLUSH PRIVILEGES;这种方式必须 FLUSH PRIVILEGES,否则内存中的授权表不会刷新。它属于绕过账号管理接口直接改表,容易漏掉 Host 条件(一条 WHERE User='root' 可能改掉多行)以及权限插件相关字段,非必要不要用。
四种方式对比
| 方式 | 适用版本 | 需要 FLUSH PRIVILEGES | 说明 |
|---|---|---|---|
ALTER USER |
5.7.6+ / 8.0 | 否 | 首选,语义清晰 |
SET PASSWORD |
5.6+(写法有差异) | 否 | 可用,官方建议改用 ALTER USER |
mysqladmin |
全版本 | 否 | 无需登录,适合脚本 |
UPDATE mysql.user |
5.6 及更早 | 是 | 应急用,列名随版本变化 |
三、8.0 特有的两个坑
1. 客户端不认 caching_sha2_password
MySQL 8.0 默认认证插件是 caching_sha2_password,一些老客户端(旧版 Navicat、老 JDBC 驱动、部分语言的老驱动)连不上,报 Authentication plugin 'caching_sha2_password' cannot be loaded。可以临时把账号改回旧插件:
ALTER USER 'root'@'localhost'
IDENTIFIED WITH mysql_native_password BY 'NewPass@2026';更推荐的做法是升级客户端或驱动,而不是长期停留在 mysql_native_password(该插件在 MySQL 8.4 已默认禁用)。
2. 弱密码被拒绝
启用了 validate_password 组件时,设置简单密码会报错:
ERROR 1819 (HY000): Your password does not satisfy the current policy requirements默认策略要求密码长度至少 8 位,且包含大小写字母、数字和特殊字符。查看当前策略:
SHOW VARIABLES LIKE 'validate_password%';测试环境想放宽可以调整策略,生产环境不建议为了省事降低要求。
四、忘记 root 密码时怎么重置
方案 A:跳过权限校验(--skip-grant-tables)
# 1. 先停掉正在运行的实例
systemctl stop mysqld # Linux
# net stop mysql80 # Windows
# 2. 以跳过授权表的方式启动,务必同时加 --skip-networking
mysqld_safe --skip-grant-tables --skip-networking &
# Windows 没有 mysqld_safe,用:
# mysqld --console --skip-grant-tables --skip-networking
# 3. 免密登录
mysql -u root-- 此时直接 ALTER USER 会报 ERROR 1290,必须先刷新授权表
FLUSH PRIVILEGES;
-- 5.7.6+ / 8.0
ALTER USER 'root'@'localhost' IDENTIFIED BY 'NewPass@2026';
-- 5.6 及更早
UPDATE mysql.user SET Password = PASSWORD('NewPass@2026') WHERE User = 'root';
FLUSH PRIVILEGES;
# 4. 正常重启实例(去掉 --skip-grant-tables),再用新密码登录验证
systemctl restart mysqld一定要加 --skip-networking:只加 --skip-grant-tables 相当于向整个网络开放了免密 root 登录,如果这台机器端口对公网可达,等于直接交出数据库。
方案 B:用 init-file(8.0 推荐)
官方推荐的另一种做法:准备一个只包含改密语句的 SQL 文件,让实例启动时执行一次,不需要跳过授权表、也不需要手工 FLUSH。
-- /root/mysql-init.sql 内容
ALTER USER 'root'@'localhost' IDENTIFIED BY 'NewPass@2026';# 停实例后用 init-file 启动
mysqld --init-file=/root/mysql-init.sql &
# Windows:
# mysqld --console --init-file=C:\mysql-init.sql
# 启动成功后停掉,删除该文件(文件里是明文密码),再正常启动
rm -f /root/mysql-init.sqlinit-file 里的密码是明文,文件权限要收紧(如 chmod 600),用完即删。
五、改完密码别忘了同步这些地方
- 应用连接串 / 配置中心:Spring 的
datasource.password、环境变量、K8s Secret 等。 - 客户端工具里保存的连接:Navicat、DataGrip、DBeaver 里的旧密码。
- 含有明文口令的配置文件:
my.cnf/my.ini的[client]、[mysql]、[mysqldump]段,备份脚本、监控和巡检脚本。 - 主从复制的凭据:复制账号若也是 root 或同名账号,需要用
CHANGE REPLICATION SOURCE TO ... PASSWORD='...'(5.7 为CHANGE MASTER TO)更新,并START REPLICA。 - 定时任务与运维工具:MHA / Orchestrator、pt-toolkit 脚本、Cron 里的备份命令。
六、速查卡
-- 5.7.6+ / 8.0 首选
ALTER USER 'root'@'localhost' IDENTIFIED BY 'NewPass@2026';
-- 兼容旧客户端(8.0)
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'NewPass@2026';
-- 当前登录账号改自己的密码
SET PASSWORD = 'NewPass@2026';
-- 5.6 及更早
SET PASSWORD FOR 'root'@'localhost' = PASSWORD('NewPass@2026');
UPDATE mysql.user SET Password = PASSWORD('NewPass@2026') WHERE User = 'root';
FLUSH PRIVILEGES;mysqladmin -u root -p'OldPass' password 'NewPass@2026' # 无需登录改密码
# 忘记密码:跳过授权表
systemctl stop mysqld
mysqld_safe --skip-grant-tables --skip-networking &
mysql -u root
# FLUSH PRIVILEGES; 然后 ALTER USER 'root'@'localhost' IDENTIFIED BY '新密码';
systemctl restart mysqld
评论区