clickhouse user.xml

config.xml文件可以使用用户设置,配置文件和配额指定单独的配置。 此配置的相对路径在users_config元素中设置。 默认情况下,它是users.xml。 如果省略users_config,则直接在config.xml中指定用户设置,配置文件和配额。

可以将用户配置分为与config.xml和config.d /类似的单独文件。
目录名称定义为users.config设置,不带.xml后缀与.d串联。
默认情况下使用目录users.d,因为users_config默认为users.xml。

注意一点,修改了user.xml的参数之后是即时生效的,如有问题可以查看其错误日志。

users.xml有三大块进行说明,分别为:profiles,quotas,users

profile

profile的作用类似于用户角色,可以在user.xml中定义多组profile,并可以为每组profile定义不同的配置项,类限制资源的使用。多个profile的配置可以复用。

模板:

<profiles> --配置profile
        <default>  -- 自定义profile
            <max_memory_usage>10000000000</max_memory_usage>
            <use_uncompressed_cache>0</use_uncompressed_cache>
            <load_balancing>random</load_balancing>
        </default>
        <readonly>  -- 自定义profile
            <readonly>1</readonly>
       <max_memory_usage>100000000</max_memory_usage>
        </readonly>
    </profiles>

说明:

<default>:自定义profile,可以在它下面设置相关参数,如:最大内存使用、只读等等。更多的配置参数后续会介绍,也而已看官网文档,可以设置多个profile。
该示例指定了两个profile:default和readonly。 默认<default>有一个特殊用途:必须始终存在并且在启动服务器时应用。profile文件可以相互继承,只需要在配置文件中列出即可,如定义一个test的profile:

        <test>
            <profile>readonly</profile>
            <max_memory_usage>10000</max_memory_usage>
        </test> 

test的profile继承了readonly的profile,包含了其所有的配置,并且使用新参数来覆盖其原有的配置。设置了之后如何使用呢?有二种方法,第1是直接在终端命令行里进行设置,第2个是在users.xml中的users选项组里进行指定(后面会说明)。

[root@dba clickhouse-server]# clickhouse-client
ClickHouse client version 20.3.5.21 (official build).
Connecting to localhost:9000 as user default.
Connected to ClickHouse server version 20.3.5 revision 54433.

dba :) set profile = 'test'

SET profile = 'test'

Ok.
rows in set. Elapsed: 0.002 sec. 

dba :) set max_memory_usage = 123123

SET max_memory_usage = 123123

Received exception from server (version 20.3.5):
Code: 164. DB::Exception: Received from localhost:9000. DB::Exception: Cannot modify 'max_memory_usage' setting in readonly mode. 
rows in set. Elapsed: 0.005 sec. 

dba :) Bye.

测试说明已经把readonly的profile的参数(readonly)继承过来了。 

profile中的设定项-查询权限设置

ClickHouse中的查询可以分为几种类型:

  • 读取数据查询:SELECT,SHOW,DESCRIBE,EXISTS。
  • 写入数据查询:INSERT,OPTIMIZE。
  • 更改设置查询:SET,USE。
  • DDL查询:CREATE,ALTER,RENAME,ATTACH,DETACH,DROP TRUNCATE。
  • KILL QUERY。
  • 其中KILL QUERY查询可以在任何设置下生效。

<readonly>

只读限制,设置读取数据,写入数据和更改设置查询的权限(并不设置ddl查询权限)。

可能的值:

  • 0-允许所有查询。
  • 1-仅允许读取数据查询。
  • 2-允许读取数据和更改设置查询。
      读取数据 写入数据 更改设置
    0 YES YES YES
    1 YES NO NO
    2 YES NO YES

    默认值:0

    <allow_ddl>

DDL限制,设置是否可以进行DDL操作

可能的值:

  • 0-不允许DDL查询。
  • 1-允许DDL查询。

默认值:1

profile中的设定项-查询复杂度的设置

对查询复杂度的限制是设置的一部分。它们用于从用户界面提供更安全的执行。
几乎所有限制仅适用于SELECT。对于分布式查询处理,限制分别应用于每个服务器(就是说对于最大内存这种设置来说是对每台服务器单独算的,不是对集群整体设置最大内存)。

