ClickHouse 创建用户/角色/行权限策略/配额 Quota 限流等
Posted 东海陈光剑
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ClickHouse 创建用户/角色/行权限策略/配额 Quota 限流等相关的知识,希望对你有一定的参考价值。
1.1. 数据控制
数据控制语言( DCL ) 是一种类似于计算机编程语言的语法,用于控制对存储在数据库中的数据的访问(授权)。特别是,它是结构化查询语言(SQL) 的一个组件。数据控制语言是 SQL 命令中的逻辑组之一。DCL 命令的示例包括:
1. GRANT允许指定的用户执行指定的任务。
2. REVOKE删除用户对数据库对象的可访问性。
ClickHouse 支持基于 RBAC(Role-Based Access Control) 的访问权限控制。本节主要介绍 ClickHouse 的权限管理和配置查询配额,包括的功能有:用户管理、角色管理、行策略管理以及资源配额管理等。
1.1.1. 概述
权限模型说明
ClickHouse 权限模型中访问实体有:
1. 用户帐户(User Account):用户账户是权限作用的实体,可以设置独立的密码和操作范围,DBA通过登陆不同的账户来行使不同的数据权限。
2. 角色(Role):角色是权限的集合,用来定义用户行使权限的范围。
3. 行策略(Row Policy):根据过滤条件创建行策略,从而限制用户可以从表中读取哪些行数据。
4. 用户配置(Settings Profile)
a) 可以在users.xml中设置用户配置节点内<clickhouse><profiles></profiles></clickhouse>,定义多组profile,并为每组profile定义不同的配置项,限制资源的使用,例如限制一次查询的资源消耗(max_memory_usage)、限制单个用户使用的最大内存用量(max_memory_usage_for_user)等。
b) 多个profile的配置可以复用。
c) 修改了users.xml的参数之后是即时生效的。
5. 配额(Quota):配额,限制资源的使用。通过配置时间间隔(interval),对一定时间内的资源消耗进行限制。例如,配置时间周期(duration)内允许的请求总数(queries)、错误总数(errors)、允许返回的行数(result_rows)、读取的数据行数(read_rows)、允许执行的查询时间(execution_time)等。属性值为0,表示不做任何限制。
可以通过 SQL 终端配置(CREATE/ALTER/DROP USER|ROLE|ROW POLICY| QUOTA等)或通过users.xml与config.xml配置文件来设置(但不能同时通过两种配置方法管理同一个访问实体)。例如,执行SHOW GRANTS查看当用户授予的权限:
GRANT SHOW, SELECT, INSERT, ALTER, CREATE, DROP, TRUNCATE, OPTIMIZE, KILL QUERY, MOVE PARTITION BETWEEN SHARDS, SYSTEM, dictGet, INTROSPECTION, SOURCES ON *.* TO default
这个时候,我们去查询系统用户信息,是没有权限的:
SELECT *
FROM system.users
Query id: 037bf01e-bcc4-4dcf-b293-c82cdee7e763
0 rows in set. Elapsed: 0.001 sec.
Received exception from server (version 22.4.1):
Code: 497. DB::Exception: Received from 127.0.0.1:9009. DB::Exception: default: Not enough privileges. To execute this query it's necessary to have grant SHOW USERS ON *.*. (ACCESS_DENIED)
我们需要开启 default 用户的管理员权限,使得 default用户可以创建其它用户,并授予它们权限。
配置管理员账户
管理员账户主要用来进行权限分配和管理。开启管理权限需要在users.xml中进行如下配置:
在users.xml中的<clickhouse><users><default></default></users></clickhouse>位置新增一行配置:<access_management>1</access_management>,配置如下:
<users>
<default>
<!-- PASSWORD=$(base64 < /dev/urandom | head -c8); echo "$PASSWORD"; echo -n "$PASSWORD" | sha256sum | tr -d '-' -->
<!-- password 7Dv7Ib0g -->
<password_sha256_hex>0c9858b4a1fb6c66d637e6b3a5e0977912c22a9d2f77e007ef7594226af409f5</password_sha256_hex>
<networks>
<ip>::/0</ip>
</networks>
<profile>default</profile>
<quota>default</quota>
<!-- User can create other users and grant rights to them. -->
<access_management>1</access_management>
</default>
...
</users>
access_management 默认为0,设置为1,标识开启管理员权限。这个时候,我们无需重启 ClickHouse Server,ClickHouse 会监听配置文件的变更,ConfigReloader会自动加载最新配置。 我们修改完users.xml 配置之后,ClickHouse 自动加载配置的Server 端日志如下:
2022.03.25 18:20:03.930643 [ 3362581 ] <Debug> ConfigReloader: Loading config 'users.xml'
Processing configuration file 'users.xml'.
Saved preprocessed configuration to '/Users/data/clickhouse/preprocessed_configs/users.xml'.
2022.03.25 18:20:03.932980 [ 3362581 ] <Debug> ConfigReloader: Loaded config 'users.xml', performing update on configuration
2022.03.25 18:20:03.933144 [ 3362581 ] <Trace> ContextAccess (default): Settings: readonly=0, allow_ddl=true, allow_introspection_functions=false
2022.03.25 18:20:03.933193 [ 3362581 ] <Trace> ContextAccess (default): List of all grants: GRANT ALL ON *.* WITH GRANT OPTION
2022.03.25 18:20:03.933214 [ 3362581 ] <Trace> ContextAccess (default): List of all grants including implicit: GRANT ALL ON *.* WITH GRANT OPTION
2022.03.25 18:20:03.933246 [ 3362581 ] <Trace> ContextAccess (default): Settings: readonly=0, allow_ddl=true, allow_introspection_functions=false
2022.03.25 18:20:03.933266 [ 3362581 ] <Trace> ContextAccess (default): List of all grants: GRANT ALL ON *.* WITH GRANT OPTION
2022.03.25 18:20:03.933283 [ 3362581 ] <Trace> ContextAccess (default): List of all grants including implicit: GRANT ALL ON *.* WITH GRANT OPTION
2022.03.25 18:20:03.933465 [ 3362581 ] <Debug> ConfigReloader: Loaded config 'users.xml', performed update on configuration
这个时候,我们再来查看系统用户信息,可以发现已经有权限了:
SELECT *
FROM system.users
FORMAT Vertical
Query id: 3f940543-b087-4cfe-8f27-7552145f54fc
Row 1:
──────
name: ck
id: ca2a268d-cf12-d78b-e74e-8b5014804561
storage: users.xml
auth_type: sha256_password
auth_params:
host_ip: ['::/0']
host_names: []
host_names_regexp: []
host_names_like: []
default_roles_all: 1
default_roles_list: []
default_roles_except: []
grantees_any: 1
grantees_list: []
grantees_except: []
default_database:
Row 2:
──────
name: default
id: 94309d50-4f52-5250-31bd-74fecac179db
storage: users.xml
auth_type: sha256_password
auth_params:
host_ip: ['::/0']
host_names: []
host_names_regexp: []
host_names_like: []
default_roles_all: 1
default_roles_list: []
default_roles_except: []
grantees_any: 1
grantees_list: []
grantees_except: []
default_database:
2 rows in set. Elapsed: 0.002 sec.
1.1.2. 创建用户
语法
CREATE USER [IF NOT EXISTS | OR REPLACE] name1 [ON CLUSTER cluster_name1]
[, name2 [ON CLUSTER cluster_name2] ...]
[NOT IDENTIFIED | IDENTIFIED [WITH no_password | plaintext_password | sha256_password | sha256_hash | double_sha1_password | double_sha1_hash] BY 'password' | 'hash' | WITH ldap SERVER 'server_name' | WITH kerberos [REALM 'realm']]
[HOST LOCAL | NAME 'name' | REGEXP 'name_regexp' | IP 'address' | LIKE 'pattern' [,...] | ANY | NONE]
[DEFAULT ROLE role [,...]]
[DEFAULT DATABASE database | NONE]
[GRANTEES user | role | ANY | NONE [,...] [EXCEPT user | role [,...]]]
[SETTINGS variable [= value] [MIN [=] min_value] [MAX [=] max_value] [READONLY | WRITABLE] | PROFILE 'profile_name'] [,...]
功能说明
用户名
CREATE USER name1:创建一个用户name1。
集群用户创建
如果是在ClickHouse分布式集群cluster_name上创建用户,则使用ON CLUSTER cluster_name子句,这样会在整个集群的每个节点上都创建相同的用户。
设置密码
ClickHouse 支持多种用户鉴权认证。其中,IDENTIFIED WITH 指定用户 name1 的密码。可以无密码(no_password)、明文密码(plaintext_password),还可以设置密文密码,其中加密算法有sha256_password、sha256_hash、double_sha1_password、double_sha1_hash等。还支持 ldap 认证授权协议服务和kerberos 认证授权服务。示例如下:
IDENTIFIED WITH no_password
IDENTIFIED WITH plaintext_password BY 'qwerty'
IDENTIFIED WITH sha256_password BY 'qwerty' or IDENTIFIED BY 'password'
IDENTIFIED WITH sha256_hash BY 'hash'
IDENTIFIED WITH double_sha1_password BY 'qwerty'
IDENTIFIED WITH double_sha1_hash BY 'hash'
IDENTIFIED WITH ldap SERVER 'server_name'
IDENTIFIED WITH kerberos or IDENTIFIED WITH kerberos REALM 'realm'
访问Host配置
HOST子句用来指定用户 name1 可以访问的主机。配置方式有:
1. HOST IP 'ip_address_or_subnetwork' :指定用户IP白名单,只有在当用户在这些 IP 名单里的机器才能访问 ClickHouse Server。例如,HOST IP '192.168.0.0/16', HOST IP '2001:DB8::/32'. 在生产环境中使用时,推荐使用HOST IP地址及其掩码,不要使用REGEXP 'name_regexp'、LIKE 'pattern',因为可能会导致额外的延迟。
2. HOST ANY:用户可以在任意位置访问 ClickHouse Server。
3. HOST LOCAL:只能在本机访问 ClickHouse Server。
4. HOST NAME 'fqdn':用户只能通过特定的域名访问 ClickHouse Server。例如,HOST NAME 'mysite.com'。
5. HOST REGEXP 'regexp':通过域名正则表达式匹配模式,指定可以访问 ClickHouse Server的域名集合。例如, HOST REGEXP '.*\\.mysite\\.com'。
6. HOST LIKE 'template':使用LIKE算子指定可以访问ClickHouse Server的域名集合。例如, HOST LIKE '%' 等价于HOST ANY, HOST LIKE '%.mysite.com' 表示所有 *.mysite.com 域名。
另外,还可以使用 user_name@'host' 语法来指定用户客户端地址,例如:
CREATE USER mira@'127.0.0.1' :等价于 HOST IP '127.0.0.1'。
CREATE USER mira@'localhost' :等价于 HOST LOCAL。
CREATE USER mira@'192.168.%.%' :等价于 HOST LIKE 192.168.%.%'。
GRANTEES子句
GRANTEES user | role | ANY | NONE: 指定当前用户 name1 可以授权的目标对象。
选项说明:
1. user:指定用户name1可以授予权限的用户。
2. role: 指定用户name1可以授予权限的角色。
3. ANY:默认设置,用户name1可以向任何人授予权限。
4. NONE:用户name1 不可以授予权限。
还可以使用EXCEPT表达式排除任何用户或角色。例如:
CREATE USER user1 GRANTEES ANY EXCEPT user2
表示如果 user1 具有通过 GRANT OPTION 授予的某些权限,它可以将这些权限授予除user2之外的任何人。
实例讲解
创建用户
创建一个用户名为 root,明文密码为 root 的用户:
CREATE USER root HOST IP '127.0.0.1' IDENTIFIED WITH plaintext_password BY 'root'
执行上面的 SQL,发现如下报错:
Received exception from server (version 22.4.1):
Code: 514. DB::Exception: Received from 127.0.0.1:9009. DB::Exception: Could not insert user `root` because there is no writeable access storage in user directories. (ACCESS_STORAGE_FOR_INSERTION_NOT_FOUND)
配置用户数据的存储目录
我们还需要在ClickHouse 配置文件config.xml中的<clickhouse><user_directories><local_directory><path>节点,配置配置权限管理数据的本地存储路径,我们设置为/Users/data/clickhouse/users/,具体配置如下:
<!-- Sources to read users, roles, access rights, profiles of settings, quotas. -->
<user_directories>
<users_xml>
<!-- Path to configuration file with predefined users. -->
<path>users.xml</path>
</users_xml>
<local_directory>
<!-- Path to folder where users created by SQL commands are stored. -->
<path>/Users/data/clickhouse/users/</path>
</local_directory>
</user_directories>
配置完成,保存 config.xml 文件,需要重启ClickHouse Server。然后,我们就可以用default用户管理其他用户了。再次执行上面的 SQL,创建成功。
查看用户详情
可以执行如下 SQL 去系统用户表system.users里面查看我们创建的用户详情:
SELECT
name,
id,
storage,
auth_type,
host_names,
default_roles_all,
grantees_any
FROM system.users
FORMAT Vertical
Query id: 72953144-a0c8-4fb6-afb6-d3e67f81c34f
Row 1:
──────
name: ck
id: ca2a268d-cf12-d78b-e74e-8b5014804561
storage: users.xml
auth_type: sha256_password
host_names: []
default_roles_all: 1
grantees_any: 1
Row 2:
──────
name: default
id: 94309d50-4f52-5250-31bd-74fecac179db
storage: users.xml
auth_type: sha256_password
host_names: []
default_roles_all: 1
grantees_any: 1
Row 3:
──────
name: root
id: 094a7c28-29fd-abba-c886-1c569be7e784
storage: local directory
auth_type: plaintext_password
host_names: ['localhost']
default_roles_all: 1
grantees_any: 1
3 rows in set. Elapsed: 0.002 sec.
可以看到我们创建的用户root的 id 是UUID:094a7c28-29fd-abba-c886-1c569be7e784。存储类型storage:local directory。我们去 ClickHouse 创建的用户数据目录/Users/data/clickhouse/users下面查看文件列表如下:
$ls -la|awk 'print $9 $10 $11'
.
..
094a7c28-29fd-abba-c886-1c569be7e784.sql
quotas.list
roles.list
row_policies.list
settings_profiles.list
users.list
可以看到一个094a7c28-29fd-abba-c886-1c569be7e784.sql,命名正是用户 root 的 id。然后,在文件users.list中存储的是“用户名UUID”列表:
$cat users.list
root094a7c28-29fd-abba-c886-1c569be7e784
如果我们给用户指定了quotas、roles、row_policies、settings_profiles等配置,也将会存储在对应的文件中。
用户登录
成功创建用户 root 之后,我们就可以使用该用户名密码登录了。登录命令如下:
$clickhouse client -h 127.0.0.1 -u root --password 'root' --port 9009
ClickHouse client version 22.4.1.1.
Connecting to 127.0.0.1:9009 as user root.
Connected to ClickHouse server version 22.4.1 revision 54455.
配置文件
本节实例中用到的config.xml 和 users.xml 配置文件的完整内容如下:
config.xml
<?xml version="1.0"?>
<clickhouse>
<logger>
<level>trace</level>
<log>/Users/data/clickhouse/logs/clickhouse.log</log>
<errorlog>/Users/data/clickhouse/logs/error.log</errorlog>
<size>500M</size>
<count>5</count>
</logger>
<http_port>8123</http_port>
<tcp_port>9009</tcp_port>
<interserver_http_port>9000</interserver_http_port>
<interserver_http_host>127.0.0.1</interserver_http_host>
<listen_host>0.0.0.0</listen_host>
<max_connections>4096</max_connections>
<keep_alive_timeout>300</keep_alive_timeout>
<max_concurrent_queries>1000</max_concurrent_queries>
<uncompressed_cache_size>8589934592</uncompressed_cache_size>
<mark_cache_size>5368709120</mark_cache_size>
<!-- Path to data directory, with trailing slash. -->
<path>/Users/data/clickhouse/</path>
<!-- Path to temporary data for processing hard queries. -->
<tmp_path>/Users/data/clickhouse/tmp/</tmp_path>
<!-- Directory with user provided files that are accessible by 'file' table function. -->
<user_files_path>/Users/data/clickhouse/user_files/</user_files_path>
<!-- Sources to read users, roles, access rights, profiles of settings, quotas. -->
<user_directories>
<users_xml>
<!-- Path to configuration file with predefined users. -->
<path>users.xml</path>
</users_xml>
<local_directory>
<!-- Path to folder where users created by SQL commands are stored. -->
<path>/Users/data/clickhouse/users/</path>
</local_directory>
</user_directories>
<default_profile>default</default_profile>
<default_database>default</default_database>
<builtin_dictionaries_reload_interval>3600</builtin_dictionaries_reload_interval>
<max_session_timeout>3600</max_session_timeout>
<default_session_timeout>300</default_session_timeout>
<max_table_size_to_drop>0</max_table_size_to_drop>
<merge_tree>
<parts_to_delay_insert>300</parts_to_delay_insert>
<parts_to_throw_insert>600</parts_to_throw_insert>
<max_delay_to_insert>2</max_delay_to_insert>
</merge_tree>
<max_table_size_to_drop>0</max_table_size_to_drop>
<max_partition_size_to_drop>0</max_partition_size_to_drop>
</clickhouse>
users.xml
<?xml version="1.0"?>
<clickhouse>
<profiles>
<default>
<max_memory_usage>10000000000</max_memory_usage>
<use_uncompressed_cache>0</use_uncompressed_cache>
<load_balancing>random</load_balancing>
</default>
<readonly>
<max_memory_usage>10000000000</max_memory_usage>
<use_uncompressed_cache>0</use_uncompressed_cache>
<load_balancing>random</load_balancing>
<readonly>1</readonly>
</readonly>
</profiles>
<quotas>
<!-- Name of quota. -->
<default>
<interval>
<queries>0</queries>
<errors>0</errors>
<result_rows>0</result_rows>
<read_rows>0</read_rows>
<execution_time>0</execution_time>
</interval>
</default>
</quotas>
<users>
<default>
<!-- PASSWORD=$(base64 < /dev/urandom | head -c8); echo "$PASSWORD"; echo -n "$PASSWORD" | sha256sum | tr -d '-' -->
<!-- password 7Dv7Ib0g -->
<password_sha256_hex>0c9858b4a1fb6c66d637e6b3a5e0977912c22a9d2f77e007ef7594226af409f5</password_sha256_hex>
<networks>
<ip>::/0</ip>
</networks>
<profile>default</profile>
<quota>default</quota>
<!-- User can create other users and grant rights to them. -->
<access_management>1</access_management>
</default>
<ck>
<password_sha256_hex>0c9858b4a1fb6c66d637e6b3a5e0977912c22a9d2f77e007ef7594226af409f5</password_sha256_hex>
<networks>
<ip>::/0</ip>
</networks>
<profile>readonly</profile>
<quota>default</quota>
</ck>
</users>
</clickhouse>
1.1.3. 创建角色
ClickHouse 是基于角色访问控制RBAC(Role-Based Access Control )实现的权限管理。在 RBAC中,核心模型就是:权限=>角色=>用户。权限与角色相关联,赋予用户相应的角色,用户将得到这些角色关联的权限。
语法
CREATE ROLE [IF NOT EXISTS | OR REPLACE] role_name1 [, role_name2 ...]
[SETTINGS variable [= value] [MIN [=] min_value] [MAX [=] max_value] [READONLY|WRITABLE] | PROFILE 'profile_name'] [,...]
功能说明
创建角色role_name1。角色与权限关联,给用户分配角色role_name1,可以获得该角色的所有权限。可以为用户分配多个角色。
使用SET DEFAULT ROLE语句或ALTER USER语句设置用户默认角色。
使用REVOKE语句撤消角色。
使用DROP ROLE语句,删除角色。已删除的角色将从分配给它的所有用户和角色中自动撤消。
实例讲解
创建角色
创建一个角色role_read:
CREATE ROLE role_read;
授予角色权限
授予角色以查询数据库clickhouse_tutorial数据的权限:
GRANT SELECT ON clickhouse_tutorial.* TO role_read;
给用户授予角色
赋予用户 root 以 role_read 角色:
GRANT role_read TO root;
用户登录查看权限
登录 root 用户:
clickhouse client -h 127.0.0.1 -u root --password 'root' --port 9009
查看数据库权限:
SHOW DATABASES
┌─name────────────────┐
│ clickhouse_tutorial │
└─────────────────────┘
可以看到用户 root 已经有了数据库clickhouse_tutorial的查看权限了。切换到clickhouse_tutorial数据库空间下面,查看所有表:
USE clickhouse_tutorial;
SHOW TABLES;
┌─name───────────────────────────────────────────┐
│ .inner.8507f16a-adaf-43a8-8416-f9b16f82ffdf │
│ .inner_id.1c93ef11-704f-4515-9596-fbdb4efdf6b8 │
│ hits_v2 │
│ user_sex_dict │
│ user_sex_dim │
│ user_tag │
│ user_tag_lv │
│ user_tag_mt_view_1 │
│ user_tag_mt_view_2 │
│ user_tag_mt_view_2_table │
│ user_tag_new │
│ user_tag_view │
│ user_tag_wv │
└────────────────────────────────────────────────┘
13 rows in set. Elapsed: 0.002 sec.
查看授权情况
执行 SHOW GRANTS命令,查看授权情况:
SHOW GRANTS
┌─GRANTS──────────────────┐
│ GRANT role_read TO root │
└─────────────────────────┘
1 rows in set. Elapsed: 0.001 sec.
切回 default 管理员账户,去系统表里查看角色详情与角色授权详情。
系统角色表system.roles:
SELECT *
FROM system.roles
┌─name──────┬─id───────────────────────────────────┬─storage─────────┐
│ role_read │ 8b42f00d-fc41-c504-12bf-4166f1a36eb2 │ local directory │
└───────────┴──────────────────────────────────────┴─────────────────┘
1 rows in set. Elapsed: 0.002 sec.
系统角色授权表system.role_grants:
SELECT *
FROM system.role_grants
┌─user_name─┬─role_name─┬─granted_role_name─┬─granted_role_is_default─┬─with_admin_option─┐
│ root │ ᴺᵁᴸᴸ │ role_read │ 1 │ 0 │
└───────────┴───────────┴───────────────────┴─────────────────────────┴───────────────────┘
1 rows in set. Elapsed: 0.002 sec.
我们去 ClickHouse 用户数据目录/Users/data/clickhouse/users下面,可以看到roles.list文件里存储了角色role_read的 UUID 信息:
$cat roles.list
role_read8b42f00d-fc41-c504-12bf-4166f1a36eb2
然后,目录下面多了一个 8b42f00d-fc41-c504-12bf-4166f1a36eb2.sql 文件,里面记录了角色role_read的创建 SQL 和为角色role_read授予权限的 SQL,内容如下:
$cat 8b42f00d-fc41-c504-12bf-4166f1a36eb2.sql
ATTACH ROLE role_read;
ATTACH GRANT SELECT ON clickhouse_tutorial.* TO role_read;
1.1.4. 创建行策略
语法
CREATE [ROW] POLICY [IF NOT EXISTS | OR REPLACE] policy_name1 [ON CLUSTER cluster_name1] ON [db1.]table1
[, policy_name2 [ON CLUSTER cluster_name2] ON [db2.]table2 ...]
[FOR SELECT] USING condition
[AS PERMISSIVE | RESTRICTIVE]
[TO role1 [, role2 ...] | ALL | ALL EXCEPT role1 [, role2 ...]]
功能说明
根据过滤条件condition,创建行策略policy_name1,用于确定用户可以从表中读取哪些行数据。行策略仅对具有只读访问权限的用户有意义。因为如果用户拥有修改权限,可以修改表或复制表分区,它就破除了行策略的限制。
AS子句指定策略应如何与其他策略组合。策略可以是允许性(PERMISSIVE)的,也可以是限制性(RESTRICTIVE)的。默认情况下,策略是允许性的,使用逻辑或OR运算符组合。当指定限制性策略,使用逻辑与AND运算符组合。
实例讲解
查询数据
使用 root 账户登陆ClickHouse客户端,执行如下查询 SQL:
SELECT *
FROM clickhouse_tutorial.user_tag
WHERE EventDate = '2022-03-24'
Query id: 731b40aa-6880-436d-bbf8-69be41ed4b9a
┌──────────────UserID─┬─────────────WatchID─┬───────────EventTime─┬─Sex─┬─Age─┬─OS─┬─RegionID─┬─RequestNum─┬──EventDate─┐
│ 1745382628175606281 │ 4611703724436325474 │ 2022-03-24 04:30:18 │ 2 │ 22 │ 42 │ 3 │ 107 │ 2022-03-24 │
│ 1266642432311731534 │ 4611720374393200609 │ 2022-03-24 04:30:18 │ 2 │ 16 │ 42 │ 13962 │ 49 │ 2022-03-24 │
│ 1080523977390906965 │ 4611724822782888722 │ 2022-03-24 04:30:18 │ 2 │ 16 │ 56 │ 15887 │ 13 │ 2022-03-24 │
└─────────────────────┴─────────────────────┴─────────────────────┴─────┴─────┴────┴──────────┴────────────┴────────────┘
┌──────────────UserID─┬─────────────WatchID─┬───────────EventTime─┬─Sex─┬─Age─┬─OS─┬─RegionID─┬─RequestNum─┬──EventDate─┐
│ 2042690798151930621 │ 4611692230555590277 │ 2022-03-24 04:17:09 │ 0 │ 0 │ 56 │ 104 │ 2 │ 2022-03-24 │
│ 2042690798151930621 │ 4611692230555590277 │ 2022-03-24 04:17:25 │ 0 │ 0 │ 56 │ 104 │ 2 │ 2022-03-24 │
│ 2042690798151930621 │ 4611692230555590277 │ 2022-03-24 04:28:21 │ 0 │ 0 │ 56 │ 104 │ 2 │ 2022-03-24 │
│ 2042690798151930622 │ 4611692230555590278 │ 2022-03-24 04:19:22 │ 0 │ 0 │ 56 │ 104 │ 2 │ 2022-03-24 │
│ 1745382628175606281 │ 4611703724436325474 │ 2022-03-24 04:20:29 │ 2 │ 22 │ 42 │ 3 │ 107 │ 2022-03-24 │
│ 1266642432311731534 │ 4611720374393200609 │ 2022-03-24 04:20:29 │ 2 │ 16 │ 42 │ 13962 │ 49 │ 2022-03-24 │
│ 1080523977390906965 │ 4611724822782888722 │ 2022-03-24 04:20:29 │ 2 │ 16 │ 56 │ 15887 │ 13 │ 2022-03-24 │
└─────────────────────┴─────────────────────┴─────────────────────┴─────┴─────┴────┴──────────┴────────────┴────────────┘
10 rows in set. Elapsed: 0.004 sec.
可以看到有 10 行数据。
创建行策略
现在我们用管理员账户 default 登陆客户端,创建一个行策略row_policy1限制用户 root 对clickhouse_tutorial.user_tag表数据中,满足过滤条件EventDate='2022-03-24'的数据的访问:
CREATE ROW POLICY row_policy1 ON clickhouse_tutorial.user_tag USING EventDate = '2022-03-24' AS RESTRICTIVE TO root;
查看行策略详情
去系统表system.row_policies中查询行策略详情:
SELECT *
FROM system.row_policies
WHERE short_name = 'row_policy1'
FORMAT Vertical
Connecting to database system at 127.0.0.1:9009 as user default.
Connected to ClickHouse server version 22.4.1 revision 54455.
Row 1:
──────
name: row_policy1 ON clickhouse_tutorial.user_tag
short_name: row_policy1
database: clickhouse_tutorial
table: user_tag
id: ef4f81ec-dfd9-6b07-a54e-71e88fb45c8d
storage: local directory
select_filter: EventDate = '2022-03-24'
is_restrictive: 1
apply_to_all: 0
apply_to_list: ['root']
apply_to_except: []
1 rows in set. Elapsed: 0.003 sec.
可以看到刚才创建的行策略的 name 是row_policy1 ON clickhouse_tutorial.user_tag。id 为ef4f81ec-dfd9-6b07-a54e-71e88fb45c8d,select_filter是EventDate = '2022-03-24' 。
行策略数据存储
我们再到用户数据目录/Users/data/clickhouse/users下面查看row_policies.list文件,内容如下:
$cat row_policies.list
+row_policy1 ON clickhouse_tutorial.user_tagef4f81ec-dfd9-6b07-a54e-71e88fb45c8d
用户数据目录下面还多了一个ef4f81ec-dfd9-6b07-a54e-71e88fb45c8d.sql文件,内容如下:
$cat ef4f81ec-dfd9-6b07-a54e-71e88fb45c8d.sql
ATTACH ROW POLICY row_policy1 ON clickhouse_tutorial.user_tag AS restrictive FOR SELECT USING EventDate = '2022-03-24' TO ID('094a7c28-29fd-abba-c886-1c569be7e784');
查询验证
再次执行如下 SQL,发现查询结果为空:
SELECT *
FROM clickhouse_tutorial.user_tag
WHERE EventDate = '2022-03-24'
Query id: 1c18f761-aaee-4e2d-8132-b16098ce4cb1
Ok.
0 rows in set. Elapsed: 0.003 sec.
删除行策略
删除行策略使用 drop row policy ON db.table_name 命令,如下:
drop row policy row_policy1 ON clickhouse_tutorial.user_tag ;
删除完行策略 row_policy1 之后,对用户 root 的行数据的访问限制也会自动删除。这个时候,我们再次执行如下 SQL 查询数据,发现又有 10 条数据返回了:
SELECT *
FROM clickhouse_tutorial.user_tag
WHERE EventDate = '2022-03-24'
Query id: 0a8529a4-e98a-4a03-8501-7285a88b18e6
┌──────────────UserID─┬─────────────WatchID─┬───────────EventTime─┬─Sex─┬─Age─┬─OS─┬─RegionID─┬─RequestNum─┬──EventDate─┐
│ 2042690798151930621 │ 4611692230555590277 │ 2022-03-24 04:17:09 │ 0 │ 0 │ 56 │ 104 │ 2 │ 2022-03-24 │
│ 2042690798151930621 │ 4611692230555590277 │ 2022-03-24 04:17:25 │ 0 │ 0 │ 56 │ 104 │ 2 │ 2022-03-24 │
│ 2042690798151930621 │ 4611692230555590277 │ 2022-03-24 04:28:21 │ 0 │ 0 │ 56 │ 104 │ 2 │ 2022-03-24 │
│ 2042690798151930622 │ 4611692230555590278 │ 2022-03-24 04:19:22 │ 0 │ 0 │ 56 │ 104 │ 2 │ 2022-03-24 │
│ 1745382628175606281 │ 4611703724436325474 │ 2022-03-24 04:20:29 │ 2 │ 22 │ 42 │ 3 │ 107 │ 2022-03-24 │
│ 1266642432311731534 │ 4611720374393200609 │ 2022-03-24 04:20:29 │ 2 │ 16 │ 42 │ 13962 │ 49 │ 2022-03-24 │
│ 1080523977390906965 │ 4611724822782888722 │ 2022-03-24 04:20:29 │ 2 │ 16 │ 56 │ 15887 │ 13 │ 2022-03-24 │
└─────────────────────┴─────────────────────┴─────────────────────┴─────┴─────┴────┴──────────┴────────────┴────────────┘
┌──────────────UserID─┬─────────────WatchID─┬───────────EventTime─┬─Sex─┬─Age─┬─OS─┬─RegionID─┬─RequestNum─┬──EventDate─┐
│ 1745382628175606281 │ 4611703724436325474 │ 2022-03-24 04:30:18 │ 2 │ 22 │ 42 │ 3 │ 107 │ 2022-03-24 │
│ 1266642432311731534 │ 4611720374393200609 │ 2022-03-24 04:30:18 │ 2 │ 16 │ 42 │ 13962 │ 49 │ 2022-03-24 │
│ 1080523977390906965 │ 4611724822782888722 │ 2022-03-24 04:30:18 │ 2 │ 16 │ 56 │ 15887 │ 13 │ 2022-03-24 │
└─────────────────────┴─────────────────────┴─────────────────────┴─────┴─────┴────┴──────────┴────────────┴────────────┘
10 rows in set. Elapsed: 0.004 sec.
1.1.5. 创建配额
配额(Quota)用来限制资源使用。配额支持在一段时间内,限制资源使用或跟踪资源的使用。配额可以在用户配置文件“users.xml”中配置。通过配额配置,还可以限制单个查询的复杂性。让我们看一下在“users.xml”中如何定义配额:
<!-- Quotas -->
<quotas>
<!-- Quota name. -->
<default>
<!-- Restrictions for a time period. You can set many intervals with different restrictions. -->
<interval>
<!-- Length of the interval. -->
<duration>3600</duration>
<!-- Unlimited. Just collect data for the specified time interval. -->
<queries>0</queries>
<query_selects>0</query_selects>
<query_inserts>0</query_inserts>
<errors>0</errors>
<result_rows>0</result_rows>
<read_rows>0</read_rows>
<execution_time>0</execution_time>
</interval>
</default>
...
</quotas>
配额默认为 0,表示不限制资源的使用,会跟踪每小时的资源消耗。每个间隔时间段,计算资源的消耗,在每次请求后输出到服务器日志。下面是一个配置具体配额限制计算资源的例子:
<res_quota>
<!-- Restrictions for a time period. You can set many intervals with different restrictions. -->
<interval>
<!-- Length of the interval. -->
<duration>3600</duration>
<queries>1000</queries>
<query_selects>100</query_selects>
<query_inserts>100</query_inserts>
<errors>100</errors>
<result_rows>1000000000</result_rows>
<read_rows>100000000000</read_rows>
<execution_time>900</execution_time>
</interval>
<interval>
<duration>86400</duration>
<queries>10000</queries>
<query_selects>10000</query_selects>
<query_inserts>10000</query_inserts>
<errors>1000</errors>
<result_rows>5000000000</result_rows>
<read_rows>500000000000</read_rows>
<execution_time>7200</execution_time>
</interval>
</res_quota>
对于“res_quota”配额,对每小时(3600s)和每 24 小时(86400 秒)设置限制。
限制参数说明:
1. duration:检查时间周期86400秒。
2. queries:请求总数上限10000。
3. query_selects:查询请求总数上限10000。
4. query_inserts:插入请求总数上限10000。
5. errors:异常查询数上限1000。
6. result_rows:结果总行数上限5000000000行。
7. read_rows:从表中读取的源行总数上限500000000000行。
8. execution_time:总查询执行时间7200秒。如果在至少一个时间间隔内,超出此执行时间限制,即终止查询,并抛出异常。
这些配额参数值,存储在系统表system.quotas_usage中。
语法
CREATE QUOTA [IF NOT EXISTS | OR REPLACE] quota_name [ON CLUSTER cluster_name]
[KEYED BY user_name | ip_address | client_key | client_key,user_name | client_key,ip_address | NOT KEYED]
[FOR [RANDOMIZED] INTERVAL number second | minute | hour | day | week | month | quarter | year
MAX queries | query_selects | query_inserts | errors | result_rows | result_bytes | read_rows | read_bytes | execution_time = number [,...] |
NO LIMITS | TRACKING ONLY [,...]]
[TO role_name [,...] | ALL | ALL EXCEPT role_name [,...]]
功能说明
创建配额,限制用户或角色的资源使用。配额持续时间的限制,以及应使用此配额的角色或用户列表。常用参数说明如下:
1. CREATE QUOTA quota_name:创建名为quota_name的配额。
2. 配额可应用于用户或角色。
3. ON CLUSTER cluster_name:在集群cluster_name上创建配额。
4. FOR INTERVAL:指定配额检查时间间隔周期。其中,queries | query_selects | query_inserts | errors | result_rows | result_bytes | read_rows | read_bytes | execution_time见上一小节中的“限制参数说明”。
5. NO LIMITS | TRACKING ONLY:不限制;仅跟踪统计查询性能数据。
6. TO role_name | user_name:配额应用于角色role_name或用户user_name。
7. ALL:配额应用于全部用户。
8. ALL EXCEPT role_name | user_name:配额应用于全部用户(除了角色role_name或用户user_name)
实例讲解
创建查询次数限制配额
给用户 root 创建一个“10 秒内只能查询 1 次的限制”:
CREATE QUOTA quota_qps_1
FOR INTERVAL 10 second MAX queries = 1
TO root;
执行查询 SQL 验证,可以发现连续 2 次执行查询 SQL,第 2 次即报错“Code: 201. DB::Exception: Received from 127.0.0.1:9009. DB::Exception: Quota for user `root` for 10s has been exceeded: queries = 2/1”,具体执行 SQL 如下:
SELECT *
FROM clickhouse_tutorial.user_tag
WHERE EventDate = '2022-03-24'
┌──────────────UserID─┬─────────────WatchID─┬───────────EventTime─┬─Sex─┬─Age─┬─OS─┬─RegionID─┬─RequestNum─┬──EventDate─┐
│ 2042690798151930621 │ 4611692230555590277 │ 2022-03-24 04:17:09 │ 0 │ 0 │ 56 │ 104 │ 2 │ 2022-03-24 │
...
│ 1080523977390906965 │ 4611724822782888722 │ 2022-03-24 04:30:18 │ 2 │ 16 │ 56 │ 15887 │ 13 │ 2022-03-24 │
└─────────────────────┴─────────────────────┴─────────────────────┴─────┴─────┴────┴──────────┴────────────┴────────────┘
10 rows in set. Elapsed: 0.003 sec.
SELECT *
FROM clickhouse_tutorial.user_tag
WHERE EventDate = '2022-03-24'
0 rows in set. Elapsed: 0.003 sec.
Received exception from server (version 22.4.1):
Code: 201. DB::Exception: Received from 127.0.0.1:9009. DB::Exception: Quota for user `root` for 10s has been exceeded: queries = 2/1. Interval will end at 2022-03-27 17:26:30. Name of quota template: `quota_qps_1`. (QUOTA_EXPIRED)
删除配额
使用 DROP QUOTA 删除配额。例如,把配额quota_qps_1删除:
drop quota quota_qps_1;
创建最大执行时间配额
再创建一个新的配额quota_qpm_10,表示“1分钟内查询次数上限 10,错误上限 1;10min 间隔时间,检查最大执行时间0.000001s”
CREATE QUOTA quota_qpm_10
FOR INTERVAL 1 minute MAX queries = 10, errors = 1,
FOR INTERVAL 10 minute MAX execution_time = 0.000001 TO root;
执行如下 SQL,观察execution_time限制抛出的异常如下:
SELECT
uniqExact(UserID) AS x,
Age,
multiIf(x > 10000, 'high', (x < 10000) AND (x > 8000), 'mid', 'low') AS level
FROM clickhouse_tutorial.user_tag
GROUP BY Age
Query id: e827418f-7fde-4036-b1c0-af04ad493d40
0 rows in set. Elapsed: 0.104 sec.
Received exception from server (version 22.4.1):
Code: 201. DB::Exception: Received from 127.0.0.1:9009. DB::Exception: Quota for user `root` for 600s has been exceeded: execution_time = 3.0000000000000001e-06/9.9999999999999995e-07. Interval will end at 2022-03-27 18:10:00. Name of quota template: `quota_qpm_10`. (QUOTA_EXPIRED)
可以看到,最大查询执行时间为3.0000000000000001e-06秒。跟终端输出的 0.104 sec不一致。因为,当前 ClickHouse配额检查时,还不不包括排序阶段和聚合计算阶段。
可以通过下面的这个例子来验证这一点。
先删除配额quota_qpm_10。然后,执行如下 SQL,可以看到耗时:
SELECT
RequestNum AS x,
multiIf(x > 10000, 'high', (x < 10000) AND (x > 8000), 'mid', 'low') AS level
FROM clickhouse_tutorial.user_tag
17747932 rows in set. Elapsed: 0.274 sec. Processed 17.75 million rows, 70.99 MB (64.65 million rows/s., 258.62 MB/s.)
我们重新创建配额quota_qpm_10,设置MAX execution_time = 0.1(单位秒),如下:
CREATE QUOTA quota_qpm_10
FOR INTERVAL 1 minute MAX queries = 10, errors = 1,
FOR INTERVAL 10 minute MAX execution_time = 0.1 TO root;
再次执行如下不带排序和聚合函数的 SQL:
SELECT
RequestNum AS x,
multiIf(x > 10000, 'high', (x < 10000) AND (x > 8000), 'mid', 'low') AS level
FROM clickhouse_tutorial.user_tag
Query id: 4bbb4e4a-db32-43c4-bba7-2aa31868dfca
┌──────x─┬─level─┐
│ 10 │ low │
│ 59 │ low │
│ 1560 │ low │
│ 4 │ low │
...
│ 4 │ low │
│ 15 │ low │
│ 44 │ low │
└────────┴───────┘
↙ Progress: 10.83 million rows, 43.30 MB (51.78 million rows/s., 207.11 MB/s.) 60%
10760295 rows in set. Elapsed: 0.209 sec. Processed 10.83 million rows, 43.30 MB (51.70 million rows/s., 206.81 MB/s.)
Received exception from server (version 22.4.1):
Code: 201. DB::Exception: Received from 127.0.0.1:9009. DB::Exception: Quota for user `root` for 600s has been exceeded: execution_time = 0.100642/0.10000000000000001. Interval will end at 2022-03-27 18:40:00. Name of quota template: `quota_qpm_10`. (QUOTA_EXPIRED)
可以看到查询处理到10.83 million rows的时候耗时0.100642 s 超过了配额中设置的 0.1s,命中配额规则限制,终止查询,抛出Code: 201. DB::Exception异常。
查看ClickHouse Server 端的查询日志,命中 Quota 限制规则查询日志如下:
2022.03.27 18:30:25.144729 [ 3864897 ] <Debug> TCP-Session: a5bb76b4-8c76-4383-bde8-cfca17853290 Creating query context from session context, user_id: 094a7c28-29fd-abba-c886-1c569be7e784, parent context user: root
2022.03.27 18:30:25.144951 [ 3864897 ] 4bbb4e4a-db32-43c4-bba7-2aa31868dfca <Debug> executeQuery: (from 127.0.0.1:55780, user: root) select RequestNum x, multiIf( x> 10000,'high', x<10000 and x>8000, 'mid', 'low' ) level from clickhouse_tutorial.user_tag
...
2022.03.27 18:30:25.353118 [ 3864897 ] 4bbb4e4a-db32-43c4-bba7-2aa31868dfca <Error> executeQuery: Code: 201. DB::Exception: Quota for user `root` for 600s has been exceeded: execution_time = 0.100642/0.10000000000000001. Interval will end at 2022-03-27 18:40:00. Name of quota template: `quota_qpm_10`. (QUOTA_EXPIRED) (version 22.4.1.1) (from 127.0.0.1:55780) (in query: select RequestNum x, multiIf( x> 10000,'high', x<10000 and x>8000, 'mid', 'low' ) level from clickhouse_tutorial.user_tag), Stack trace (when copying this message, always include the lines below):
...
2022.03.27 18:30:25.353877 [ 3864897 ] <Debug> TCPHandler: Processed in 0.209187 sec.
查看配额详情
去系统表system.quotas查看配额quota_qpm_10详情:
SELECT *
FROM system.quotas
WHERE name = 'quota_qpm_10'
FORMAT Vertical
Query id: 010300eb-5e51-4ecf-89a7-0ad2839166d2
Row 1:
──────
name: quota_qpm_10
id: 07476af8-13ab-cc04-bd77-d71831106c96
storage: local directory
keys: []
durations: [60,600]
apply_to_all: 0
apply_to_list: ['root']
apply_to_except: []
1 rows in set. Elapsed: 0.003 sec.
去系统表system.quotas_usage,查看配额quota_qpm_10的使用详细信息:
SELECT *
FROM system.quotas_usage
WHERE quota_name = 'quota_qpm_10'
FORMAT Vertical
Query id: 0040cf19-8499-4a57-bdca-e5003d1f3471
Row 1:
──────
quota_name: quota_qpm_10
quota_key:
is_current: 0
start_time: 2022-03-27 18:40:00
end_time: 2022-03-27 18:50:00
duration: 600
queries: 0
max_queries: ᴺᵁᴸᴸ
query_selects: 0
max_query_selects: ᴺᵁᴸᴸ
query_inserts: 0
max_query_inserts: ᴺᵁᴸᴸ
errors: 0
max_errors: ᴺᵁᴸᴸ
result_rows: 0
max_result_rows: ᴺᵁᴸᴸ
result_bytes: 0
max_result_bytes: ᴺᵁᴸᴸ
read_rows: 0
max_read_rows: ᴺᵁᴸᴸ
read_bytes: 0
max_read_bytes: ᴺᵁᴸᴸ
execution_time: 0
max_execution_time: 0.1
Row 2:
──────
quota_name: quota_qpm_10
quota_key:
is_current: 0
start_time: 2022-03-27 18:44:00
end_time: 2022-03-27 18:45:00
duration: 60
queries: 0
max_queries: 10
query_selects: 0
max_query_selects: ᴺᵁᴸᴸ
query_inserts: 0
max_query_inserts: ᴺᵁᴸᴸ
errors: 0
max_errors: 1
result_rows: 0
max_result_rows: ᴺᵁᴸᴸ
result_bytes: 0
max_result_bytes: ᴺᵁᴸᴸ
read_rows: 0
max_read_rows: ᴺᵁᴸᴸ
read_bytes: 0
max_read_bytes: ᴺᵁᴸᴸ
execution_time: 0
max_execution_time: ᴺᵁᴸᴸ
2 rows in set. Elapsed: 0.004 sec.
可以看到有两条记录,对应到我们创建的两个INTERVAL:
FOR INTERVAL 1 minute MAX queries = 10, errors = 1,
FOR INTERVAL 10 minute MAX execution_time = 0.000001 TO root;
1.1.6. 创建settings profile
创建设置配置文件,分配给有关用户或角色。
语法
CREATE SETTINGS PROFILE [IF NOT EXISTS | OR REPLACE] TO profile_name [ON CLUSTER cluster_name1]
[, name2 [ON CLUSTER cluster_name2] ...]
[SETTINGS variable [= value] [MIN [=] min_value] [MAX [=] max_value] [READONLY|WRITABLE] | INHERIT 'profile_name'] [,...]
功能说明
创建名为profile_name设置配置。如果是在集群上创建设置配置文件,使用ON CLUSTER 子句。
实例讲解
创建一个max_memory_usage_profile设置配置,其中包含max_memory_usage设置的值100000001 bytes,和最小值90000000 bytes、最大值110000000 bytes约束,并将其分配给用户jack:
CREATE SETTINGS PROFILE max_memory_usage_profile
SETTINGS max_memory_usage = 100000001 MIN 90000000 MAX 110000000
TO jack
1.1.7. 修改用户
ALTER修改用户USER、角色ROLE、行策略ROW POLICY、配额 QUOTA、settings profile等,与对应的CREATE创建语法、功能类似,故这里只给出语法。
语法
ALTER USER [IF EXISTS] name [ON CLUSTER cluster_name]
[RENAME TO new_name]
[IDENTIFIED [WITH PLAINTEXT_PASSWORD|SHA256_PASSWORD|DOUBLE_SHA1_PASSWORD] BY 'password'|'hash']
[[ADD|DROP] HOST LOCAL | NAME 'name' | REGEXP 'name_regexp' | IP 'address' | LIKE 'pattern' [,...] | ANY | NONE]
[DEFAULT ROLE role [,...] | ALL | ALL EXCEPT role [,...] ]
[SETTINGS variable [= value] [MIN [=] min_value] [MAX [=] max_value] [READONLY|WRITABLE] | PROFILE 'profile_name'] [,...]
1.1.8. 修改角色
语法
ALTER ROLE [IF EXISTS] name [ON CLUSTER cluster_name]
[RENAME TO new_name]
[SETTINGS variable [= value] [MIN [=] min_value] [MAX [=] max_value] [READONLY|WRITABLE] | PROFILE 'profile_name'] [,...]
1.1.9. 修改行策略
语法
ALTER [ROW] POLICY [IF EXISTS] name [ON CLUSTER cluster_name] ON [database.]table
[RENAME TO new_name]
[AS PERMISSIVE | RESTRICTIVE]
[FOR SELECT]
[USING condition | NONE][,...]
[TO role [,...] | ALL | ALL EXCEPT role [,...]]
1.1.10. 修改配额
语法
ALTER QUOTA [IF EXISTS] name [ON CLUSTER cluster_name]
[RENAME TO new_name]
[KEYED BY 'none' | 'user name' | 'ip address' | 'client key' | 'client key or user name' | 'client key or ip address']
[FOR [RANDOMIZED] INTERVAL number SECOND | MINUTE | HOUR | DAY | WEEK | MONTH | QUARTER | YEAR
MAX QUERIES | ERRORS | RESULT ROWS | RESULT BYTES | READ ROWS | READ BYTES | EXECUTION TIME = number [,...] |
NO LIMITS | TRACKING ONLY [,...]]
[TO role [,...] | ALL | ALL EXCEPT role [,...]]
1.1.11. 修改settings profile
语法
ALTER SETTINGS PROFILE [IF EXISTS] name [ON CLUSTER cluster_name]
[RENAME TO new_name]
[SETTINGS variable [= value] [MIN [=] min_value] [MAX [=] max_value] [READONLY|WRITABLE] | INHERIT 'profile_name'] [,...]
1.1.12. 撤销授权
使用REVOKE 指令撤销用户或角色的权限。
撤销用户权限
REVOKE [ON CLUSTER cluster_name] privilege[(column_name [,...])] [,...] ON db.table|db.*|*.*|table|* FROM user | CURRENT_USER [,...] | ALL | ALL EXCEPT user | CURRENT_USER [,...]
撤销用户的角色
REVOKE [ON CLUSTER cluster_name] [ADMIN OPTION FOR] role [,...] FROM user | role | CURRENT_USER [,...] | ALL | ALL EXCEPT user_name | role_name | CURRENT_USER [,...]
局部撤销权限
如果用户有 SELECT (x,y) 权限,管理员可以执行 REVOKE SELECT(x,y) 撤销此SELECT权限。执行REVOKE ALL PRIVILEGES撤销所有权限。
组合使用授权、撤销权限
授予用户john除了accounts数据库之外的,所有数据库中查询权限:
GRANT SELECT ON *.* TO john;
REVOKE SELECT ON accounts.* FROM john;
授予用户mira,对accounts.staff表中除了salary 列之外,其他所有列查询权限:
GRANT SELECT ON accounts.staff TO mira;
REVOKE SELECT(wage) ON accounts.staff FROM mira;
以上是关于ClickHouse 创建用户/角色/行权限策略/配额 Quota 限流等的主要内容,如果未能解决你的问题,请参考以下文章