MySQL 用户与权限管理 (DCL) 操作命令大全

说明:DCL(Data Control Language,数据控制语言)用于管理数据库用户的权限和访问控制。本指南涵盖 MySQL 5.7 和 8.0 中的所有用户、角色和权限管理命令。


一、用户管理

1.1 创建用户

语法

sql 复制代码
CREATE USER [IF NOT EXISTS] '用户名'@'主机名' 
    IDENTIFIED BY '密码'
    [DEFAULT ROLE 角色名]
    [PASSWORD EXPIRE [NEVER | INTERVAL N DAY | DEFAULT]]
    [ACCOUNT LOCK | UNLOCK];

主机名格式

  • 'localhost' - 仅允许本地连接
  • '%' - 允许任意主机连接
  • '192.168.1.%' - 允许特定网段
  • '192.168.1.100' - 允许特定IP

示例

sql 复制代码
-- 基本创建
CREATE USER 'john'@'localhost' IDENTIFIED BY 'password123';

-- 存在则不重复创建(推荐)
CREATE USER IF NOT EXISTS 'app_user'@'%' IDENTIFIED BY 'AppPass456';

-- 带账户锁定(解锁后可用)
CREATE USER 'temp'@'localhost' IDENTIFIED BY 'temp' ACCOUNT LOCK;

-- 设置密码过期策略(90天后过期)
CREATE USER 'reporter'@'%' IDENTIFIED BY 'report' PASSWORD EXPIRE INTERVAL 90 DAY;

1.2 删除用户

语法

sql 复制代码
DROP USER [IF EXISTS] '用户名'@'主机名' [, '用户名'@'主机名'] ...;

示例

sql 复制代码
-- 删除单个用户
DROP USER 'john'@'localhost';

-- 安全删除(推荐)
DROP USER IF EXISTS 'old_user'@'%';

-- 批量删除多个用户
DROP USER 'user1'@'localhost', 'user2'@'192.168.1.%';

1.3 修改用户名(重命名用户)

语法

sql 复制代码
RENAME USER '旧用户名'@'旧主机名' TO '新用户名'@'新主机名';

示例

sql 复制代码
RENAME USER 'john'@'localhost' TO 'john_doe'@'%';

⚠️ 注意:MySQL 8.0 中已支持,5.7 也可用。重命名后原有权限会自动转移到新用户名上。

1.4 修改用户密码

方式一:ALTER USER(MySQL 5.7.6+,推荐)

sql 复制代码
ALTER USER '用户名'@'主机名' IDENTIFIED BY '新密码';

方式二:SET PASSWORD(旧方式)

sql 复制代码
-- 修改当前用户密码
SET PASSWORD = '新密码';

-- 修改指定用户密码(需要权限)
SET PASSWORD FOR '用户名'@'主机名' = '新密码';

方式三:使用旧版 PASSWORD() 函数(不推荐)

sql 复制代码
SET PASSWORD FOR 'user'@'host' = PASSWORD('新密码');

方式四:mysqladmin 命令行

bash 复制代码
mysqladmin -u root -p password '新密码'

示例

sql 复制代码
ALTER USER 'john'@'localhost' IDENTIFIED BY 'new_secure_pass';
SET PASSWORD FOR 'app_user'@'%' = 'new_app_pass';

1.5 密码过期管理

sql 复制代码
-- 设置密码立即过期(下次登录强制修改)
ALTER USER 'user'@'host' PASSWORD EXPIRE;

-- 设置密码永不过期
ALTER USER 'user'@'host' PASSWORD EXPIRE NEVER;

-- 设置为默认过期策略(由 default_password_lifetime 决定)
ALTER USER 'user'@'host' PASSWORD EXPIRE DEFAULT;

-- 设置间隔天数后过期
ALTER USER 'user'@'host' PASSWORD EXPIRE INTERVAL 90 DAY;

1.6 锁定/解锁账户

sql 复制代码
-- 锁定账户(禁止登录)
ALTER USER 'user'@'host' ACCOUNT LOCK;

-- 解锁账户
ALTER USER 'user'@'host' ACCOUNT UNLOCK;

1.7 查看所有用户

sql 复制代码
-- MySQL 5.7/8.0
SELECT user, host, account_locked, password_expired FROM mysql.user;

-- 更详细的信息
SELECT user, host, authentication_string, password_last_changed, 
       password_lifetime, account_locked 
FROM mysql.user;

1.8 查看当前登录用户

