云数据库 SelectDB 版的权限管理系统借鉴了MySQL的权限管理机制,实现了表级别细粒度的权限控制,并支持基于角色的权限访问控制和白名单机制。本文介绍云数据库 SelectDB 版权限管理系统的操作方式和详细语法细节,及一些使用时的注意事项。
权限操作
创建用户后,需要通过高权限账号给新用户授予集群、库、表的访问权限,以保证其可以正常使用。
- 如何授予集群权限,请参见授予集群访问权限。 
- 如何授予库表权限,请参见下述表格中的授权操作。 
| 操作名称 | 操作关键字 | 语法 | 
| 创建用户 | CREATE USER |  | 
| 删除用户 | DROP USER |  | 
| 授权 | GRANT |  | 
| 撤权 | REVOKE |  | 
| 创建角色 | CREATE ROLE |  | 
| 删除角色 | DROP ROLE |  | 
| 查看当前(所有)用户权限 | SHOW (ALL)GRANTS |  | 
| 查看已创建的角色 | SHOW ROLES |  | 
| 查看用户属性 | SHOW PROPERTY |  | 
| 设置用户属性 | SET PROPERTY |  | 
参数说明
| 参数 | 说明 | 
| [password_policy] | 指定密码认证登录相关策略,具体策略如下。 
 | 
操作示例
- 示例1:创建用户 - test_user且密码为123456,允许从'172.10.0.0/16'网段登录。- CREATE USER test_user@'172.10.%' IDENTIFIED BY '123456';
- 示例2:删除用户 - test_user@'172.10.%'。- DROP USER 'test_user'@'172.10.%'
- 示例3:授予用户 - test_user@'172.10.%'表- test_db.test_table的读取、修改和导入权限。- GRANT SELECT_PRIV,ALTER_PRIV,LOAD_PRIV ON test_db.test_table TO 'test_user'@'172.10.%';
- 示例4:撤销用户 - test_user数据库test_db的读取权限。- REVOKE SELECT_PRIV ON test_db.* FROM 'test_user'@'172.10.%';
- 示例5:创建角色 - test_role。- CREATE ROLE test_role;
- 示例6:删除角色 - test_role。- DROP ROLE test_role;
- 示例7:将数据库 - test_db的所有表的导入权限授予角色- test_role。- GRANT LOAD_PRIV ON test_db.* TO ROLE 'test_role';
- 示例8:将用户 - test_user@'172.10.%'的角色修改为- test_role。- GRANT "test_role" TO test_user@'172.10.%';
- 示例9:查看用户 - test_user@'%'的权限。- SHOW GRANTS FOR test_user@'%';
- 示例10:查看用户 - test_user的属性。- # 查看用户的全部属性 SHOW PROPERTY FOR 'test_user'; # 使用LIKE表达式查看用户的具体属性 SHOW PROPERTY FOR 'test_user' LIKE '%max_user_connections%';
- 示例11:设置用户 - test_user的属性。- SET PROPERTY FOR 'test_user' 'max_user_connections' = '1000';
最佳实践
常见权限系统的使用场景如下:
- 场景一 - 集群的使用者分为管理员(Admin)、开发工程师(RD)和用户(Client)。其中管理员拥有整个集群的所有权限,主要负责集群的搭建、节点管理等。开发工程师负责业务建模,包括建库建表、数据的导入和修改等。用户访问不同的数据库和表来获取数据。 - 在这种场景下,可以为管理员赋予ADMIN权限或GRANT权限。对RD赋予对任意或指定数据库表的 CREATE、DROP、ALTER、LOAD、SELECT权限。对Client赋予对任意或指定数据库表SELECT权限。同时,也可以通过创建不同的角色,来简化对多个用户的授权操作。 
- 场景二 - 一个集群内有多个业务,每个业务可能使用一个或多个数据。每个业务需要管理自己的用户。在这种场景下,管理员用户可以为每个数据库创建一个拥有DATABASE层级GRANT权限的用户。该用户仅可以对用户进行指定的数据库的授权。 
- 场景三 - 云数据库 SelectDB 版本身不支持黑名单,只有白名单功能,但可以通过某些方式来模拟黑名单。假设先创建了名为 - test_user1@'192.%'的用户,表示允许来自- 192.*的用户登录。此时如果想禁止来自- 192.168.0.0/16的用户登录。则可以再创建一个用户- test_user2@'192.168.%'的用户,并设置一个新的密码。因为- 192.168.%的优先级高于- 192.%,所以来自- 192.168.0.0/16将不能再使用旧密码进行登录。
权限注意事项
- 实例初始化时,会自动创建如下角色和用户: - operator角色:该角色为运维操作角色,拥有Node_priv和Admin_priv权限,即对云数据库 SelectDB 版的所有权限,允许从任意节点登录。仅实例内置的root用户(root@'%')拥有该角色。 
- admin角色:该角色为管理角色,拥有Admin_priv权限,即除节点变更以外的所有权限,允许从任意节点登录。实例初始化会自动创建一个该角色的用户admin(admin@'%'),支持创建多个该角色的用户。 
 
