MySQL 权限

MySQL 的权限信息存储在授权表中。

可用权限列表:https://dev.mysql.com/doc/refman/8.0/en/privileges-provided.html

一、权限级别

  • 管理权限:管理 MySQL 服务器。

  • 数据库权限:管理数据库和所有数据库对象。

  • 数据库对象权限:管理数据库对象。

二、静态权限

静态权限内置在服务器中,始终可授予用户账户,且不能取消注册。

1. 修改权限

(1)ALTER

  • 拥有 ALTER TABLE 语句的权限。
  • 执行 ALTER TABLE 还需要 CREATE、INSERT 权限。

(2)ALTER ROUTINE

  • 拥有 alter/drop 存储例程(存储过程和函数)的权限。

2. 创建权限

(1)CREATE USER

  • 拥有 ALTER USER、CREATE ROLE、CREATE USER、DROP ROLE、DROP USER、RENAME USER、REVOKE ALL PRIVILEGES 语句的权限。

(2)CREATE ROLE

  • 拥有 CREATE ROLE 语句的权限。
  • CREATE USER 权限包含此权限,且权限范围更大。

(3)CREATE

  • 拥有创建数据库和表的权限。

(4)CREATE VIEW

  • 拥有 CREATE VIEW 语句的权限。

(5)CREATE ROUTINE

  • 拥有创建存储例程(存储过程和函数)的权限。

(6)CREATE TABLESPACE

  • 拥有 create/alter/drop tablespace 和日志组的权限。

(7)CREATE TEMPORARY TABLES

  • 拥有 CREATE TEMPORARY TABLE 语句的权限。
  • 临时表创建后,不再进行进一步的权限检查。

3. 删除权限

(1)DELETE

  • 拥有删除表中数据的权限。

(2)DROP

  • 拥有 drop 数据库、表、视图的权限。
  • ALTER TABLE … DROP PARTITION 语句和 TRUNCATE TABLE 语句也需要此权限。

(3)DROP ROLE

  • 拥有 DROP ROLE 语句的权限。
  • CREATE USER 权限包含此权限,且权限范围更大。

4. 重要权限汇总

(1)ALL、ALL PRIVILEGES

  • 代表全部权限。

(2)FILE

  • 允许使用 LOAD DATA 和 SELECT … INTO OUTFILE 语句以及 LOAD_FILE() 函数,在服务器主机上读写文件。
  • 允许在 MySQL 服务器具有写访问权的任何目录中创建新文件。
  • 允许对 CREATE TABLE 语句使用 DATA DIRECTORY 或 INDEX DIRECTORY 选项。
  • 安全措施:服务器不会覆盖现有文件,可通过 secure_file_priv 限制文件读写权限。

(3)PROCESS

  • 控制对服务器内执行线程信息(即会话执行语句的信息)的访问,涉及 SHOW PROCESSLIST、mysqladmin processlist、信息表 INFORMATION_SCHEMA.PROCESSLIST。
  • 此权限允许用户访问所有线程信息,包括其他用户的线程。
  • 无此权限时,非匿名用户只能访问自己的线程信息,匿名用户无法访问线程信息。
  • 拥有 SHOW ENGINE 语句的权限,可访问 INFORMATION_SCHEMA.INNODB_xxx、INFORMATION_SCHEMA.FILES_xxx 等信息表。

(4)SUPER(已过时,将来会删除)

  • 允许动态修改系统变量(对应动态权限 SYSTEM_VARIABLES_ADMIN、SESSION_VARIABLES_ADMIN)。
  • 允许更改全局事务特征(对应动态权限 SYSTEM_VARIABLES_ADMIN)。
  • 支持复制和组复制相关操作(对应动态权限 REPLICATION_SLAVE_ADMIN、GROUP_REPLICATION_ADMIN)。
  • 可控制二进制日志(对应动态权限 BINLOG_ADMIN);若启用二进制日志记录,创建或更改存储功能可能也需要此权限。
  • 执行视图或存储程序时允许设置有效授权 ID(对应动态权限 SET_USER_ID)。
  • 拥有 CREATE SERVER、ALTER SERVER、DROP SERVER 语句的权限。
  • 拥有 mysqladmin debug 命令的权限。
  • 允许 InnoDB 加密密钥轮换(对应动态权限 ENCRYPTION_KEY_ADMIN)。
  • 允许执行版本令牌用户定义的功能(对应动态权限 VERSION_TOKEN_ADMIN)。
  • 允许使用 GRANT 语句中的 WITH ADMIN OPTION 子句授予或撤销角色,以及 ROLES_GRAPHML() 函数的非空 <graphml 元素内容(对应动态权限 ROLE_ADMIN)。
  • 允许控制非超级用户的拒绝连接,如杀死其他用户的线程、使服务器不执行 init_connect 系统变量内容等。

