MySQL 更改用户密码:ALTER USER 命令(MySQL 5.7 / 8.0)+ Root 密码恢复

目次

1. [Quick Answer] MySQL 用户密码更改命令列表(最快的解决方案)

在 MySQL 中更改用户密码的基本命令是 ALTER USER
此方法在 MySQL 5.7 及更高版本中推荐使用,在 MySQL 8.0 中也以相同方式使用。

1.1 基本语法(最常用)

ALTER USER 'username'@'localhost' IDENTIFIED BY 'newpassword';
  • username : 要更新的目标用户名
  • localhost : 客户端主机(MySQL 账户由 “用户名 + 主机” 标识)
  • newpassword : 新密码

执行后,修改会立即生效。在大多数情况下,不需要 FLUSH PRIVILEGES;(ALTER USER 会自动更新权限表)。

常见陷阱

  • 即使用户名相同,@'localhost'@'%' 也被视为不同的账户
  • 密码中的符号必须用单引号括起来

1.2 更改远程访问用户(%

ALTER USER 'username'@'%' IDENTIFIED BY 'newpassword';

% 表示 “任意主机”。
它常用于云环境或允许从外部连接的用户。

注意

  • 预先使用 SELECT User, Host FROM mysql.user; 检查更安全
  • 如果为错误的 Host 更改密码,将无法登录

1.3 在指定身份验证插件的情况下更改密码(在 8.0 中重要)

在 MySQL 8.0 中,默认的身份验证插件是 caching_sha2_password
如果使用旧客户端无法连接,需要显式设置插件。

ALTER USER 'username'@'localhost'
IDENTIFIED WITH mysql_native_password
BY 'newpassword';
  • mysql_native_password : 传统方法(兼容性优先)
  • caching_sha2_password : MySQL 8.0 标准(推荐)

典型错误

  • 较旧的 PHP 或客户端可能不支持 MySQL 8.0 默认插件
  • 在未检查身份验证插件的情况下就判断 “我无法登录”

1.4 如果出现权限错误

错误示例:

ERROR 1227 (42000): Access denied; you need (at least one of) the SYSTEM_USER privilege(s)

在这种情况下,当前登录的用户没有权限进行更改。

检查:

SHOW GRANTS FOR CURRENT_USER();

以 root 身份或具有足够权限的用户运行该命令。

1.5 更改后如何验证

SELECT User, Host, plugin FROM mysql.user WHERE User='username';
  • 通过 plugin 列检查身份验证插件
  • 最可靠的检查方式是实际登录并确认连接

1.6 已有会话会怎样

更改密码后:

  • 新的连接必须使用新密码
  • 现有会话可能会根据环境立即被终止
  • 在生产环境中,建议在业务时间之外进行更改

2. MySQL 用户与主机基础(防止常见的“卡住”问题)

在 MySQL 中,用户不仅仅由 “用户名” 标识,而是由 “用户名 + 客户端主机(Host)” 的组合 标识。如果不了解这一点,可能会遇到经典问题:“我已经更改了密码,但仍然无法登录。”

2.1 用户是 “user@host” 对

示例:

  • 'appuser'@'localhost'
  • 'appuser'@'%'
  • 'appuser'@'192.168.1.%'

这些 都被视为不同的账户。因此,即使为 localhost 更改了密码,也不会影响 % 账户。

检查命令:

SELECT User, Host FROM mysql.user ORDER BY User, Host;

常见陷阱

  • 没有意识到同一用户名可能对应多个账户
  • 您为 localhost 更改了密码,但实际是通过 TCP(127.0.0.1)登录

2.2 localhost 与 127.0.0.1 被区别对待

在 MySQL 中:

  • localhost → UNIX 套接字连接(本地内部连接)
  • 127.0.0.1 → TCP/IP 连接

根据环境的不同,可能匹配到不同的账户。

检查:

mysql -u username -p -h 127.0.0.1

如果您无法使用上述方法登录,则 @'127.0.0.1' 帐户可能不存在。

2.3 检查当前已认证的用户

理解“您以哪个帐户身份认证”很重要。

SELECT CURRENT_USER();

这将显示实际认证的“user@host”。

SELECT USER(); 显示连接请求信息,因此可能不匹配。

2.4 检查权限 (SHOW GRANTS)

如果您无法更改密码,权限不足可能是原因。

SHOW GRANTS FOR 'username'@'host';

或者针对当前登录用户:

SHOW GRANTS FOR CURRENT_USER();

最低所需权限

  • ALTER USER
  • SYSTEM_USER (MySQL 8.0 及更高版本)

2.5 典型失败模式

  1. 您为错误的 Host 更改了密码
  2. 认证插件不同(在 8.0 中非常常见)
  3. 目标帐户从一开始就不存在

检查用户是否存在:

SELECT User, Host FROM mysql.user WHERE User='username';

一旦您理解此模型,就可以避免大多数与密码更改相关的问题。

3. 推荐程序:使用 ALTER USER 安全更改 (适用于 MySQL 8.0 / 5.7)

在 MySQL 5.7 及更高版本中,使用 ALTER USER 更改密码是标准且推荐的方法
UPDATE mysql.user 这样的直接更新可能会根据版本表现不同,并带来未来的兼容性风险,因此最好避免使用它们。

3.1 预检查 (更改前始终确认)

在更改密码之前,确认以下三项。

① 确认目标用户和 Host

SELECT User, Host FROM mysql.user WHERE User='username';
  • 检查是否存在多个具有相同用户名的帐户
  • 不要将 localhost% 混淆

② 确认当前认证插件 (在 8.0 中很重要)

SELECT User, Host, plugin
FROM mysql.user
WHERE User='username';
  • caching_sha2_password (MySQL 8.0 标准)
  • mysql_native_password (遗留插件)

某些连接失败是由认证插件引起的。

③ 确认当前已认证的用户

SELECT CURRENT_USER();

为了避免权限错误,请以 root 或具有适当权限的用户身份运行命令。

3.2 运行 ALTER USER (标准形式)

ALTER USER 'username'@'localhost'
IDENTIFIED BY 'NewStrongPassword123!';

更改立即生效。
在大多数情况下,不需要 FLUSH PRIVILEGES;

注意事项

  • 如果违反密码策略 ( validate_password ),可能会发生 ERROR 1819
  • 如果密码包含特殊字符,请始终用单引号括起来

3.3 在指定认证插件的同时更改 (仅在需要时)

如果您在 MySQL 8.0 环境中使用较旧的客户端:

ALTER USER 'username'@'localhost'
IDENTIFIED WITH mysql_native_password
BY 'NewStrongPassword123!';

应该更改的情况:

  • 无法使用旧 PHP / 旧 MySQL 客户端连接
  • 不支持 caching_sha2_password 的环境

不应该更改的情况:

  • 如果在现代环境中已经可以无问题连接 (标准插件更安全)

3.4 更改后的验证

① 验证认证插件

SELECT User, Host, plugin
FROM mysql.user
WHERE User='username';

② 通过实际登录验证

mysql -u username -p

始终测试您是否可以登录。

3.5 对现有会话的影响

更改密码后:

  • 新连接 → 必须使用新密码
  • 现有连接 → 可能根据环境保留
  • 生产环境 → 可能需要重启应用程序连接

常见错误

  • 未更新应用程序的连接凭据
  • 配置文件中仍保留旧密码

3.6 生产环境的安全操作提示

  • 在业务时间之外进行更改
  • 提前检查应用程序配置文件
  • 在不断开 SSH 会话的情况下完成工作
  • 更改 root 时,确保已有恢复方法准备就绪

4. MySQL 8.0 与 5.7 的差异

更改 MySQL 密码时最常出现的问题是 MySQL 8.0 与 5.7 之间的认证方式差异
尤其是,许多 “我已经修改了但仍然无法登录” 的情况都是由于认证插件的不同导致的。

Diagram showing the difference between MySQL 5.7 mysql_native_password and MySQL 8.0 caching_sha2_password authentication methods

MySQL 5.7 与 MySQL 8.0 之间的认证差异

4.1 默认认证插件的差异

VersionDefault authentication plugin
MySQL 5.7mysql_native_password
MySQL 8.0caching_sha2_password

在 MySQL 8.0 中,caching_sha2_password 成为标准,以提供更强的安全性。
然而,较旧的客户端(旧版 PHP、旧版 MySQL 连接器等)可能不支持该插件。

如何检查:

SELECT User, Host, plugin
FROM mysql.user
WHERE User='username';

常见问题

  • 旧客户端无法连接在 MySQL 8.0 上创建的用户
  • 即使出现错误,也未意识到根本原因是认证插件

4.2 为兼容性切换认证插件的方法

仅在必须从旧环境连接时,按如下方式进行更改:

ALTER USER 'username'@'localhost'
IDENTIFIED WITH mysql_native_password
BY 'NewStrongPassword123!';

更改后,务必运行连接测试。

注意事项

  • 从安全角度来看,caching_sha2_password 更安全
  • 不要无故切换到旧插件
  • 如有可能,优先升级客户端

4.3 不推荐直接使用 UPDATE

在 MySQL 5.7 及更早版本中,常使用如下方法:

UPDATE mysql.user
SET authentication_string=PASSWORD('newpassword')
WHERE User='username';
FLUSH PRIVILEGES;

然而,这种做法存在以下问题:

  • 高度依赖版本
  • 在 8.0 中可能因规范变更而失效
  • 将来可能被废弃

经验法则:使用 ALTER USER

4.4 validate_password 插件的行为差异

在 MySQL 5.7 与 8.0 中,密码策略(强度检查)功能默认启用。

检查方式:

SHOW VARIABLES LIKE 'validate_password%';

如果违反策略,可能会得到如下提示:

ERROR 1819 (HY000)

.

由于许多 8.0 环境强制更严格的安全基线,
从 5.7 升级后,可能会发现密码更改因更高的策略要求而无法通过。

4.5 如何检查你的版本

如果不确定正在运行的版本:

SELECT VERSION();

如果在未确认版本的情况下直接应用修复,可能会使用错误的方法。

5. 恢复忘记的 root 密码(安全导向的步骤)

如果忘记了 MySQL root 用户(管理员)密码,就无法正常登录。
此时必须 临时禁用授权表并重置密码。但此过程存在安全风险,请务必仔细按照步骤操作。

5.1 确认是否真的需要 root 密码

首先检查以下内容:

  • 是否拥有 OS 级别的 sudo 权限
  • 是否启用了 auth_socket 认证(在基于 Ubuntu 的系统中常见)

示例检查:

SELECT User, Host, plugin
FROM mysql.user
WHERE User='root';

如果 pluginauth_socket,则可能以 OS root 用户身份登录。

sudo mysql

如果此方式可行,则只需重置密码即可。

5.2 恢复流程(通用步骤)

① 停止 MySQL 服务

sudo systemctl stop mysql

② 以禁用授权表的方式启动

sudo mysqld_safe --skip-grant-tables &

--skip-grant-tables 会关闭认证。
在此状态下,任何人都可以连接,因此请尽快完成后续操作。

③ 连接到 MySQL

mysql -u root

此时可以在不输入密码的情况下连接。

④ 重置 root 密码(推荐方法)

ALTER USER 'root'@'localhost'
IDENTIFIED BY 'NewStrongPassword123!';

重要提示

  • 请勿直接使用 UPDATE mysql.user
  • 使用 ALTER USER(兼容不同版本)

⑤ 重新启用授权表

FLUSH PRIVILEGES;

⑥ 以正常模式重启 MySQL

sudo systemctl restart mysql

然后验证正常登录:

mysql -u root -p

5.3 常见错误

  • 保持 --skip-grant-tables 处于启用状态(严重的安全风险)
  • 不小心更改了 root 的 Host
  • 错误地更改身份验证插件导致自己被锁定

5.4 生产环境注意事项

  • 始终在公共服务器的维护窗口期间执行此操作
  • 工作时保持 SSH 会话活跃
  • 如有可能,请提前创建备份

如果谨慎执行,Root 密码恢复可以安全完成。

6. 常见错误及解决方案(按错误信息捕获流量)

在更改 MySQL 密码时会出现多种典型错误。
下面我们按常见的错误代码整理了原因和解决方案。

6.1 ERROR 1819(密码不符合策略要求)

错误示例:

ERROR 1819 (HY000): Your password does not satisfy the current policy requirements

原因

密码未通过 validate_password 插件强制的强度校验。

检查当前策略

SHOW VARIABLES LIKE 'validate_password%';

重要设置:

  • validate_password.length
  • validate_password.policy
  • validate_password.mixed_case_count
  • validate_password.number_count
  • validate_password.special_char_count

解决方案 ①(推荐):使用更强的密码

  • 至少 12 个字符
  • 包含大写字母、小写字母、数字和符号
  • 避免使用字典单词

解决方案 ②(临时放宽策略)

SET GLOBAL validate_password.policy = LOW;

完成任务后,建议恢复原始设置。

常见错误

  • 在生产环境中保持策略放宽
  • 忽视更改此设置需要 SUPER 权限

6.2 ERROR 1227(权限不足)

错误示例:

ERROR 1227 (42000): Access denied; you need (at least one of) the SYSTEM_USER privilege(s)

原因

当前用户缺少 ALTER USERSYSTEM_USER 权限。

检查权限

SHOW GRANTS FOR CURRENT_USER();

解决方案

以 root 身份或具有足够权限的用户执行该命令。

如有必要:

GRANT ALTER USER ON *.* TO 'username'@'host';
FLUSH PRIVILEGES;

注意

  • 在 MySQL 8.0 中,可能还需要 SYSTEM_USER 权限
  • 在生产环境中遵循最小权限原则

6.3 更改密码后无法登录

主要原因

  1. Host 错误
  2. 身份验证插件不匹配
  3. 客户端不兼容
  4. 应用配置未更新

① 检查 Host

SELECT User, Host FROM mysql.user WHERE User='username';

② 检查身份验证插件

SELECT plugin FROM mysql.user WHERE User='username';

③ 更改身份验证插件(如有必要)

ALTER USER 'username'@'localhost'
IDENTIFIED WITH mysql_native_password
BY 'NewStrongPassword123!';

④ 检查应用配置

  • .env
  • config.php
  • 连接字符串(DSN)

常见错误

  • 更改了 MySQL 但未更新应用
  • 在 Docker 环境中未重启容器

6.4 更改后仍能使用旧密码登录

通常,使用 ALTER USER 所做的更改会立即生效。

可能原因:

  • 实际上更改了不同 Host 的账户
  • 连接指向了另一台服务器(副本)
  • 会话缓存

检查:

SELECT CURRENT_USER();

关键在于准确确认所连接的服务器和已认证的用户。

7. 安全运维:密码策略与最佳实践

Changing a password is not a one-time task.
更改密码不是一次性任务。

In real-world operations, you maintain security by combining strength enforcement, privilege design, and operational rules.
在实际运维中,您通过结合强度强制、特权设计和运维规则来维护安全。

7.1 使用 validate_password 插件

MySQL provides built-in functionality to enforce password strength.
MySQL 提供内置功能来强制密码强度。

检查当前设置

SHOW VARIABLES LIKE 'validate_password%';

主要配置参数

  • validate_password.length(最小长度)
  • validate_password.policy(LOW / MEDIUM / STRONG)
  • validate_password.mixed_case_count
  • validate_password.number_count
  • validate_password.special_char_count

示例配置(最小 12 字符,MEDIUM 策略)

SET GLOBAL validate_password.length = 12;
SET GLOBAL validate_password.policy = MEDIUM;

注意

  • GLOBAL 更改可能在重启后重置
  • 为了持久化设置,请在配置文件( my.cnf / my.ini )中进行配置

7.2 强密码的最低要求

Recommended standards in practice:
实践中的推荐标准:

  • 至少 12 个字符
  • 包含大写字母、小写字母、数字和符号
  • 避免使用字典单词
  • 不要在其他服务中重复使用

Example:
示例:

X9v!pQ4z#Lm2

避免的示例

password123
mysql2025
companyname!

7.3 比定期更改更重要的事项

More important than “changing every six months” is designing under the assumption of potential credential leakage.
比“每六个月更改一次”更重要的是在潜在凭证泄露的假设下进行设计。

① 分离应用程序用户

  • 不要在应用程序中使用 root
  • 创建最小特权用户

Example:
示例:

GRANT SELECT, INSERT, UPDATE ON dbname.* TO 'appuser'@'localhost';

② 最小化特权(最小特权原则)

Allow only necessary operations to limit potential damage.
仅允许必要的操作以限制潜在损害。

③ 使用审计和日志

Example log check:
日志检查示例:

tail -f /var/log/mysql/mysql.log

MySQL Enterprise also supports audit plugins.
MySQL Enterprise 也支持审计插件。

7.4 生产环境的运维技巧

  • 在进行生产更改前先在预发布环境测试
  • 跟踪更改历史(Git 或文档)
  • 更改后始终运行连接测试
  • 工作时保持 SSH 会话活跃

7.5 绝不可做的事情

  • 在应用程序中使用 root 账户
  • 在源代码中硬编码密码
  • 禁用 validate_password 并保持这种状态
  • 让服务器在 --skip-grant-tables 模式下运行

Password management is not a one-off task but part of continuous operational design.
密码管理不是一次性任务,而是持续运维设计的一部分。

8. 常见问题解答(FAQ)

8.1 问:更改密码后活动会话会怎样?

答。 In principle, new connections require the new password.
答。 原则上,新连接需要使用新密码。
For existing sessions, they may either be terminated immediately or remain active depending on the environment and configuration.
对于已有会话,它们可能会立即被终止,也可能保持活跃,这取决于环境和配置。

In practice:
在实践中:

  • 在生产环境中在业务时间之外进行更改
  • 重启应用程序以刷新连接

is recommended.
是推荐的做法。

8.2 问:我已更改密码,但仍无法登录

The three most common causes are:
最常见的三大原因是:

  1. Wrong Host ( localhost vs % , etc.)
  2. 主机错误( localhost% 等)
  3. Authentication plugin mismatch (very common in 8.0)
  4. 认证插件不匹配(在 8.0 中非常常见)
  5. Application configuration not updated
  6. 应用程序配置未更新

Check with:
检查方式:

SELECT User, Host, plugin
FROM mysql.user
WHERE User='username';

Pay special attention to the plugin column.
请特别注意 plugin 列。

8.3 问:我能只允许特定用户更改密码吗?

Yes.
可以。

GRANT ALTER USER ON *.* TO 'username'@'host';
FLUSH PRIVILEGES;

In MySQL 8.0, the SYSTEM_USER privilege may also be required.
在 MySQL 8.0 中,可能还需要 SYSTEM_USER 权限。

SHOW GRANTS FOR 'username'@'host';

Use this to verify privileges.
使用此方式验证权限。

8.4 问:在 MariaDB 中方法相同吗?

Basically, ALTER USER is available, but:
基本上,ALTER USER 可用,但:

  • Authentication plugins
  • 认证插件
  • Password policy behavior
  • 密码策略行为
  • Version-specific differences
  • 版本特定差异

may differ depending on the environment.
可能因环境而异。

Check with:
检查方式:

SELECT VERSION();

MySQL Community Edition 默认不提供内置的密码历史跟踪功能。

8.5 问:我可以检查密码更改历史吗?

可能的做法:

  • 启用审计日志
  • 使用外部日志管理
  • 在运维文档中跟踪历史

示例:

tail -f /var/log/mysql/mysql.log

8.6 问:我可以使用 –skip-grant-tables 恢复非 root 用户吗?

可以,但这会导致 极其危险的状态
完成操作后应立即恢复到正常模式。

9. 总结

更改 MySQL 密码看似简单,但如果不了解 user@host 模型、认证插件以及权限设计,很容易出现问题。

本文的关键要点包括:

9.1 使用 ALTER USER 作为标准方法

ALTER USER 'username'@'localhost'
IDENTIFIED BY 'NewStrongPassword123!';
  • MySQL 5.7 及以上的标准方法
  • 不建议直接 UPDATE mysql.user
  • 通常不需要执行 FLUSH PRIVILEGES

9.2 用户以 “user@host” 形式管理

  • localhost% 是不同的账户
  • 同一用户名可能对应多个账户
  • 可使用 SELECT User, Host FROM mysql.user; 检查

9.3 注意 8.0 中的认证插件

  • 8.0 默认:caching_sha2_password
  • 兼容旧版:mysql_native_password
  • 若无法连接,请检查 plugin
    SELECT plugin FROM mysql.user WHERE User='username';
    

9.4 恢复 root 密码时请小心

  • --skip-grant-tables 仅为临时措施
  • 完成后务必恢复到正常模式
  • 在生产环境的维护窗口期间执行

9.5 大多数错误都有明确原因

  • ERROR 1819 → 密码策略违规
  • ERROR 1227 → 权限不足
  • 无法登录 → 主机不匹配或认证插件不匹配

9.6 实际中,最小权限和运维设计最为重要

  • 应用程序中不要使用 root
  • 创建专用用户
  • 强制执行强密码策略
  • 更改后始终测试连接

MySQL 密码管理不仅仅是更改一个值——它是 安全数据库运维的基石
请为您的环境选择合适的方法并谨慎执行。