ClickHouse会检查对于整体数据部分的限制条件,而不是对每一行进行限制。这意味着您可以超出数据部分大小的限制值。(It means that you can exceed the value of restriction with the size of the data part.)

对“什么东西的最大数量”的限制可以取值为0,表示“不受限制”。

大多数限制还具有“ overflow_mode”设置,表示超出限制时该怎么做,通常有以下两个值:

  • throw –抛出异常(默认)。
  • break –停止执行查询并返回部分结果。

对于聚合限制(group_by_overflow_mode),还有另一个值any,表示继续聚合进入集合的key值,但不要向集合中添加新key值。

<max_memory_usage>

用于在单个服务器上运行查询的最大RAM量,在默认配置文件中,最大为10 GB(10000000000byte,大约9.3个g)。

该设置不考虑可用内存量或计算机上的总内存量,适用於单个服务器内的单个查询。

可以使用 SHOW PROCESSLIST 来查看每个查询的当前内存消耗。此外,每个查询的峰值内存消耗也会被跟踪并写入日志。但是不监视某些聚合功能状态的内存使用情况。

Memory usage is not fully tracked for states of the aggregate functions min, max, any, anyLast, argMin, argMax from String and Array arguments.

内存消耗也受参数max_memory_usage_for_user和max_server_memory_usage限制。

<max_memory_usage_for_user>

用于在单个服务器上运行用户查询的最大RAM量。

默认值在Settings.h中定义。默认情况下max_memory_usage_for_user = 0,不受限制。

<max_rows_to_read>

在每个块(而不是每一行)上检查以下限制。也就是说,限制可以打破一点。

运行查询时可以从表中读取的最大行数。

<max_rows_to_read_leaf>

在每个块(而不是每一行)上检查以下限制。也就是说,限制可以打破一点。

运行分布式查询时,可以从叶子节点上的本地表读取的最大行数。仅在叶节点上的读取阶段检查此限制,而在根节点上的结果合并阶段将忽略此限制。

例如,集群由2个分片组成,每个分片包含一个包含100行的表,现在查询想要返回所有数据。

假设设置max_rows_to_read=150,那么查询失败,因为总共有200行数据。
假设设置max_rows_to_read_leaf=150,那么查询成功,因为每个节点只有100行。

<max_bytes_to_read>

运行查询时可以从表中读取的最大字节数(未压缩数据)。

<max_bytes_to_read_leaf>

运行分布式查询时,可以从叶节点上的本地表读取的最大字节数(未压缩的数据)。仅在叶节点上的读取阶段检查此限制,而在根节点上的结果合并阶段将忽略此限制。

例如,集群由2个分片组成,每个分片包含一个包含100字节的表,现在查询想要返回所有数据。

假设设置max_bytes_to_read=150,那么查询失败,因为总共有200字节数据。
假设设置max_bytes_to_read_leaf=150,那么查询成功,因为每个节点只有100字节。

<read_overflow_mode>

读取的数据量超过其中一个限制时该怎么办: ‘throw’ 或 ‘break’. 默认情况下是throw,抛出异常

<read_overflow_mode_leaf>

读取的数据量超过叶节点其中一个限制时该怎么办: ‘throw’ 或 ‘break’. 默认情况下是throw,抛出异常

<max_rows_to_group_by>

从聚合接收的唯一密钥的最大数量。 此设置允许您在聚合时限制内存消耗。

<group_by_overflow_mode>

当聚合的唯一键数超过限制时该怎么办:‘throw’ 或 ‘break’或‘any’,默认情况下是throw,抛出异常

使用“ any”值,您可以近似计算GROUP BY。这种近似的质量取决于数据的统计性质。

<max_bytes_before_external_group_by>

启用或禁用GROUP BY外部存储器中子句的执行。请参阅外部存储器中的GROUP BY。

可能的值:

  • 单个GROUP BY操作可以使用的最大RAM量(以字节为单位)。
  • 0-GROUP BY禁用外部存储器。

默认值:0。

<max_rows_to_sort>

排序前允许的最大行数。这样可以限制排序时的内存消耗。

<max_bytes_to_sort>

排序前允许的最大字节数。

<sort_overflow_mode>

如果排序前收到的行数超过限制之一该怎么办: ‘throw’ 或 ‘break’. 默认情况下是throw,抛出异常

