Skip to main content
ClickHouse 中的查询可分为以下几类:
  1. 读取数据查询:SELECT, SHOW, DESCRIBE, EXISTS。
  2. 写入数据查询:INSERT, OPTIMIZE, DELETE, UPDATE, ALTER TABLE ... DELETE, ALTER TABLE ... UPDATE。
  3. 修改设置查询:SET, USE。
  4. DDL 查询:CREATE, ALTER, RENAME, EXCHANGE, ATTACH, DETACH, DROP, TRUNCATE。
  5. 访问管理查询:GRANT、REVOKE,以及针对用户、角色、行策略、脱敏策略、配额 和 profile 的 CREATE、ALTER 和 DROP。参见访问控制与账户管理。
  6. KILL QUERY。
ALTER TABLE ... DELETE 和 ALTER TABLE ... UPDATE 修改的是数据而非表元数据,因此上面将它们列为写入数据查询。它们需要 ALTER DELETE 和 ALTER UPDATE 特权,独立的 DELETE 和 UPDATE 语句同样需要这些特权。这些特权属于 ALTER TABLE 特权组,因此 allow_ddl = 0 会拒绝对持久化表执行上述全部四种语句。 以下设置按查询类型控制用户权限:

readonly

限制一个 session 可以运行哪些查询。该设置的取值、默认值,以及每个取值允许你更改哪些设置,详见 settings reference;本节说明每个取值允许哪些 类别的查询。 设置为 1 时,允许如下查询:
  • 读取查询 (如 SELECT 及与之等价的查询) 。
  • 仅修改 session 上下文的查询 (如 USE) 。
设置为 2 时,在上述基础上还允许 SET、CREATE TEMPORARY TABLE 和 RESTORE。由于 RESTORE 可以 创建表并向其中加载数据,因此 readonly = 2 本身并不能阻止 session 进行写入;而 readonly = 1 会拒绝该操作。 无论取何值,BACKUP 都不受 readonly 限制:只要 session 拥有备份某张表的 特权,即使在 readonly = 1 下也可以写入 backup。请勿依赖 readonly 来阻止备份。 大多数 table functions 需要 CREATE TEMPORARY TABLE 特权,因此读取此类表函数的 SELECT 在 readonly = 1 下会被拒绝,而在 readonly = 2 下不会。某些 table function,例如 numbers,在 read-only 模式下是允许的。 当取值大于 0 时,对 持久化表 不允许执行以下任何操作:写入数据查询 (INSERT、OPTIMIZE、DELETE、UPDATE、ALTER TABLE ... DELETE、ALTER TABLE ... UPDATE) 或 DDL 查询 (CREATE、ALTER TABLE、ALTER VIEW、RENAME、EXCHANGE、ATTACH、DETACH、DROP、 TRUNCATE TABLE) 。需要 SYSTEM 组 特权 的 SYSTEM 语句,以及对 users、角色、行策略、脱敏策略、 配额 和 profile 的 CREATE、ALTER 和 DROP 同样不被允许。named collection 管理是个例外: readonly 不限制 CREATE NAMED COLLECTION、ALTER NAMED COLLECTION 或 DROP NAMED COLLECTION。 使用 GRANT 授予 特权 同样会被拒绝,但并非所有 访问管理 语句都如此:本地的 REVOKE 和 GRANT CURRENT GRANTS 不受 readonly 限制,因此 read-only session 仍可以 revoke 其持有的、 带 grant option 的 特权,并将自身的 grants 传播给另一个 USER。 而以 ON CLUSTER 方式 revoke 特权 会被拒绝。 temporary tables 不受这两项设置的约束:能够创建 temporary table 的 session 也可以对其执行 ALTER、 insert 和 drop。
通过 HTTP interface 发起请求时,若请求 method 不是 POST, 且其有效值原本为 0,则该请求会以 readonly = 2 运行。若用户 settings 或 profile 已设置了更严格的值,则保留该值。 当 PUT 和 DELETE 到达接受它们的 SQL-defined handler 时不受此限制, 因此在有效 readonly 为 0 时这类请求可以修改数据;否则请使用 POST method 修改数据。对于以这种方式提升限制的请求,query string 中的 readonly 参数会被拒绝并报 Cannot modify 'readonly' setting in readonly mode,除非其指定的值与请求当前的值相同。可以只禁止 USER 修改特定 settings,也可以在 readonly = 1 的限制下只允许修改 特定 settings。详见 constraints on settings,其中也 建议不要将 readonly 设置本身 设为可在 read-only 模式下更改。

