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. 如有不对,欢迎指正!!!
相关推荐
Gauss松鼠会2 小时前
【GaussDB】GaussDB锁阻塞源头查询
java·开发语言·前端·数据库·算法·gaussdb·经验总结
2601_965798472 小时前
How to Build a Custom Artisan Store on WordPress: Crafti Theme Review
linux·服务器·数据库
霸道流氓气质2 小时前
Spring 事务传播机制与 REQUIRES_NEW
java·数据库·spring
YOU OU2 小时前
Redis分布式锁
数据库·redis·分布式
小草儿7993 小时前
GBase 8s CLOB → VARCHAR(32739) 数据迁移方案文档
数据库
秋田君3 小时前
QT_QColorDialog颜色对话框
java·数据库·qt
涛声依旧393163 小时前
运维项目:InnoAI SQL 助手
运维·数据库·sql
万悉科技3 小时前
时尚品牌GEO技术选型指南:LLM原生优化与AI记忆构建全解析
数据库·人工智能·搜索引擎
lb29173 小时前
在window上安装orcale数据库流程(快速,简洁)
数据库