<max_result_rows>

限制结果中的行数。运行部分分布式查询时,还检查在远程服务器上的子查询。

<max_result_bytes>

限制结果中的字节数。运行部分分布式查询时,还检查在远程服务器上的子查询。

<result_overflow_mode>

如果返回结果量超过限制该怎么办: ‘throw’ 或 ‘break’. 默认情况下是throw,抛出异常

使用“ break”类似于使用LIMIT。Break仅在块级别中断执行。这意味着返回的行数会大于max_result_rows、max_block_size(不在本章,在config.xml)的倍数,并取决于max_threads(不在本章,在config.xml)

举例和结果:

SET max_threads = 3, max_block_size = 3333;
SET max_result_rows = 3334, result_overflow_mode = 'break';
 
SELECT *
FROM numbers_mt(100000)
FORMAT Null;
 
 
6666 rows in set. ...


<max_execution_time>

最大查询执行时间,以秒为单位。

目前,不检查排序阶段、合并和最终确定集合函数。

<timeout_overflow_mode>

如果查询运行时间超过'max_execution_time':‘throw’ 或 ‘break’. 默认情况下是throw,抛出异常

<min_execution_speed>

最小执行速度(每秒行数)。当'timeout_before_checking_execution_speed'到期时,检查每个数据块。如果执行速度较低,则会引发异常。

<min_execution_speed_bytes>

每秒最小执行字节数。当'timeout_before_checking_execution_speed'到期时,检查每个数据块。如果执行速度较低,则会引发异常。

<max_execution_speed>

每秒最大执行行数。当'timeout_before_checking_execution_speed'到期时,检查每个数据块。如果执行速度很高,执行速度将降低。

<max_execution_speed_bytes>

每秒最大执行字节数。当'timeout_before_checking_execution_speed'到期时,检查每个数据块。如果执行速度很高,执行速度将降低。

<timeout_before_checking_execution_speed>

在以秒为单位的指定时间到期后,检查执行速度

<max_columns_to_read>

单个查询中可以从表中读取的最大列数。如果查询需要读取更多的列,则会引发异常。

<max_temporary_columns>

运行查询时必须同时在RAM中保留的临时列的最大数量,包括常量列。如果临时列多于此,则会引发异常。

<max_temporary_non_const_columns>

与“ max_temporary_columns”相同,但不计算常量列。请注意,运行查询时经常会形成常数列,但它们需要大约零计算资源。

<max_subquery_depth>

子查询的最大嵌套深度。如果子查询更深,则会引发异常。默认情况下为100。

<max_pipeline_depth>

最大管道深度。对应于每个数据块在查询处理期间经历的转换次数。计入单个服务器的限制内。如果管道深度更大,则会引发异常。默认情况下为1000。

<max_ast_depth>

查询语法树的最大嵌套深度。如果超过,则会引发异常。

目前,在解析期间不会对其进行检查,而只会在解析查询之后进行检查。也就是说,在解析过程中可能会创建过深的语法树。默认情况下为1000。

<max_ast_elements>

查询语法树中的最大元素数。如果超过,则会引发异常。
与以前的设置相同,仅在解析查询后才对其进行检查。默认情况下为50,000。

<max_rows_in_set>

从子查询创建的IN子句中的数据集的最大行数。

<max_bytes_in_set>

从子查询创建的IN子句中的集合使用的最大字节数(未压缩的数据)。

<set_overflow_mode>

IN子句中的集合数据量超过以下限制之一时该怎么办:‘throw’ 或 ‘break’. 默认情况下是throw,抛出异常

<max_rows_in_distinct>

使用DISTINCT时的最大不同行数。

<max_bytes_in_distinct>

使用DISTINCT时,哈希表使用的最大字节数。

<distinct_overflow_mode>

使用DISTINCT时的数据量超过限制之一时该怎么办:‘throw’ 或 ‘break’. 默认情况下是throw,抛出异常

<max_rows_to_transfer>

使用GLOBAL IN时可以传递到远程服务器或保存在临时表中的最大行数。

<max_bytes_to_transfer>

使用GLOBAL IN时,可以传递到远程服务器或保存在临时表中的最大字节数(未压缩的数据)。

<transfer_overflow_mode>