5. 操作数据库对象的权限

(1)EVENT

  • 拥有 create/alter/drop/display events 的权限。

(2)INDEX

  • 拥有 create/drop 索引的权限。

(3)TRIGGER

  • 允许对触发器进行操作,表需要此权限才能 create/drop/execute/display triggers 及执行触发器。

(4)INSERT

  • 拥有向表中插入数据的权限。
  • ANALYZE TABLE、OPTIMIZE TABLE、REPAIR TABLE 等表维护语句也需要此权限。

(5)LOCK TABLES

  • 拥有 LOCK TABLES 语句的权限。

(6)SELECT

  • 拥有 SELECT 语句的权限。
  • UPDATE 语句的列表达式 col_name=expr 中需要此权限。
  • DELETE/UPDATE 的 WHERE 子句需要此权限。
  • 与 EXPLAIN 一起使用的表/视图需要此权限。

(7)UPDATE

  • 允许更新表中数据。

(8)EXECUTE

  • 拥有执行存储例程(存储过程和函数)的权限。

6. 其他权限

(1)GRANT OPTION

  • 拥有 grant/revoke 的权限。

(2)PROXY

  • 代理权限。

(3)REFERENCES

  • 创建外键约束时,要求父表具有此权限。

(4)RELOAD

  • 拥有 FLUSH 语句的权限。
  • 支持与 FLUSH 操作等效的 mysqladmin 命令(如 flush-hosts、flush-logs、flush-hosts, flush-logs, flush-privileges, flush-status, flush-tables, flush-threads, refresh 和 reload),其中 reload 命令会让服务器将授权表重新加载到内存中。
  • 支持与 FLUSH 操作相关的 mysqldump 选项(–flush-logs 和 --master-data)。

(5)REPLICATION CLIENT

  • 拥有 SHOW REPLICAS | SHOW SLAVE HOSTS、SHOW RELAYLOG EVENTS 和 SHOW BINARY LOGS 语句的权限。
  • mysqlbinlog 的 --read-from-remote-server(-R) 和 --read-from-remote-master 选项也需要此权限。

(6)SHOW DATABASES

  • 拥有 SHOW DATABASE 语句的权限。

(7)SHOW VIEW

  • 拥有 SHOW CREATE VIEW 语句的权限。
  • 与 EXPLAIN 一起使用的视图需要此权限。

(8)SHUTDOWN

  • 拥有 SHUTDOWN/RESTART 语句的权限。
  • 拥有 mysqladmin shutdown 命令的权限。
  • 拥有 C API 函数 mysql_shutdown() 的权限。

(9)USAGE

  • 代表无权限。
  • 可用于全局级别的 GRANT … WITH GRANT OPTION 语句,无需指定权限。
  • SHOW GRANTS 会显示 USAGE 为无权限。

三、动态权限

动态权限大多在服务器启动时定义,部分由特定组件/插件定义,需启用相应组件/插件才能使用。动态权限可在运行时注册和注销,仅适用于全局级别,注册信息持久保存在 mysql.global_grants 表中,服务器启动时自动注册,GRANT/REVOKE 语句可更改表内容,FLUSH PRIVILEGES 语句会读取并注册未注册的权限。

1. 与插件相关