sql 复制代码
SELECT CURRENT_USER();   -- 当前活动用户(权限对应的用户)
SELECT USER();           -- 连接时提供的用户名和主机

二、权限管理

2.1 权限级别

MySQL 权限从大到小分为:

  • 全局权限*.* 所有数据库的所有对象
  • 数据库级权限db_name.* 特定数据库的所有对象
  • 表级权限db_name.table_name 特定表
  • 列级权限db_name.table_name(column1, column2,...) 特定列
  • 存储过程/函数权限db_name.procedure_name
  • 代理用户权限PROXY

2.2 授予权限(GRANT)

完整语法

sql 复制代码
GRANT 权限列表 ON 权限级别 TO '用户名'@'主机名' 
    [WITH GRANT OPTION]
    [MAX_QUERIES_PER_HOUR count]
    [MAX_UPDATES_PER_HOUR count]
    [MAX_CONNECTIONS_PER_HOUR count]
    [MAX_USER_CONNECTIONS count];

常用权限列表ALL [PRIVILEGES], SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, ALTER, INDEX, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, TRIGGER, REFERENCES, LOCK TABLES, CREATE TEMPORARY TABLES, EVENT, CREATE USER, FILE, PROCESS, RELOAD, REPLICATION SLAVE, REPLICATION CLIENT, SHOW DATABASES, SHUTDOWN, SUPER 等。

示例

sql 复制代码
-- 授予全局所有权限(管理员)
GRANT ALL PRIVILEGES ON *.* TO 'admin'@'localhost' WITH GRANT OPTION;

-- 授予特定数据库的所有权限
GRANT ALL PRIVILEGES ON company_db.* TO 'app_user'@'%';

-- 授予只读权限(SELECT)
GRANT SELECT ON company_db.* TO 'reporter'@'localhost';

-- 授予表级权限
GRANT INSERT, UPDATE, DELETE ON company_db.users TO 'editor'@'%';

-- 授予列级权限(只能查询id和name列)
GRANT SELECT(id, name) ON company_db.users TO 'limited'@'localhost';

-- 授予存储过程执行权限
GRANT EXECUTE ON PROCEDURE company_db.calc_bonus TO 'app_user'@'%';

-- 授予创建视图权限
GRANT CREATE VIEW, SHOW VIEW ON company_db.* TO 'developer'@'localhost';

-- 授予资源限制(每小时最多100次查询)
GRANT SELECT ON *.* TO 'reporter'@'%' 
    WITH MAX_QUERIES_PER_HOUR 100;

2.3 撤销权限(REVOKE)

语法

sql 复制代码
REVOKE 权限列表 ON 权限级别 FROM '用户名'@'主机名';

-- 撤销 WITH GRANT OPTION 权限(特殊)
REVOKE GRANT OPTION FOR 权限列表 ON 权限级别 FROM '用户名'@'主机名';

-- 撤销所有权限(不删除用户)
REVOKE ALL PRIVILEGES, GRANT OPTION FROM '用户名'@'主机名';

示例

sql 复制代码
-- 撤销特定权限
REVOKE INSERT, UPDATE ON company_db.* FROM 'app_user'@'%';

-- 撤销全局权限
REVOKE ALL PRIVILEGES ON *.* FROM 'admin'@'localhost';

-- 撤销列级权限(MySQL不支持直接撤销列权限,需重新赋予完整权限再限制列)
-- 通常的做法是先删除列权限的GRANT,然后重新赋予更窄的权限

2.4 查看权限

sql 复制代码
-- 查看当前用户的权限
SHOW GRANTS;
SHOW GRANTS FOR CURRENT_USER;

-- 查看指定用户的权限
SHOW GRANTS FOR '用户名'@'主机名';

-- 更详细的权限信息(通过表查询)
SELECT * FROM mysql.user WHERE user='用户名'\G
SELECT * FROM mysql.db WHERE user='用户名'\G
SELECT * FROM mysql.tables_priv WHERE user='用户名'\G
SELECT * FROM mysql.columns_priv WHERE user='用户名'\G

示例

sql 复制代码
SHOW GRANTS FOR 'john'@'localhost';

2.5 刷新权限

修改了 mysql.user 或其他权限表后,需执行以下命令使更改生效:

sql 复制代码
FLUSH PRIVILEGES;

通常在使用 GRANTREVOKE 命令时,MySQL 会自动刷新,但直接操作权限表(INSERT/UPDATE/DELETE)后必须手动执行 FLUSH PRIVILEGES


