MySQL 权限管理

MySQL 权限管理


1. 查看用户权限

1.1 查看当前用户权限

MySQL 5.7

sql 复制代码
-- 查看当前用户
SELECT USER();

返回结果:

复制代码
+----------------+
| USER()         |
+----------------+
| root@localhost |
+----------------+
1 row in set (0.00 sec)
sql 复制代码
-- 查看当前用户的所有权限
SHOW GRANTS;
-- 查看当前用户所有权限(等价写法)
SHOW GRANTS FOR CURRENT_USER;
SHOW GRANTS FOR CURRENT_USER();

返回结果:

复制代码
+---------------------------------------------------------------------+
| Grants for root@localhost                                           |
+---------------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION |
| GRANT PROXY ON ''@'' TO 'root'@'localhost' WITH GRANT OPTION        |
+---------------------------------------------------------------------+
2 rows in set (0.00 sec)

MySQL 8.0

sql 复制代码
-- 查看当前用户
SELECT USER();

返回结果:

复制代码
+----------------+
| USER()         |
+----------------+
| root@localhost |
+----------------+
1 row in set (0.00 sec)
sql 复制代码
-- 查看当前用户的所有权限
SHOW GRANTS;
-- 查看当前用户所有权限(等价写法)
SHOW GRANTS FOR CURRENT_USER;
SHOW GRANTS FOR CURRENT_USER();
-- mysql8权限显示内容较多,\G让结果显示为纵向格式
SHOW GRANTS\G

返回结果:

复制代码
*************************** 1. row ***************************
Grants for root@localhost: GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE, CREATE ROLE, DROP ROLE ON *.* TO `root`@`localhost` WITH GRANT OPTION
*************************** 2. row ***************************
Grants for root@localhost: GRANT APPLICATION_PASSWORD_ADMIN,AUDIT_ABORT_EXEMPT,AUDIT_ADMIN,AUTHENTICATION_POLICY_ADMIN,BACKUP_ADMIN,BINLOG_ADMIN,BINLOG_ENCRYPTION_ADMIN,CLONE_ADMIN,CONNECTION_ADMIN,ENCRYPTION_KEY_ADMIN,FIREWALL_EXEMPT,FLUSH_OPTIMIZER_COSTS,FLUSH_STATUS,FLUSH_TABLES,FLUSH_USER_RESOURCES,GROUP_REPLICATION_ADMIN,GROUP_REPLICATION_STREAM,INNODB_REDO_LOG_ARCHIVE,INNODB_REDO_LOG_ENABLE,PASSWORDLESS_USER_ADMIN,PERSIST_RO_VARIABLES_ADMIN,REPLICATION_APPLIER,REPLICATION_SLAVE_ADMIN,RESOURCE_GROUP_ADMIN,RESOURCE_GROUP_USER,ROLE_ADMIN,SENSITIVE_VARIABLES_OBSERVER,SERVICE_CONNECTION_ADMIN,SESSION_VARIABLES_ADMIN,SET_USER_ID,SHOW_ROUTINE,SYSTEM_USER,SYSTEM_VARIABLES_ADMIN,TABLE_ENCRYPTION_ADMIN,XA_RECOVER_ADMIN ON *.* TO `root`@`localhost` WITH GRANT OPTION
*************************** 3. row ***************************
Grants for root@localhost: GRANT PROXY ON ``@`` TO `root`@`localhost` WITH GRANT OPTION
3 rows in set (0.00 sec)

说明:

MySQL 8 查看权限比 5.7 复杂的原因: 引入了动态权限机制 。

静态权限(SELECT、INSERT 等)仍然存在 mysql.user 表中,但 MySQL 8 支持组件/插件在运行时注册新权限(如 CLONE_ADMIN、BACKUP_ADMIN),这些动态权限存在 mysql.global_grants 表中,无法合并到一条 ALL PRIVILEGES 里。

结果就是 SHOW GRANTS 必须拆成多条:静态权限一条、动态权限一条、代理权限一条。


1.2 查看指定用户权限

MySQL 5.7

sql 复制代码
-- 查看 root@localhost 的权限
SHOW GRANTS FOR 'root'@'localhost';

MySQL 8.0