当数据量超过以下限制之一时该怎么办:‘throw’ 或 ‘break’. 默认情况下是throw,抛出异常

<max_rows_in_join>

限制联接表时使用的哈希表中的行数。

此设置适用于SELECT…JOIN操作和Join表引擎。

如果查询包含多个联接,ClickHouse将为每个中间结果检查此设置。

可能的值:

  • 正整数。
  • 0-无限行。

默认值:0。

<max_bytes_in_join>

限制联接表时使用的哈希表的大小(以字节为单位)。

此设置适用于SELECT…JOIN操作和Join表引擎。

如果查询包含联接,ClickHouse将为每个中间结果检查此设置。

可能的值:

  • 正整数。
  • 0-禁用内存控制。

默认值:0。

<join_overflow_mode>

当每个中间结果超过以下限制之一时该怎么办:‘throw’ 或 ‘break’. 默认情况下是throw,抛出异常

<max_partitions_per_insert_block>

限制单个插入块中的最大分区数。

  • 正整数。
  • 0-无限数量的分区。

默认值:100。

插入数据时,ClickHouse计算插入的块中的分区数。如果分区数大于max_partitions_per_insert_block,则ClickHouse会引发带有以下文本的异常:

“Too many partitions for single INSERT block (more than” + toString(max_parts) + “). The limit is controlled by ‘max_partitions_per_insert_block’ setting. A large number of partitions is a common misconception. It will lead to severe negative performance impact, including slow server startup, slow INSERT queries and slow SELECT queries. Recommended total number of partitions for a table is under 1000..10000. Please note, that partitioning is not intended to speed up SELECT queries (ORDER BY key is sufficient to make range queries fast). Partitions are intended for data manipulation (DROP PARTITION, etc).”
profile中的设定项——设置约束(Constraints on Settings)

profile中的设定项-constraints

在user.xml配置文件的profile选项组下constraints选项组里定义对设置的约束,并禁止用户使用SET查询更改某些设置。constraints标签可以设置一组约束条件,以限制profile内的参数值被随意修改,约束条件有如下三种规则:

  • min:最小值约束,在设置相应参数的时候,取值不能小于该阈值;
  • max:最大值约束,在设置相应参数的时候,取值不能大于该阈值;
  • readonly:只读约束,该参数值不允许被修改。

需要在profile选项组里设置constraints,模板:

<profiles>
  <user_name>
    <constraints>
      <setting_name_1>
        <min>lower_boundary</min>
      </setting_name_1>
      <setting_name_2>
        <max>upper_boundary</max>
      </setting_name_2>
      <setting_name_3>
        <min>lower_boundary</min>
        <max>upper_boundary</max>
      </setting_name_3>
      <setting_name_4>
        <readonly/>
      </setting_name_4>
    </constraints>
  </user_name>
</profiles>

说明:如果违反约束,则会引发异常,并且设置实际上不会更改。支持三种约束类型:最小,最大,只读。

最小和最大约束为数字设置指定上限和下限,并且可以组合使用。

只读约束指定用户完全不能更改相应的设置。如:

<profiles>
  <default>
    <max_memory_usage>10000000000</max_memory_usage>
    <force_index_by_date>0</force_index_by_date>
    ...
    <constraints>
      <max_memory_usage>
        <min>5000000000</min>
        <max>20000000000</max>
      </max_memory_usage>
      <force_index_by_date>
        <readonly/>
      </force_index_by_date>
    </constraints>
  </default>
</profiles>

以下查询均引发异常:

SET max_memory_usage=20000000001;
SET max_memory_usage=4999999999;
SET force_index_by_date=1;

Code: 452, e.displayText() = DB::Exception: Setting max_memory_usage should not be greater than 20000000000.
Code: 452, e.displayText() = DB::Exception: Setting max_memory_usage should not be less than 5000000000.
Code: 452, e.displayText() = DB::Exception: Setting force_index_by_date should not be changed.

说明:在default默认profile中定义的constraints约束,将作为默认的全局约束,自动被其他profile继承。例子中约束了参数max_memory_usage的最大最小值和参数force_index_by_date的只读属性,不能修改。如果违反约束则会报错。

quotas

配额,限制使用资源,限制有二种类型:一是在固定周期里的执行次数(quotas),二是限制用户或则查询的使用资源(profiles)

