- 读取数据查询:
SELECT,SHOW,DESCRIBE,EXISTS。 - 写入数据查询:
INSERT,OPTIMIZE,DELETE,UPDATE,ALTER TABLE ... DELETE,ALTER TABLE ... UPDATE。 - 修改设置查询:
SET,USE。 - DDL 查询:
CREATE,ALTER,RENAME,EXCHANGE,ATTACH,DETACH,DROP,TRUNCATE。 - 访问管理查询:
GRANT、REVOKE,以及针对用户、角色、行策略、脱敏策略、配额 和 profile 的CREATE、ALTER和DROP。参见访问控制与账户管理。 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) 。
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 — 该设置不阻止任何操作。
如果当前 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,则不受影响。