三、角色管理(MySQL 8.0+)

角色是权限的集合,可以方便地批量管理用户权限。

3.1 创建角色

sql 复制代码
CREATE ROLE [IF NOT EXISTS] '角色名'[@'主机名'];

示例

sql 复制代码
CREATE ROLE 'app_read';
CREATE ROLE 'app_write';
CREATE ROLE 'db_admin'@'localhost';

3.2 删除角色

sql 复制代码
DROP ROLE [IF EXISTS] '角色名'[@'主机名'];

示例

sql 复制代码
DROP ROLE 'app_read';

3.3 授予权限给角色

sql 复制代码
GRANT SELECT ON company_db.* TO 'app_read';
GRANT INSERT, UPDATE, DELETE ON company_db.* TO 'app_write';

3.4 将角色授予用户

sql 复制代码
GRANT '角色名'[@'主机名'] TO '用户名'@'主机名';

示例

sql 复制代码
GRANT 'app_read' TO 'reporter'@'localhost';
GRANT 'app_write' TO 'editor'@'%';

3.5 激活角色

用户登录后默认角色可能未激活。默认情况下,在 MySQL 8.0 中,如果设置了 activate_all_roles_on_login 为 ON,则自动激活所有授予的角色;否则需要手动激活或设置默认角色。

查看当前激活的角色:

sql 复制代码
SELECT CURRENT_ROLE();

设置用户的默认角色(自动激活):

sql 复制代码
SET DEFAULT ROLE '角色名' TO '用户名'@'主机名';

-- 示例
SET DEFAULT ROLE 'app_read' TO 'reporter'@'localhost';

-- 设置所有授予的角色为默认角色
SET DEFAULT ROLE ALL TO 'user'@'host';

会话中手动激活角色:

sql 复制代码
SET ROLE '角色名';
SET ROLE ALL;           -- 激活所有授予的角色
SET ROLE NONE;          -- 无角色
SET ROLE DEFAULT;       -- 激活默认角色

3.6 撤销用户的角色

sql 复制代码
REVOKE '角色名' FROM '用户名'@'主机名';

示例

sql 复制代码
REVOKE 'app_read' FROM 'reporter'@'localhost';

3.7 查看角色信息

sql 复制代码
-- 查看所有角色
SELECT * FROM mysql.user WHERE account_locked='Y' AND password_expired='Y';

-- 查看角色拥有的权限
SHOW GRANTS FOR '角色名';

-- 查看用户拥有的角色
SELECT * FROM mysql.role_edges WHERE TO_USER='用户名';

-- 查看当前会话的角色
SELECT CURRENT_ROLE();

四、资源限制管理

资源限制用于防止单个用户过度消耗数据库资源。

4.1 设置资源限制

可在 GRANTALTER USER 中设置:

sql 复制代码
-- 在 GRANT 中设置
GRANT SELECT ON *.* TO 'webuser'@'%' 
    WITH MAX_QUERIES_PER_HOUR 500
         MAX_UPDATES_PER_HOUR 200
         MAX_CONNECTIONS_PER_HOUR 50
         MAX_USER_CONNECTIONS 10;

-- 使用 ALTER USER 修改现有用户(MySQL 8.0+)
ALTER USER 'webuser'@'%' 
    WITH MAX_QUERIES_PER_HOUR 1000
         MAX_UPDATES_PER_HOUR 500;

参数说明

  • MAX_QUERIES_PER_HOUR:每小时允许的查询次数
  • MAX_UPDATES_PER_HOUR:每小时允许的更新次数
  • MAX_CONNECTIONS_PER_HOUR:每小时允许的连接次数
  • MAX_USER_CONNECTIONS:同一时刻允许的最大连接数

4.2 查看资源限制

sql 复制代码
SELECT user, host, max_questions, max_updates, max_connections, max_user_connections
FROM mysql.user WHERE user='webuser';

4.3 清除资源计数器

sql 复制代码
FLUSH USER_RESOURCES;

五、认证插件管理

MySQL 8.0 默认使用 caching_sha2_password,而 5.7 默认是 mysql_native_password

5.1 更改认证插件

sql 复制代码
-- 修改用户使用 mysql_native_password(兼容旧版客户端)
ALTER USER 'user'@'host' IDENTIFIED WITH mysql_native_password BY 'password';

-- 修改为 caching_sha2_password(MySQL 8.0 默认)
ALTER USER 'user'@'host' IDENTIFIED WITH caching_sha2_password BY 'password';