allow_ddl

允许或禁止对数据库、表、视图、字典、用户自定义函数、工作负载、资源以及 SQL 定义的 handler 执行 DDL 查询。 可能的值:
  • 0 — 对持久化对象执行需要以下任一特权的查询会被阻止:CREATE DATABASE、DROP DATABASE、CREATE TABLE、CREATE VIEW、ALTER TABLE、 ALTER VIEW、DROP TABLE、DROP VIEW、TRUNCATE、CREATE DICTIONARY、DROP DICTIONARY、 CREATE FUNCTION、DROP FUNCTION、CREATE WORKLOAD、DROP WORKLOAD、CREATE RESOURCE、 DROP RESOURCE、CREATE HANDLER、ALTER HANDLER、DROP HANDLER。RENAME、EXCHANGE、 ATTACH 和 DETACH 同样需要这些特权,因此也会被阻止;但 ALTER TABLE ... ATTACH PARTITION 和 ATTACH PART 只需要 INSERT,不受该设置阻止,不过 readonly 仍会在持久化表上阻止它们。 ATTACH PARTITION ... FROM 还需要 ALTER DELETE,因此会被阻止。授予和撤销这些特权则不受阻止。
  • 1 — 该设置不阻止任何操作。
默认值:1
如果当前 session 的 allow_ddl = 0,则无法执行 SET allow_ddl = 1。allow_ddl 不会限制访问管理类查询:GRANT、REVOKE 以及对用户、角色、行策略、脱敏策略、配额和 profile 的 CREATE、ALTER 和 DROP 均不受其影响。CREATE TEMPORARY TABLE 和 named collection 管理同样不受影响, ALTER DATABASE ... MODIFY SETTING、ALTER DATABASE ... MODIFY COMMENT 和 UNDROP TABLE 也是如此,readonly 同样不会限制这些操作。在对用户、角色或 profile 执行 CREATE 或 ALTER 时, 只要当前 session 的 allow_ddl = 0,其中的 SETTINGS allow_ddl = 1 子句就会被拒绝, 而 SETTINGS allow_ddl = 0 子句会被接受。内嵌的设置会依据 session 自身的 settings 约束进行检查,这也正是 SET allow_ddl = 1 被拒绝的原因。
KILL QUERY终止自己的查询不需要 KILL QUERY 特权,因此在 readonly 和 allow_ddl 的任意组合下都可以执行,但需要对 system.processes 拥有 SELECT 权限; KILL QUERY WHERE query_id = '<id>' 除外,它会直接取消您自己的、具有该 id 的查询,而无需读取该表。终止其他用户的查询,以及任何 KILL QUERY ... ON CLUSTER,都需要 KILL QUERY 特权,而 readonly = 1 和 readonly = 2 会拒绝该特权。

其他相关设置

  • allow_introspection_functions 是与 readonly 和 allow_ddl 一同参与权限判定的第三个设置。当它被禁用时,执行内部信息函数会被阻止,但授予 INTROSPECTION 权限不受影响。
  • allow_non_metadata_alters 并不是权限设置,但它对 ALTER TABLE 施加了进一步的限制:当它被禁用时,对于 MergeTree 家族的表,如果某条修改 表定义的命令在执行时会重写磁盘上的数据(DROP COLUMN、RENAME COLUMN、MODIFY COLUMN 类型变更、MODIFY TTL), 该命令将被拒绝。CLEAR COLUMN、CLEAR INDEX 和 CLEAR PROJECTION 虽然不会改变表定义,但同样会被拒绝。 本身即为变更操作的语句,例如 ALTER TABLE ... DELETE、ALTER TABLE ... UPDATE 和 ALTER TABLE ... MATERIALIZE INDEX,则不受影响。
最后修改于 2026年9月26日