在user.xml配置文件的选项组quotas里设置,限制该用户一段时间内的资源使用,即对一段时间内运行的一组查询施加限制,而不是限制单个查询。

还具有限制单个查询的复杂性(上面提到的“profile中的设定项——对查询复杂度的设置”)的功能。

与查询复杂度限制相反,配额:

  • 对可以在一段时间内运行的一组查询施加限制,而不是限制单个查询。
  • 计入在所有远程服务器上用于分布式查询处理的资源。

模板:
 

<!-- Quotas. -->
    <quotas>
        <!-- Name of quota. -->
        <default> --指定quotas名
            <!-- Limits for time interval. You could specify many intervals with different limits. -->
            <interval> --时间间隔
                <!-- Length of interval. -->
                <duration>3600</duration> --周期
                <!-- No limits. Just calculate resource usage for time 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>

说明:

  • <default>:配额规则名。
  • <interval>:配置时间间隔,每个时间内的资源消耗限制。
  • <duration>:时间周期,单位秒。
  • <queries>:时间周期内允许的请求总数,0表示不限制。
  • <errors>:时间周期内允许的异常总数,0表示不限制。
  • <result_rows>:时间周期内允许返回的行数,0表示不限制。
  • <read_rows>:时间周期内允许在分布式查询中,远端节点读取的数据行数,0表示不限制。
  • <execution_time>:时间周期内允许执行的查询时间,单位是秒,0表示不限制。

默认情况下,配额跟踪每小时的资源消耗,而不限制使用量。
在每个请求之后,针对每个时间间隔计算的资源消耗将输出到服务器日志。

下面是非默认情况的另一组配额:

//以下内容是在<quotas>中定义的
<statbox>
    <!-- Restrictions for a time period. You can set many intervals with different restrictions. -->
    <interval>
        <!-- Length of the interval. -->
        <duration>3600</duration>
 
        <queries>1000</queries>
        <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>
        <errors>1000</errors>
        <result_rows>5000000000</result_rows>
        <read_rows>500000000000</read_rows>
        <execution_time>7200</execution_time>
    </interval>
</statbox>

如果在至少一个时间间隔内超过了限制,则将引发一个异常,并显示一条文本:是对于哪一个间隔的,何时新间隔可以开始(何时可以再次发送查询)。

Code: 201. DB::Exception: Received from localhost:9000. DB::Exception: Quota for user `default` for 10s has been exceeded: queries = 4/3. Interval will end at 2020-04-02 11:29:40. Name of quota template: `default`.

从实施定义的固定时刻开始计算时间间隔。间隔结束时,将清除所有收集的值。 接下来的一个小时,配额计算将重新开始。对于分布式查询处理,累积量存储在请求者服务器上。 因此,如果用户转到另一台服务器,则那里的配额将重新开始。重新启动服务器后,配额将重置。

如果不是根据时间周期而是根据查询的资源消耗来进行限制,则在user.xml里的profile里进行设置,如上面提到的max_memory_usage、max_rows_to_group_by之类。

此外,配额可以使用“配额键(quota key)”功能独立报告多个键的资源。举例:
 

<!-- For the global reports designer. -->
<web_global>
    <!-- keyed – The quota_key "key" is passed in the query parameter,
            and the quota is tracked separately for each key value.
        For example, you can pass a Yandex.Metrica username as the key,
            so the quota will be counted separately for each username.
        Using keys makes sense only if quota_key is transmitted by the program, not by a user.
        You can also write <keyed_by_ip />, so the IP address is used as the quota key.
        (But keep in mind that users can change the IPv6 address fairly easily.)
    -->
    <keyed />

users

user.xml配置文件的users选项组是配置自定义用户,定义一个新用户,必须包含以下几项属性:用户名、密码、访问ip、数据库、表等等。它还可以应用上面的profile、quota。

<users>
    <!-- If user name was not specified, 'default' user is used. -->
    <user_name>
        <password></password>
        <!-- Or -->
        <password_sha256_hex></password_sha256_hex>
 
        <access_management>0|1</access_management>
 
        <networks incl="networks" replace="replace">
        </networks>
 
        <profile>profile_name</profile>
 
        <quota>default</quota>
 
        <databases>
            <database_name>
                <table_name>
                    <filter>expression</filter>
                <table_name>
            </database_name>
        </databases>
    </user_name>
    <!-- Other users settings -->