-- 不指定密码,仅改变插件(密码保持不变)
ALTER USER 'user'@'host' IDENTIFIED WITH mysql_native_password;

5.2 查看认证插件

sql 复制代码
SELECT user, host, plugin FROM mysql.user;

六、代理用户管理

代理用户允许一个用户以另一个用户的权限执行操作。

6.1 授予代理权限

sql 复制代码
GRANT PROXY ON '被代理用户'@'主机' TO '代理用户'@'主机';

示例

sql 复制代码
CREATE USER 'app_proxy'@'localhost' IDENTIFIED BY 'proxy';
CREATE USER 'app_backend'@'localhost' IDENTIFIED BY 'backend';

-- 允许 app_proxy 代理 app_backend
GRANT PROXY ON 'app_backend'@'localhost' TO 'app_proxy'@'localhost';

6.2 查看代理信息

sql 复制代码
SELECT * FROM mysql.proxies_priv;

6.3 撤销代理权限

sql 复制代码
REVOKE PROXY ON 'app_backend'@'localhost' FROM 'app_proxy'@'localhost';

七、密码管理高级功能(MySQL 8.0+)

7.1 密码重用策略

sql 复制代码
-- 设置密码不能与最近5次使用的密码相同
ALTER USER 'user'@'host' PASSWORD HISTORY 5;

-- 设置密码不能与过去90天内使用的密码相同
ALTER USER 'user'@'host' PASSWORD REUSE INTERVAL 90 DAY;

-- 同时设置
ALTER USER 'user'@'host' 
    PASSWORD HISTORY 5 
    PASSWORD REUSE INTERVAL 90 DAY;

7.2 密码强度验证(需安装 validate_password 组件)

sql 复制代码
-- 安装插件(如果未安装)
INSTALL COMPONENT 'file://component_validate_password';

-- 设置密码策略
SET GLOBAL validate_password.policy = 'STRONG';
SET GLOBAL validate_password.length = 12;

7.3 双密码(Dual Password)

sql 复制代码
-- 设置主密码和次密码(用于轮换)
ALTER USER 'user'@'host' IDENTIFIED BY 'new_password' RETAIN CURRENT PASSWORD;

-- 弃用旧密码
ALTER USER 'user'@'host' DISCARD OLD PASSWORD;

八、安全相关操作

8.1 忘记 root 密码重置(命令行)

bash 复制代码
# 停止 MySQL 服务
sudo systemctl stop mysql

# 跳过授权表启动
sudo mysqld_safe --skip-grant-tables &

# 登录(无需密码)
mysql -u root

# 在 MySQL 中清空 root 密码
FLUSH PRIVILEGES;
ALTER USER 'root'@'localhost' IDENTIFIED BY '';

# 正常重启 MySQL
sudo systemctl restart mysql

# 使用新密码登录后设置密码
mysql -u root -p
ALTER USER 'root'@'localhost' IDENTIFIED BY '新密码';

8.2 限制用户登录来源

sql 复制代码
-- 创建只能从特定IP登录的用户
CREATE USER 'user'@'192.168.1.100' IDENTIFIED BY 'pass';

-- 创建只能从内网域名登录的用户
CREATE USER 'user'@'internal.example.com' IDENTIFIED BY 'pass';

8.3 查看当前登录会话

sql 复制代码
SHOW PROCESSLIST;
SELECT * FROM information_schema.processlist;

8.4 终止用户会话

sql 复制代码
-- 首先找到连接ID
SHOW PROCESSLIST;

-- 然后杀死指定连接
KILL CONNECTION 123;  -- 礼貌关闭
KILL QUERY 123;       -- 仅杀死当前查询,不关闭连接

九、综合示例

示例1:创建应用程序用户并授权

sql 复制代码
-- 创建数据库
CREATE DATABASE IF NOT EXISTS ecommerce;

-- 创建只读角色
CREATE ROLE 'readonly';
GRANT SELECT ON ecommerce.* TO 'readonly';

-- 创建读写角色
CREATE ROLE 'readwrite';
GRANT SELECT, INSERT, UPDATE, DELETE ON ecommerce.* TO 'readwrite';

-- 创建用户
CREATE USER 'app_user'@'%' IDENTIFIED BY 'SecurePass123';
CREATE USER 'report_user'@'localhost' IDENTIFIED BY 'ReportPass456';

-- 授予角色
GRANT 'readwrite' TO 'app_user'@'%';
GRANT 'readonly' TO 'report_user'@'localhost';