sql 复制代码
-- 查看 root@localhost 的权限
SHOW GRANTS FOR 'root'@'localhost';

2. 给用户授权

重要概念 :MySQL 中用户由 用户名 + Host 共同唯一标识。'appuser'@'localhost''appuser'@'%'两个完全不同的用户,拥有独立的权限和密码。

2.1 创建用户后再授权(推荐方式)

MySQL 5.7

第一步:创建用户

sql 复制代码
CREATE USER 'appuser'@'%' IDENTIFIED BY 'Password123!';

第二步:授予权限

sql 复制代码
GRANT SELECT, INSERT, UPDATE, DELETE ON db_test.* TO 'appuser'@'%';

验证权限

sql 复制代码
SHOW GRANTS FOR 'appuser'@'%';

返回结果:

复制代码
+----------------------------------------------------------------------+
| Grants for appuser@%                                                 |
+----------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'appuser'@'%'                                  |
| GRANT SELECT, INSERT, UPDATE, DELETE ON `db_test`.* TO 'appuser'@'%' |
+----------------------------------------------------------------------+
2 rows in set (0.00 sec)

说明:

GRANT USAGE中,USAGE 是一个 无权限的占位符 ,表示该用户存在于 MySQL 中,可以登录。写入的是mysql.user

授权会新增一条记录,因为GRANT SELECT ,它写入的是 mysql.db

MySQL 8.0

第一步:创建用户

sql 复制代码
CREATE USER 'appuser'@'%' IDENTIFIED BY 'Password123!';

第二步:授予权限

sql 复制代码
GRANT SELECT, INSERT, UPDATE, DELETE ON db_test.* TO 'appuser'@'%';

验证权限

sql 复制代码
SHOW GRANTS FOR 'appuser'@'%';

返回结果:

复制代码
+----------------------------------------------------------------------+
| Grants for appuser@%                                                 |
+----------------------------------------------------------------------+
| GRANT USAGE ON *.* TO `appuser`@`%`                                  |
| GRANT SELECT, INSERT, UPDATE, DELETE ON `db_test`.* TO `appuser`@`%` |
+----------------------------------------------------------------------+
2 rows in set (0.00 sec)

2.2 创建用户同时授权(仅 MySQL 5.7)

sql 复制代码
-- MySQL 5.7 中 GRANT 可附带 IDENTIFIED BY 自动创建用户
-- 注意:MySQL 8.0 已移除此语法,不推荐使用
GRANT SELECT, INSERT ON db_test.* TO 'newuser'@'%' IDENTIFIED BY 'Password123!';

验证

sql 复制代码
SHOW GRANTS FOR 'newuser'@'%';

返回结果:

复制代码
+------------------------------------------------------+
| Grants for newuser@%                                 |
+------------------------------------------------------+
| GRANT USAGE ON *.* TO 'newuser'@'%'                  |
| GRANT SELECT, INSERT ON `db_test`.* TO 'newuser'@'%' |
+------------------------------------------------------+
2 rows in set (0.00 sec)

警告 :MySQL 8.0 中 GRANT ... IDENTIFIED BY 已被移除 ,必须先 CREATE USERGRANT。建议在 5.7 中也采用分步方式,保持良好习惯。


2.3 相同用户名不同 Host 是不同的用户

sql 复制代码
-- 创建两个同名但不同 host 的用户(他们是不同的用户)
CREATE USER 'appuser'@'localhost' IDENTIFIED BY 'Password123!';
CREATE USER 'appuser'@'%'       IDENTIFIED BY 'Password456!';

用户匹配规则:

匹配优先级 host 值 说明
1(最高) 具体 IP,如 192.168.1.100 精确匹配
2 含通配符的 IP,如 192.168.1.% 网段匹配
3 具体域名,如 db.example.com 域名匹配
4 含通配符的域名,如 %.example.com 域名模糊匹配
5(最低) % 匹配所有主机(不含 localhost)

注意localhost 仅匹配本地 socket 连接或 -h localhost 的 TCP 连接;127.0.0.1 仅匹配 -h 127.0.0.1。两者也是不同的用户。


3. 授权的各个级别

MySQL 权限按粒度从大到小分为四个层级:全局级 > 数据库级 > 表级 > 列级。权限向下覆盖:全局级权限对其下所有库/表/列生效,库级权限对该库下所有表/列生效。

