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 限流等的主要内容,如果未能解决你的问题,请参考以下文章

如何在AWS中定义仅允许使用预定义模板创建堆栈的策略/角色/权限

初探ClickHouse的RBAC权限功能

限制 ClickHouse 中的用户访问权限

角色分配策略中无法识别 aws 自定义属性

ClickHouse 仅授予用户对数据库中几个表的访问权限

S3 存储桶策略授予/限制对特定联合用户的访问权限