</users>
  • <user_name>:自定义用户
  • <password>:用户密码,密码可以以纯文本、SHA256(十六进制格式)、password_double_sha1_hex(和MySQL兼容)指定,设置方法如下:
  1.     以纯文本形式分配密码(不建议使用),将其放在一个password元素中。例如,<password>qwerty</password>。密码可以留空。       
  2.  使用SHA256哈希值分配密码,将其放在一个password_sha256_hex元素中。例如,<password_sha256_hex>65e84be33532fb784c48129675f9eff3a682b27168c0ea744b2cf58ee02337c5</password_sha256_hex>。如何从shell生成密码的示例:    PASSWORD=$(base64 < /dev/urandom | head -c8); echo "$PASSWORD"; echo -n "$PASSWORD" | sha256sum | tr -d '-'。结果的第一行是密码。第二行是对应的SHA256哈希。
  3. 为了与MySQL客户端兼容,可以在双SHA1哈希中指定密码。将其放在password_double_sha1_hex元素中。例如,<password_double_sha1_hex>08b4a0f1de6ad37da17359e592c8d74788a83eb0</password_double_sha1_hex>。如何从shell生成密码的示例:  PASSWORD=$(base64 < /dev/urandom | head -c8); echo "$PASSWORD"; echo -n "$PASSWORD" | sha1sum | tr -d '-' | xxd -r -p | sha1sum | tr -d '-'。结果的第一行是密码。第二行是对应的双SHA1哈希。

 

  • <access_management>:此设置为用户启用或禁用SQL驱动的访问控制和帐户管理。

可能的值:0-禁用。1-启用。默认为0

  • <networks>:用户可以从中连接到ClickHouse服务器的网络列表。列表的每个元素可以具有以下形式之一:
  1. <ip> — IP地址或网络掩码。例如:213.180.204.3,10.0.0.1/8,10.0.0.1/255.255.255.0,2a02:6b8::3,2a02:6b8::3/64,2a02:6b8::3/ffff:ffff:ffff:ffff::。
  2. <host> - 主机名。范例:example01.host.ru。为了检查访问,将执行DNS查询,并将所有返回的IP地址与对等地址进行比较。
  3. <host_regexp> —主机名的正则表达式。范例:^example\d\d-\d\d-\d\.host\.ru$。为了检查访问,对同一个地址执行DNS PTR查询,然后应用指定的正则表达式。然后,对PTR查询的结果执行另一个DNS查询,并将所有接收到的地址与对等地址进行比较。我们强烈建议regexp以$结尾。
要为来自任何网络的用户打开访问权限,请指定:
<ip>::/0</ip>
 
 
要仅打开来自本地主机的访问,请指定:
<ip>::1</ip>
<ip>127.0.0.1</ip>
  • <profile>:指定用户的profile,上面有详细介绍。
  • <quota>:指定用户的quota,限制用户使用资源,上面有详细介绍。
  • <database_name>:指定用户访问的数据库

    可以限制ClickHouse返回的行以供SELECT当前用户进行的查询,从而实现基本的行级安全性。
    例如。以下配置强制用户user1只能看到table1作为SELECT查询结果的id字段,其中字段的值为1000。

<user1>
    <databases>
        <database_name>
            <table1>
                <filter>id = 1000</filter>
            </table1>
        </database_name>
    </databases>
</user1>
  • <table_name>:指定用户访问的表
  • <filter>:指定用户访问的过滤器,该 filter 可以是导致任何表达式 UInt8-键入值。 它通常包含比较和逻辑运算符。 

    如:id = 1 ,即查询表只返回id=1的行
    如:id >= 500,即查询表只返回id>=500的行

自定义设置

除了通用设置,用户还可以定义自定义设置。

定义设置名称必须以预定义前缀之一开头。这些前缀的列表必须在服务器配置文件的custom_settings_prefixes参数中声明。 

<custom_settings_prefixes>custom_</custom_settings_prefixes>


要定义自定义设置,请使用SET命令:

SET custom_a = 123;


要获取自定义设置的当前值,请使用getSetting()函数:

SELECT getSetting('custom_a');    


 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章