-- 设置默认角色
SET DEFAULT ROLE 'readwrite' TO 'app_user'@'%';
SET DEFAULT ROLE 'readonly' TO 'report_user'@'localhost';

-- 查看权限
SHOW GRANTS FOR 'app_user'@'%';

示例2:细粒度权限控制

sql 复制代码
-- 用户只能查询 orders 表中的 user_id 和 status 列
GRANT SELECT(user_id, status) ON ecommerce.orders TO 'support'@'localhost';

-- 用户只能插入 logs 表,不能更新或删除
GRANT INSERT ON ecommerce.logs TO 'audit'@'%';

-- 用户只能执行特定的存储过程
GRANT EXECUTE ON PROCEDURE ecommerce.sp_update_inventory TO 'inventory'@'localhost';

示例3:临时用户管理

sql 复制代码
-- 创建临时账户,30天后密码过期,账户锁定
CREATE USER 'temp'@'localhost' IDENTIFIED BY 'tempPass'
    PASSWORD EXPIRE INTERVAL 30 DAY
    ACCOUNT LOCK;

-- 激活账户
ALTER USER 'temp'@'localhost' ACCOUNT UNLOCK;

-- 使用完成后立即锁定
ALTER USER 'temp'@'localhost' ACCOUNT LOCK;

-- 最终删除
DROP USER 'temp'@'localhost';

十、常用查询与维护

10.1 检查弱密码用户

sql 复制代码
SELECT user, host, password_last_changed 
FROM mysql.user 
WHERE password_last_changed < NOW() - INTERVAL 180 DAY;

10.2 查看所有用户的全局权限

sql 复制代码
SELECT user, host, Select_priv, Insert_priv, Update_priv, Delete_priv, Create_priv, Drop_priv 
FROM mysql.user;

10.3 生成批量用户创建语句

sql 复制代码
SELECT CONCAT("CREATE USER '", user, "'@'", host, "' IDENTIFIED BY 'randomPass';") 
FROM (SELECT DISTINCT 'test_user' AS user, '%' AS host) AS t;

10.4 备份权限

sql 复制代码
-- 使用 pt-show-grants 工具(Percona Toolkit)
pt-show-grants --user=root --password=root > grants_backup.sql

-- 或手动生成 GRANT 语句
SELECT CONCAT("SHOW GRANTS FOR '", user, "'@'", host, "';") FROM mysql.user;

十一、注意事项与最佳实践

方面 建议
密码安全 使用强密码(>12位,混合字符),定期更换;避免明文存储密码。
最小权限原则 只授予用户完成任务所需的最小权限,避免滥用 ALL PRIVILEGES
主机限制 生产环境避免使用 '%' 通配符,限制到具体IP或网段。
角色管理 MySQL 8.0 以上建议使用角色简化权限管理。
审计 定期审查用户权限,移除不再需要的账号。
备份 定期使用 pt-show-grants 或备份 mysql 系统库。
连接加密 要求使用 SSL 连接(REQUIRE SSLCREATE USERGRANT 中)。
密码历史 开启密码重用限制,防止重复使用旧密码。

以上完整涵盖了 MySQL 中用户与权限管理的所有 DCL 操作命令,包括用户管理、权限授予/撤销、角色管理、资源限制、认证插件、代理用户、密码高级功能等。根据实际安全需求选择适当命令即可。

相关推荐
彩票管理中心秘书长2 小时前
MySQL 索引、事务与约束操作命令大全
后端
Rust语言中文社区2 小时前
【Rust日报】2026-04-24 Vizia 0.4 发布——纯 Rust 声明式响应式 GUI 框架
开发语言·后端·rust
Lisonseekpan2 小时前
Git:如何将一个分支的特定提交合并到另一个分支?
java·大数据·git·后端·elasticsearch
程序员Better3 小时前
前端成功转型AI全栈,我踩过的坑都替你填上了
前端·后端·ai编程
兔子零10243 小时前
GPT-5.5 与 DeepSeek-V4:大模型竞争的本质,正在从“谁更强”变成“谁让成本更低”
前端·javascript·后端
楼田莉子4 小时前
CMake学习:CMake语法
c++·后端·学习·软件构建
无限进步_4 小时前
C++ 继承机制完全解析:从基础原理到菱形继承问题
java·开发语言·数据结构·c++·vscode·后端·算法
武子康4 小时前
大数据-278 Spark MLib-GBDT梯度提升决策树详解:从原理到实战案例
大数据·后端·spark