以下演示均使用同一个用户 dba_user,便于最后通过 SHOW GRANTS 看到不同层级权限的累积效果。

演示环境准备:

sql 复制代码
-- 创建测试库和测试表
CREATE DATABASE IF NOT EXISTS db_test;
USE db_test;
CREATE TABLE IF NOT EXISTS t_test (
    id   INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(50)
);

3.1 全局级授权(ON *.*

对 MySQL 实例中所有的数据库和表生效。适用场景:DBA 账号、运维监控账号、主从复制账号。

sql 复制代码
CREATE USER 'dba_user'@'%' IDENTIFIED BY 'StrongPass123!';
GRANT SELECT ON *.* TO 'dba_user'@'%';

查询 mysql.user 表(全局级权限存储在这里)

sql 复制代码
SELECT User, Host,
       Select_priv, Insert_priv, Update_priv, Delete_priv,
       Create_priv, Drop_priv, Reload_priv, Shutdown_priv,
       Process_priv, File_priv, Grant_priv, References_priv,
       Index_priv, Alter_priv, Show_db_priv, Super_priv,
       Create_tmp_table_priv, Lock_tables_priv, Execute_priv,
       Repl_slave_priv, Repl_client_priv, Create_view_priv,
       Show_view_priv, Create_routine_priv, Alter_routine_priv,
       Create_user_priv, Event_priv, Trigger_priv, Create_tablespace_priv
FROM mysql.user
WHERE User = 'dba_user' AND Host = '%'\G

返回结果:

复制代码
*************************** 1. row ***************************
                  User: dba_user
                  Host: %
           Select_priv: Y
           Insert_priv: N
           Update_priv: N
           Delete_priv: N
           Create_priv: N
             Drop_priv: N
           Reload_priv: N
         Shutdown_priv: N
          Process_priv: N
             File_priv: N
            Grant_priv: N
       References_priv: N
            Index_priv: N
            Alter_priv: N
          Show_db_priv: N
            Super_priv: N
Create_tmp_table_priv: N
      Lock_tables_priv: N
          Execute_priv: N
       Repl_slave_priv: N
      Repl_client_priv: N
      Create_view_priv: N
        Show_view_priv: N
   Create_routine_priv: N
    Alter_routine_priv: N
      Create_user_priv: N
            Event_priv: N
          Trigger_priv: N
Create_tablespace_priv: N
1 row in set (0.00 sec)

MySQL 8 注意 :全局级权限分为静态权限和动态权限。静态权限(SELECT、INSERT 等)存在 mysql.user 表中;动态权限(BACKUP_ADMIN、CLONE_ADMIN 等,MySQL 8 新增)存在 mysql.global_grants 表中。ALL PRIVILEGES 仅涵盖静态权限,动态权限需单独 GRANT


3.2 数据库级授权(ON db_name.*

对指定数据库内的所有表生效。适用场景:应用后端账号、项目隔离数据库账号。

sql 复制代码
GRANT INSERT, UPDATE ON db_test.* TO 'dba_user'@'%';

查询 mysql.db 表(库级权限存储在这里)

sql 复制代码
SELECT Host, Db, User,
       Select_priv, Insert_priv, Update_priv, Delete_priv,
       Create_priv, Drop_priv, Grant_priv, References_priv,
       Index_priv, Alter_priv, Create_tmp_table_priv,
       Lock_tables_priv, Create_view_priv, Show_view_priv,
       Create_routine_priv, Alter_routine_priv, Execute_priv,
       Event_priv, Trigger_priv
FROM mysql.db
WHERE User = 'dba_user' AND Host = '%'\G

返回结果:

复制代码
*************************** 1. row ***************************
                 Host: %
                   Db: db_test
                 User: dba_user
          Select_priv: N
          Insert_priv: Y
          Update_priv: Y
          Delete_priv: N
          Create_priv: N
            Drop_priv: N
           Grant_priv: N
      References_priv: N
           Index_priv: N
           Alter_priv: N
Create_tmp_table_priv: N
     Lock_tables_priv: N
     Create_view_priv: N
       Show_view_priv: N
 Create_routine_priv: N
   Alter_routine_priv: N
         Execute_priv: N
           Event_priv: N
         Trigger_priv: N
1 row in set (0.00 sec)

3.3 表级授权(ON db_name.table_name

仅对指定的某张表生效。适用场景:只需操作特定表的账号、第三方数据同步账号。

sql 复制代码
GRANT DELETE ON db_test.t_test TO 'dba_user'@'%';

查询 mysql.tables_priv 表(表级权限存储在这里)

sql 复制代码
SELECT Host, Db, User, Table_name, Table_priv, Column_priv
FROM mysql.tables_priv
WHERE User = 'dba_user' AND Host = '%'\G

返回结果:

复制代码
*************************** 1. row ***************************
    Host: %
      Db: db_test
    User: dba_user
Table_name: t_test
Table_priv: Delete
Column_priv:
1 row in set (0.00 sec)

3.4 列级授权(ON db_name.table_name (col1, col2, ...)

精确到表中的具体列。适用场景:敏感字段脱敏(如隐藏薪资、手机号列)。

注意 :列级授权仅支持 SELECTINSERTUPDATEREFERENCES 四种权限。

sql 复制代码
GRANT SELECT (id, name) ON db_test.t_test TO 'dba_user'@'%';

查询 mysql.columns_priv 表(列级权限存储在这里)

sql 复制代码
SELECT Host, Db, User, Table_name, Column_name, Column_priv
FROM mysql.columns_priv
WHERE User = 'dba_user' AND Host = '%'\G

返回结果:

复制代码
*************************** 1. row ***************************
       Host: %
         Db: db_test
       User: dba_user
Table_name: t_test
Column_name: id
Column_priv: Select
*************************** 2. row ***************************
       Host: %
         Db: db_test
       User: dba_user
Table_name: t_test
Column_name: name
Column_priv: Select
2 rows in set (0.00 sec)

列级授权,同样会影响tables_priv表

sql 复制代码
SELECT Host, Db, User, Table_name, Table_priv, Column_priv
FROM mysql.tables_priv
WHERE User = 'dba_user' AND Host = '%'\G

返回结果:

复制代码
*************************** 1. row ***************************
    Host: %
      Db: db_test
    User: dba_user
Table_name: t_test
Table_priv: Delete
Column_priv: Select
1 row in set (0.00 sec)

3.5 SHOW GRANTS 汇总查看

以上四个层级的授权全部施加在 dba_user 身上后,SHOW GRANTS 会汇总所有系统表中的权限,合并输出:

sql 复制代码
SHOW GRANTS FOR 'dba_user'@'%';

返回结果:

复制代码
+-----------------------------------------------------------------------------+
| Grants for dba_user@%                                                       |
+-----------------------------------------------------------------------------+
| GRANT SELECT ON *.* TO `dba_user`@`%`                                       |  ← 来自 mysql.user
| GRANT INSERT, UPDATE ON `db_test`.* TO `dba_user`@`%`                       |  ← 来自 mysql.db
| GRANT SELECT (id, name), DELETE ON `db_test`.`t_test` TO `dba_user`@`%`     |  ← 来自 mysql.tables_priv + mysql.columns_priv(表级+列级合并为一条)
+-----------------------------------------------------------------------------+

与逐表查询的对照关系:

说明 :对同一张表同时授予表级权限和列级权限时,它们存储在 mysql.tables_priv同一条记录 中(Table_privColumn_priv 为同一行的不同字段),SHOW GRANTS 也会合并显示为一行。

层级 GRANT 写入 查询语句
全局 mysql.user SELECT * FROM mysql.user WHERE User='dba_user'
库级 mysql.db SELECT * FROM mysql.db WHERE User='dba_user'
表级/列级 mysql.tables_priv SELECT * FROM mysql.tables_priv WHERE User='dba_user'
列明细 mysql.columns_priv SELECT * FROM mysql.columns_priv WHERE User='dba_user'

总结 :每执行一次不同层级的 GRANT,都在对应的系统表中新增一条记录。SHOW GRANTS 扫描以上所有表后合并输出,因此一个用户可能显示多行,每行对应一个层级。


3.6 各层级对比总结

层级 语法格式 粒度 典型场景
全局 ON *.* 整个实例 DBA、监控、复制账号
数据库 ON db_name.* 库下所有表 应用后端、项目隔离
ON db_name.table_name 单张表 第三方同步、特定表操作
ON db_name.table_name (col1, col2) 表中的具体列 敏感字段脱敏、细粒度控制

4. 取消授权

4.1 基本撤销操作

查看当前权限

sql 复制代码
SHOW GRANTS FOR 'dba_user'@'%';

撤销单个权限

sql 复制代码
REVOKE DELETE ON db_test.* FROM 'dba_user'@'%';

撤销多个权限

sql 复制代码
REVOKE INSERT, UPDATE ON db_test.* FROM 'dba_user'@'%';

撤销所有权限(等价于回到 USAGE 状态,仅可连接)

sql 复制代码
REVOKE ALL PRIVILEGES ON db_test.* FROM 'dba_user'@'%';

撤销 GRANT OPTION(取消该用户授予他人权限的权力)

sql 复制代码
REVOKE GRANT OPTION ON db_test.* FROM 'dba_user'@'%';

撤销全局级别权限

sql 复制代码
REVOKE SUPER, FILE ON *.* FROM 'dba_user'@'%';

撤销动态权限(MySQL 8.0 新增)

sql 复制代码
REVOKE BINLOG_ADMIN ON *.* FROM 'dba_user'@'%';

验证撤销结果

sql 复制代码
SHOW GRANTS FOR 'dba_user'@'%';

4.2 取消授权需要具备的权限

条件 说明
执行者必须是授权者本人 只有当初授予权限的用户(或拥有该权限 + GRANT OPTION 的用户)才能撤销
拥有 GRANT OPTION 对目标层级的权限持有 GRANT OPTION,才能撤销同层级的权限
拥有 CREATE USER 撤销全局级权限时需要(MySQL 8.0 中,REVOKE 全局权限会隐含检查此权限)
拥有 SYSTEM_USER(MySQL 8.0) 撤销 SYSTEM_USER 权限时,执行者本身也必须是 SYSTEM_USER
root 或超级用户 root 用户天然拥有所有权限,可以撤销任何用户的权限
sql 复制代码
-- 示例:让 dba_user 具备授予和撤销 db_test 权限的能力
GRANT ALL PRIVILEGES ON db_test.* TO 'dba_user'@'%' WITH GRANT OPTION;

4.3 注意事项

  1. REVOKE 只撤销已显式授予的权限,不会影响通过角色获得的权限
  2. 撤销 ALL PRIVILEGES 后,用户仍有 USAGE 权限(即可连接)
  3. 要完全禁止连接,需 DROP USER 'username'@'host'
  4. 撤销权限后,已存在的连接不会立即受影响(MySQL 权限在连接时加载)
  5. MySQL 8.0 中用户可能通过角色间接获得权限,需同时检查角色权限

  1. 部分内容由AI生成
  2. 如有不对,欢迎指正!!!
相关推荐
布莱克60539 分钟前
理解数据库聚簇索引:原理、优势与适用场景
数据库·mysql
Nturmoils1 小时前
只面对一张表:KingbaseES 超表如何简化海量时序数据管理
数据库
starrocks_stella2 小时前
StarRocks 如何查询 Paimon 半结构化数据?Variant、Shredding 与 SQL 实践
数据库
这个DBA有点耶2 小时前
MySQL迁移实战:从mysqldump到专业工具的完整选型指南
数据库·mysql·dba
小白说大模型3 小时前
LLM集成数据库的幻觉治理:当AI给出的SQL建议是错的
数据库·人工智能·sql·oracle·重构·开源
zcmodeltech3 小时前
工程机械与矿山机械沙盘模型多系统协同控制系统设计:基于STM32与Modbus RTU的露天开采-井下掘进-智慧矿山全场景联动方案
数据库·stm32·单片机·嵌入式硬件·制造·多分类
曹牧3 小时前
Oracle:空值排序
数据库·oracle
SelectDB4 小时前
Apache Doris 与 StarRocks 深度对比:2026 年 OLAP 引擎选型指南
数据库
lbb 小魔仙4 小时前
谁替 AI Agent 记住时间?——从航海钟到智能数据库,三百年时延坍缩史
数据库·人工智能·db