(1)APPLICATION_PASSWORD_ADMIN

  • 对于双密码功能,允许通过 ALTER USER、SET PASSWORD 子句(RETAIN CURRENT PASSWORD 和 DISCARD OLD PASSWORD)操纵第二密码。
  • 若允许一个账户操作所有账户的第二密码,需授予该账户 CREATE USER 权限。

(2)AUDIT_ADMIN

  • 允许配置审计日志,由 audit_log 插件定义。

(3)CLONE_ADMIN

  • 拥有 CLONE 语句的权限,包含 BACKUP_ADMIN/SHUTDOWN 权限。

(4)FIREWALL_ADMIN

  • 拥有所有用户防火墙规则的管理权限,由 MYSQL_FIREWALL 插件定义。

(5)FIREWALL_USER

  • 拥有更新自己的防火墙规则的权限,由 MYSQL_FIREWALL 插件定义。

(6)ENCRYPTION_KEY_ADMIN

  • 允许 InnoDB 加密密钥轮换。

(7)VERSION_TOKEN_ADMIN

  • 允许执行版本令牌用户定义的功能,由 version_tokens 插件定义。

2. 与备份相关

(1)BACKUP_ADMIN

  • 允许执行 LOCK INSTANCE FOR BACKUP 语句,及访问性能表 performance_schema.log_status(访问此表还需要 SELECT 权限)。
  • 早期版本升级到 8.0 时,具有 RELOAD 权限的用户会被自动赋予此权限。

3. 与二进制日志相关

(1)BINLOG_ADMIN

  • 允许通过 PURGE BINARY LOGS 和 BINLOG 语句控制二进制日志。

(2)BINLOG_ENCRYPTION_ADMIN

  • 允许设置系统变量 binlog_encryption(用于激活或禁用二进制日志和中继日志的加密)。

4. redo 日志相关

(1)INNODB_REDO_LOG_ARCHIVE

  • 拥有激活/禁用 redo 日志的权限。

(2)INNODB_REDO_LOG_ENABLE

  • 拥有通过 ALTER INSTANCE {ENABLE|DISABLE} INNODB REDO_LOG 语句激活/禁用 redo 日志的权限。

5. 与复制/组复制相关

(1)GROUP_REPLICATION_ADMIN

  • 拥有通过 START|STOP GROUP REPLICATION 语句启动/停止组复制的权限。
  • 拥有修改系统变量 group_replication_consistency 的权限。
  • 拥有使用函数 group_replication_set_write_concurrency() 和 group_replication_set_communication_protocol() 的权限。

(2)REPLICATION_APPLIER

  • 拥有 CHANGE REPLICATION SOURCE TO 语句的权限(开启复制通道,且 mysqlbinlog 的输出中包含 BINLOG 语句)。

(3)REPLICATION_SLAVE_ADMIN

  • 拥有通过 START REPLICA | SLAVE 和 STOP REPLICA | SLAVE 语句开始和停止复制的权限。
  • 拥有 CHANGE REPLICATION SOURCE TO 语句和 CHANGE REPLICATION FILTER 语句的权限,不适用于组复制(组复制权限为 GROUP_REPLICATION_ADMIN)。

6. 与刷新相关

(1)FLUSH_OPTIMIZER_COSTS

  • 拥有 FLUSH_OPTIMIZER_COSTS 语句的权限。

(2)FLUSH_STATUS

  • 拥有 FLUSH_STATUS 语句的权限。

(3)FLUSH_TABLES

  • 拥有 FLUSH_TABLES 语句的权限。

(4)FLUSH_USER_RESOURCES

  • 拥有 FLUSH_USER_RESOURCES 语句的权限。

7. 与资源组相关

(1)RESOURCE_GROUP_ADMIN

  • 拥有资源组的管理权限,包括创建、更改和删除资源组,以及将线程和语句分配给资源组。

(2)RESOURCE_GROUP_USER

  • 拥有分配资源组线程和语句的权限,可使用 SET RESOURCE GROUP 语句和 RESOURCE_GROUP 优化器提示。

8. 与设置系统变量相关

