人人都会AI编程

23.1 用户管理:创建、删除、密码管理

更新时间:2026-07-10

线上数据库的用户管理,是安全防线的最前沿。一个弱密码、一个被遗忘的测试账号、一条范围过大的授权语句,都可能让整个数据库暴露在风险中。本节聚焦用户管理的基础操作,不讲空泛的理论,只讲你上手就能用的命令和必须注意的细节。

23.1.1 创建用户

MySQL 的用户由 账号允许连接的客户端主机 共同确定,即 'user'@'host' 是一个完整的用户标识。'app'@'192.168.1.%''app'@'%' 是两个完全不同的用户,各自拥有独立的权限。

创建用户的基本语法如下:

CREATE USER '用户名'@'主机' IDENTIFIED BY '密码';

注意主机部分的写法,它决定了这个账号能从哪里连接数据库:

  • 'localhost':只能从本机通过 socket 连接,最安全,适合运维管理账号。
  • '192.168.1.100':仅允许指定 IP 连接。
  • '192.168.1.%':允许该网段内所有 IP 连接。
  • '%':允许任何 IP 连接,虽然方便但对生产环境不够安全,应尽量避免,除非确有跨公网访问需求。

示例,创建一个只能从内网某网段连接的应用账号:

CREATE USER 'app_user'@'10.0.1.%' IDENTIFIED BY 'A_Strong_Passw0rd';

如果你希望用户连接后就被强制修改密码,可以在创建时加上 PASSWORD EXPIRE

CREATE USER 'new_user'@'%' IDENTIFIED BY 'Temp_Passw0rd' PASSWORD EXPIRE;

另外,从 MySQL 8.0 开始,默认的身份验证插件从 mysql_native_password 变更为更安全的 caching_sha2_password。一些老旧的客户端(如较老的 mysql-connector 版本)可能不支持新的认证方式,如果连接报错,可以通过 IDENTIFIED WITH mysql_native_password BY '密码' 显式指定旧的认证插件,但这只是临时兼容方案,最佳实践是升级客户端。

创建用户后,该账号默认没有任何数据库的操作权限,需要单独授权(见 23.3 节)。注意,CREATE USER 执行时,MySQL 会自动把密码哈希后存入 mysql.user 表,密码不会被明文记录。

23.1.2 删除用户

清理不再使用的账号,是减少攻击面的基本操作。必须精确指定用户和主机

DROP USER '用户名'@'主机';

例如删除测试账号:

DROP USER 'test_app'@'%';

这条命令不仅会移除用户,还会回收该用户所有的权限,并关闭该用户现有的所有连接(MySQL 5.7 之后)。在删除前,建议先用 SELECT 确认你要删的用户是不是还存在:

SELECT user, host FROM mysql.user WHERE user = 'test_app';

一个常见错误是:如果忘记了指定主机部分,比如只写 DROP USER 'test_app';,MySQL 会尝试删除 'test_app'@'%',如果该用户实际上定义的是 'test_app'@'localhost',则删除操作会失败,并提示用户不存在。所以务必保持“用户名@主机”的完整写法。

如果你的数据库是从 5.6 或更早版本升级上来的,可能存在 DROP USER 无法自动关闭已存在连接的情况,此时可以手动通过 SHOW PROCESSLIST 找到该用户的连接 ID,执行 KILL <id> 后再删除用户。

23.1.3 密码管理

密码管理主要包括修改密码、密码过期策略、密码强度检查三个方面。

修改密码

最常用的方式是通过 ALTER USER

ALTER USER '用户名'@'主机' IDENTIFIED BY '新密码';

如果是让用户自己修改当前连接用户的密码,可以简写为:

ALTER USER USER() IDENTIFIED BY '新密码';

对于 MySQL 5.6 及更早版本,或者需要兼容的场景,也可以用 SET PASSWORD,但不推荐在新版本中使用。

另一个常见的需求是应急情况下通过命令行直接传递新密码修改 root 密码(例如忘记 root 密码后的重置流程,该流程通常需要先停止 MySQL,用 --skip-grant-tables 启动,然后手动更新 mysql.user 表,这里不深入展开)。

密码过期策略

你可以强制要求用户定期更换密码,通过 PASSWORD EXPIRE INTERVAL N DAY 设置,比如每 90 天过期:

ALTER USER 'app_user'@'10.0.1.%' PASSWORD EXPIRE INTERVAL 90 DAY;

设置为 PASSWORD EXPIRE NEVER 则取消过期,PASSWORD EXPIRE DEFAULT 则使用全局默认策略(通过 default_password_lifetime 系统变量控制)。

当密码过期后,用户下次登录时会强制要求修改密码(除非账号被锁定),这有助于满足安全审计要求。

密码强度检查

MySQL 8.0 内置了 validate_password 插件,用来强制密码复杂度,防止弱密码。你可以通过以下命令查看当前密码策略:

SHOW VARIABLES LIKE 'validate_password%';

关键参数包括:

  • validate_password.policy:强度级别(LOW/MEDIUM/STRONG),生产环境建议至少 MEDIUM。
  • validate_password.length:最小长度,默认为 8。
  • validate_password.mixed_case_count:至少包含的大小写字母数。
  • validate_password.number_count:至少包含的数字个数。
  • validate_password.special_char_count:至少包含的特殊字符个数。

如果你安装了该插件,设置密码时不符合复杂度要求会导致创建或修改密码失败,从而在数据库层面杜绝了诸如 123456password 这种危险的弱密码。

其他实用操作

  • 账号锁定/解锁:MySQL 8.0 支持 ACCOUNT LOCK/UNLOCK,当某个业务账号不再需要写访问但又不方便立即删除时,可以临时锁定:
ALTER USER 'readonly_user'@'%' ACCOUNT LOCK;
ALTER USER 'readonly_user'@'%' ACCOUNT UNLOCK;
  • 查看用户信息:除了 SELECT user,host FROM mysql.user,还可以用 SHOW CREATE USER '用户名'@'主机'; 得到创建该用户时所用的完整语句,方便审计和重建。

掌握以上操作,配合后续的权限管理,你就能搭建一个安全、可控的 MySQL 用户体系。记住两点最核心的原则:最小权限最小暴露面——尽可能使用准对特定库、特定业务的账号,并且仅从内网必要机器开放连接。这些看似繁琐的步骤,最终保护的是你的数据资产。