- 不支持删除或更改默认创建的角色或用户的权限。 
- 忘记admin密码。如果忘记了admin密码无法登录,可以在管控平台上重置admin密码,详情请参见重置实例admin密码。 
- ADMIN_PRIV权限只能在GLOBAL层级授予或撤销。 
- 拥有GLOBAL层级GRANT_PRIV等同于拥有ADMIN_PRIV,因为该层级的GRANT_PRIV有授予任意权限的权限,请谨慎使用。 
- 通过 - SELECT current_user();和- SELECT user();可以分别查看- current_user和- user。其中- current_user表示当前用户是以哪种身份通过认证系统的,而- user则是用户当前实际的- user_identity。所有的权限都是赋予某一个- current_user的,真实用户拥有对应的- current_user的所有权限。- 举例说明:假设创建了 - user1@'192.%'这个用户,但是来自- 192.168.0.0/16的用户- user1登录了系统,则此时的- current_user为- user1@'192.%',而- user为- user1@'192.168.%'。
权限语法细节
权限类型
| 权限名称 | 说明 | 
| GRANT_PRIV | 权限变更权限。 允许执行包括授权、撤权、添加、删除和变更用户或角色等操作。 | 
| SELECT_PRIV | 对数据库、表的只读权限。 | 
| LOAD_PRIV | 对数据库、表的写权限。包括Load、Insert、Delete等。 | 
| ALTER_PRIV | 对数据库、表的更改权限。包括重命名数据库和表,添加、删除或变更列,添加或删除分区等操作。 | 
| CREATE_PRIV | 创建数据库、表、视图的权限。 | 
| DROP_PRIV | 删除数据库、表、视图的权限。 | 
| USAGE_PRIV | 资源的使用权限。 | 
权限层级
权限层级适用于数据和资源。
数据分为全局(Global)、数据目录(Catalog)、数据库(Database)、数据表(Table)等层级,具体层级的权限介绍如下:
| 权限级别 | 说明 | 
| GLOBAL LEVEL 全局权限 | 通过GRANT语句授予的 | 
| CATALOG LEVEL 数据目录级权限 | 通过GRANT语句授予的 | 
| DATABASE LEVEL 数据库级权限 | 通过GRANT语句授予的 | 
| TABLE LEVEL 表级权限 | 通过GRANT语句授予的 | 
ADMIN/GRANT权限说明
ADMIN_PRIV和GRANT_PRIV权限同时拥有授予权限的权限,较为特殊。ADMIN_PRIV和GRANT_PRIV权限相关的操作说明如下:
- CREATE USER - 拥有ADMIN权限,或GLOBAL和DATABASE层级的GRANT权限的用户可以创建新用户。 
 
- DROP USER - 拥有ADMIN权限或全局层级的GRANT权限的用户可以删除用户。 
 
- CREATE/DROP ROLE - 拥有ADMIN权限或全局层级的GRANT权限的用户可以创建角色。 
 
- GRANT/REVOKE - 拥有ADMIN权限,或者GLOBAL层级GRANT权限的用户,可以授予或撤销任意用户的权限。 
- 拥有CATALOG层级GRANT权限的用户,可以授予或撤销任意用户对指定CATALOG的权限。 
- 拥有DATABASE层级GRANT权限的用户,可以授予或撤销任意用户对指定数据库的权限。 
- 拥有TABLE层级GRANT权限的用户,可以授予或撤销任意用户对指定数据库中指定表的权限。 
 
- SET PASSWORD - 拥有ADMIN权限,或者GLOBAL层级GRANT权限的用户,可以设置任意用户的密码。 
- 普通用户可以设置自己对应的UserIdentity的密码。自己对应的UserIdentity可以通过 - SELECT CURRENT_USER();命令查看。
- 拥有非GLOBAL层级GRANT权限的用户,不可以设置已存在用户的密码,仅能在创建用户时指定密码。 
 
用户属性列表
部分与用户相关的属性如下表所示:
| 属性名 | 说明 | 
| cpu_resource_limit | 限制查询的CPU资源。详见会话变量 | 
| default_load_cluster | 默认的导入Cluster。 | 
| exec_mem_limit | 限制查询的内存使用。详见会话变量 | 
| insert_timeout | 指定用户INSERT操作的超时限制。 | 
| max_query_instances | 用户同一时间点执行查询可以使用的执行单元个数。 | 
| max_user_connections | 最大连接数。 | 
| query_timeout | 指定用户的查询超时限制。 | 
| resource_tags | 指定用户的资源标签限制。 | 
| sql_block_rules | 设置SQL Block Rules。设置后,用户发送的查询如果匹配规则,则会被拒绝执行。 | 
如果某个用户属性(user property)在变量(variable)中也存在,例如query_timeout,生效的优先级次序是:session variable>user property>global variable>default value。较高优先级的变量未设置时,会自动采用下一个优先级的数值。
常见问题
Q:如何解决在创建用户并且进行授权时,遇到域名与IP冲突或重复IP冲突的问题?
A:执行DROP USER删除出现冲突的用户后重新创建用户,即可解决问题。
- 域名与IP冲突: - 删除该用户后,创建新用户并且授权,示例如下。 - CREATE USER test_user@['domain']; GRANT SELECT_PRIV ON.TO test_user@['domain'];- 例如,该domain被DNS解析为两个IP:IP1和IP2。 
- 对用户 - test_user@['domain']进行一次单独授权的访问IP1授权,示例如下。- GRANT ALTER_PRIV ON.TO test_user@'IP1';- 则 - test_user@'IP1'的权限会被从SELECT_PRIV修改为ALTER_PRIV,且允许访问的IP变更为IP1,再次变更- test_user@['domain']的权限时,- test_user@'IP1'也不会跟随改变。
 
- 重复IP冲突: - 删除该用户后,创建新用户,示例如下。 - CREATE USER test_user@'%' IDENTIFIED BY "12345"; CREATE USER test_user@'192.%' IDENTIFIED BY "abcde";- 在优先级上,'192.%'优先于'%'。因此,当用户 - test_user从- 192.168.0.0/16网段的机器尝试使用密码'12345'登录云数据库 SelectDB 版时会被拒绝。