(1)SYSTEM_VARIABLES_ADMIN

  • 允许动态修改系统变量,如 SET GLOBAL、SET PERSIST 语句(SET PERSIST_ONLY 语句还需要 PERSIST_RO_VARIABLES_ADMIN 权限)。
  • 允许设置受限制的会话级系统变量。
  • 允许修改全局事务特征。

(2)PERSIST_RO_VARIABLES_ADMIN

  • 允许通过 SET PERSIST_ONLY 语句进行持久化全局变量的设置,且需要同时拥有 SYSTEM_VARIABLES_ADMIN 权限。

(3)SESSION_VARIABLES_ADMIN

  • 允许设置受限制的会话级系统变量(如 binlog_format、sql_log_bin、sql_log_off)。
  • 此权限是 SYSTEM_VARIABLES_ADMIN 和 SUPER 权限的子集。

9. 与用户/角色相关

(1)SYSTEM_USER

  • 系统用户权限,用于区分系统用户和普通用户(有此权限为系统用户,无则为普通用户)。

(2)SET_USER_ID

  • 执行视图或存储程序时允许设置有效授权 ID,拥有此权限的用户可在视图或存储程序的 DEFINER 属性中指定任何账户。

(3)ROLE_ADMIN

  • 允许使用 GRANT 语句中的 WITH ADMIN OPTION 子句授予/撤销角色,以及 ROLES_GRAPHML() 函数的非空 <graphml 元素内容。
  • 设置系统变量 mandatory_roles 需要此权限。

10. 与连接相关

(1)CONNECTION_ADMIN

  • 允许使用 KILL 语句或 mysqladmin kill 命令杀掉其他用户的线程。
  • 允许设置与客户端连接有关的系统变量或规避相关限制(如 init_connect、max_connections、offline_mode、read_only)。

(2)SERVICE_CONNECTION_ADMIN

  • 允许使用管理连接接口的权限。

11. 其他

(1)SHOW_ROUTINE

  • 拥有查看存储例程(存储过程和函数)的定义和属性的权限,涉及 INFORMATION_SCHEMA.ROUTINES 信息表、SHOW CREATE FUNCTION 等语句。

(2)TABLE_ENCRYPTION_ADMIN

  • 当开启 table_encryption_privilege_check 时,允许用户覆盖默认的加密设置。

(3)XA_RECOVER_ADMIN

  • 拥有 XA RECOVER 语句的权限。

(4)NDB_STORED_USER

  • 新加入 NDB 集群时,允许分享用户、角色、权限。

四、权限授予准则

1. 基本原则

仅向账户授予所需的权限。需注意:

  • 滥用 FILE 权限可能导致从主机任意读取文件。
  • GRANT OPTION 权限允许用户将自身权限授予其他用户。
  • ALTER 权限可通过重命名表颠覆权限系统。
  • SHUTDOWN 权限可通过关闭服务器拒绝为其他用户提供服务。
  • PROCESS 权限可查看当前执行语句的纯文本,包括密码相关语句。
  • SUPER 权限可终止其他会话或更改服务器运行方式。
  • 授予 mysql 系统数据库权限可能导致密码和访问权限被篡改。

2. 静态权限与动态权限对比

类型 特点
静态权限 内置在服务器中,始终可授予,不能取消注册。
动态权限 可在运行时注册和注销;由组件/插件定义,卸载后不取消注册;仅适用于全局级别;ALL 包含所有静态权限和已注册的动态权限。

3. 将账户从 SUPER 迁移到动态权限

(1)迁移原因

  • 许多原需 SUPER 权限的操作已与动态权限关联,动态权限限制更严格。
  • SUPER 权限已过时,将来会删除。

(2)迁移过程

  • 查找拥有 SUPER 权限的账户:

    SELECT GRANTEE FROM INFORMATION_SCHEMA.USER_PRIVILEGES WHERE PRIVILEGE_TYPE = 'SUPER';
    
  • 以动态权限替换并回收 SUPER 权限:

    GRANT BINLOG_ADMIN, SYSTEM_VARIABLES_ADMIN ON *.* TO 'u1'@'localhost';
    REVOKE SUPER ON *.* FROM 'u1'@'localhost';