ivory31.png

前情提要

上篇文章 中,我们介绍了 IvorySQL 3.1 和 2.3 系统参数有哪些删减和默认值变更,本文将介绍 23 个新增参数。

新增参数

新增参数一览如下,共 23 个。

  • 4 个安全相关
    1. createrole_self_grant
    2. gss_accept_delegation
    3. reserved_connections
    4. scram_iterations
  • 5 个开发选项
    1. debug_io_direct
    2. debug_logical_replication_streaming
    3. debug_parallel_query
    4. send_abort_for_crash
    5. send_abort_for_kill
  • 1 个优化器相关
    1. enable_presorted_aggregate
  • 1 个语言相关
    1. icu_validation_level
  • 1 个复制相关
    1. max_parallel_apply_workers_per_subscription
  • 1 个资源相关
    1. vacuum_buffer_usage_limit
  • 10 个兼容性相关
    1. nls_date_format
    2. nls_timestamp_format
    3. nls_timestamp_tz_format
    4. ivorysql.compatible_mode
    5. ivorysql.database_mode
    6. ivorysql.datetime_ignore_nls_mask
    7. ivorysql.enable_emptystring_to_NULL
    8. ivorysql.identifier_case_switch
    9. ivorysql.listen_addresses
    10. ivorysql.port

接下来我们逐一介绍。

1. createrole_self_grant

​ 如果具有 CREATEROLE 但没有 SUPERUSER 的用户创建角色,并且将其设置为非空值,则新创建的角色将被授予具有指定选项的创建用户。该值必须是设置的、继承的或以逗号分隔的列表。默认值为空字符串,这会禁用该功能。

此选项的目的是允许非超级用户的 CREATEROLE 用户自动继承或自动获得对任何创建的用户设置 ROLE 的能力。由于 CREATEROLE 用户始终在创建的角色上隐式授予 ADMIN OPTION,因此该用户始终可以执行 GRANT 语句来实现与此设置相同的效果。但是,如果自动授予,出于可用性原因,可能会很方便。超级用户自动继承每个角色的权限,并且始终可以为任何角色设置 ROLE,并且此设置可用于为 CREATEROLE 用户创建的用户产生类似的行为。

用法示例如下:

[ivorysql@shawnyan ~]$ psql
psql (16.1-ShawnYan)
Type "help" for help.

ivorysql=# show createrole_self_grant;
 createrole_self_grant
-----------------------

(1 row)

ivorysql=# CREATE USER shawnyan_user_1 CREATEROLE NOINHERIT;
CREATE ROLE
ivorysql=# \c - shawnyan_user_1
You are now connected to database "postgres" as user "shawnyan_user_1".
ivorysql=> CREATE USER shawnyan_tenant_1;
CREATE ROLE
ivorysql=> SET createrole_self_grant = 'set, inherit';
SET
ivorysql=> SET ROLE shawnyan_user_1;
SET
ivorysql=> SELECT roleid::regrole, member::regrole, grantor::regrole, * FROM pg_auth_members;
        roleid        |     member      | grantor  |  oid  | roleid | member | grantor | admin_option | inherit_option | set_option
----------------------+-----------------+----------+-------+--------+--------+---------+--------------+----------------+------------
...
 shawnyan_tenant_1    | shawnyan_user_1 | ivorysql | 16398 |  16397 |  16396 |      10 | t            | f              | f
(4 rows)

ivorysql=> \c - shawnyan_user_1
You are now connected to database "ivorysql" as user "shawnyan_user_1".
ivorysql=> SET createrole_self_grant = 'set, inherit';
SET
ivorysql=> CREATE USER shawnyan_tenant_2;
CREATE ROLE
ivorysql=> SELECT roleid::regrole, member::regrole, grantor::regrole, * FROM pg_auth_members;
        roleid        |     member      |     grantor     |  oid  | roleid | member | grantor | admin_option | inherit_option | set_option
----------------------+-----------------+-----------------+-------+--------+--------+---------+--------------+----------------+------------
...
 shawnyan_tenant_1    | shawnyan_user_1 | ivorysql        | 16398 |  16397 |  16396 |      10 | t            | f              | f
 shawnyan_tenant_2    | shawnyan_user_1 | ivorysql        | 16400 |  16399 |  16396 |      10 | t            | f              | f
 shawnyan_tenant_2    | shawnyan_user_1 | shawnyan_user_1 | 16401 |  16399 |  16396 |   16396 | f            | t              | t
(6 rows)

ivorysql=> show createrole_self_grant;
 createrole_self_grant
-----------------------
 set, inherit
(1 row)

2. gss_accept_delegation

添加对 Kerberos 凭证委托的支持。

这可以通过服务器变量 gss_accept_delegation 和 libpq 连接参数 gssdelegation 来启用。

默认值为 off,这意味着不接受来自客户端的凭据。

3. reserved_connections

确定具有 pg_use_reserved_connections 角色权限的角色为连接保留的连接“插槽”的数量。当空闲连接槽的数量大于 superuser_reserved_connections,但小于或等于 superuser_reserved_connectionsreserved_connections 的总和时,新的连接将只被超级用户和具有 pg_use_reserved_connections 权限的角色接受。如果 superuser_reserved_connections 或更少的连接槽可用,则只接受超级用户的新连接。

缺省值为零连接。该值必须小于 max_connections 减去 superuser_reserved_connections。该参数只能在服务器启动时设置。

关联参数: superuser_reserved_connections 关联角色: pg_use_reserved_connections

4. scram_iterations

允许使用服务器变量 scram_iterations 设置 SCRAM 迭代计数。 使用 SCRAM-SHA-256 加密密码时要执行的计算迭代次数。

5. debug_io_direct

从 IvorySQL 3 开始,新增 3 个用于开发调试的参数,debug_io_directdebug_logical_replication_streamingdebug_parallel_query

可以设置为空字符串(默认值)以禁用直接 I/O,或者应该使用直接 I/O 的逗号分隔的操作列表。

目前,该特性降低了性能,并且仅用于开发人员测试。

6. debug_logical_replication_streaming

在逻辑复制中,添加服务器变量以控制逻辑解码发布者如何传输更改以及订阅者如何应用更改。

默认值为 buffered,还可选 immediate

7. debug_parallel_query

上篇文章提及过,该参数由 force_parallel_mode 更名而来。

debug_parallel_query 允许的值是 off(仅在期望提高性能时使用并行模式)、on(对所有被认为是安全的查询强制并行查询)和regress(类似于 on,但会有例外行为)。

8. send_abort_for_crash

允许 postmaster 用中止信号终止子进程。

这允许为卡住的子进程收集核心转储 (core dump)。这是由 send_abort_for_crashsend_abort_for_kill 控制的。postmaster 的 -T 开关现在与设置 send_abort_for_crash 相同。

[ivorysql@shawnyan bin]$ postgres --help | grep '\-T'
  -T                 send SIGABRT to all backend processes if one dies

9. send_abort_for_kill

同上。

区别在于 send_abort_for_crash 发送的是 SIGABRT,而 send_abort_for_kill 发送的是 SIGKILL。

10. enable_presorted_aggregate

优化器中为具有 ORDER BYDISTINCT 的聚合添加使用预排序数据的能力,默认开启,通过该参数可将其关闭。

示例:

ivorysql=# create table t(id int);
CREATE TABLE

ivorysql=# explain select sum(id order by id) from t;
                           QUERY PLAN
-----------------------------------------------------------------
 Aggregate  (cost=192.53..192.54 rows=1 width=8)
   ->  Sort  (cost=179.78..186.16 rows=2550 width=4)
         Sort Key: id
         ->  Seq Scan on t  (cost=0.00..35.50 rows=2550 width=4)
(4 rows)

ivorysql=# set enable_presorted_aggregate to off;
SET
ivorysql=# explain select sum(id order by id) from t;
                        QUERY PLAN
-----------------------------------------------------------
 Aggregate  (cost=41.88..41.88 rows=1 width=8)
   ->  Seq Scan on t  (cost=0.00..35.50 rows=2550 width=4)
(2 rows)

11. icu_validation_level

当遇到 ICU 语言环境验证问题时,控制使用哪个消息级别来报告问题。

如果设置为 DISABLED 则不报告验证问题。默认值是 WARNING

示例:

ivorysql=# CREATE COLLATION nonsense (provider = icu, locale = 'nonsense');
WARNING:  ICU locale "nonsense" has unknown language "nonsense"
HINT:  To disable ICU locale validation, set the parameter "icu_validation_level" to "disabled".
CREATE COLLATION
ivorysql=# set icu_validation_level to disabled;
SET
ivorysql=# CREATE COLLATION nonsense1 (provider = icu, locale = 'nonsense');
CREATE COLLATION

12. max_parallel_apply_workers_per_subscription

每次订阅的最大并行应用程序工作者数。该参数通过订阅参数 streaming = parallel 控制正在进行的事务流的并行度。

并行应用程序是从 max_logical_replication_workers 定义的池中获取的。

默认值为 2。此参数只能在 postgresql.conf 文件或服务器命令行中设置。

ivorysql=# alter system set max_parallel_apply_workers_per_subscription = 5;
ALTER SYSTEM
...
ivorysql=# show max_parallel_apply_workers_per_subscription;
 max_parallel_apply_workers_per_subscription
---------------------------------------------
 5
(1 row)

<!-- select * from pg_subscription; create subscription s1 connection 'dbname=postgres' publication p1 with (streaming = parallel); -->

13. vacuum_buffer_usage_limit

允许通过 vacuum 和 analyze 来控制共享缓冲区的使用。

VACUUM/ANALYZE 选项是 BUFFER_USAGE_LIMIT, vacuumdb 选项是 --buffer-usage-limit。默认值由服务器变量 vacuum_buffer_usage_limit 设置,该变量还控制 autovacuum。

VACUUM 使用类似于顺序扫描的环,但是,这个环的大小由 vacuum_buffer_usage_limit GUC 控制。脏页不会从环上移除。相反,如果需要,则刷新 WAL 以允许重用缓冲区。在 8.3 引入缓冲区环策略之前,VACUUM 的缓冲区被发送到自由列表,这实际上是一个 1 缓冲区的缓冲区环,导致过多的 WAL 刷新。

ivorysql=# ANALYZE (BUFFER_USAGE_LIMIT 128) t;
ANALYZE
ivorysql=# show vacuum_buffer_usage_limit;
 vacuum_buffer_usage_limit
---------------------------
 256kB
(1 row)

14. nls_date_format

接下来的 10 个参数是 IvorySQL 为兼容 Oracle 而增设参数,在 IvorySQL 官方文档中也有相关描述。

nls_date_format 表示默认的日期格式。

ivorysql=# show nls_date_format;
-[ RECORD 1 ]---+-----------
nls_date_format | YYYY-MM-DD

15. nls_timestamp_format

nls_timestamp_format 表示带时间的日期格式。

ivorysql=# show nls_timestamp_format;
-[ RECORD 1 ]--------+--------------------------
nls_timestamp_format | YYYY-MM-DD HH24:MI:SS.FF6

16. nls_timestamp_tz_format

nls_timestamp_tz_format 表示带时区的日期格式。

ivorysql=# show nls_timestamp_tz_format;
-[ RECORD 1 ]-----------+----------------------------------
nls_timestamp_tz_format | YYYY-MM-DD HH24:MI:SS.FF6 TZH:TZM

17. ivorysql.compatible_mode

表示当前兼容 pg 还是 oracle。

普通连接到默认端口 5432,显示为 pg 模式。

[ivorysql@shawnyan ~]$ psql -x
psql (16.1-ShawnYan)
Type "help" for help.

ivorysql=# show ivorysql.compatible_mode;
-[ RECORD 1 ]------------+---
ivorysql.compatible_mode | pg

连接到兼容 oracle 的端口 1521,显示为 oracle 模式。

[ivorysql@shawnyan bin]$ psql -p1521 -x
psql (16.1-ShawnYan)
Type "help" for help.

ivorysql=# show ivorysql.compatible_mode;
-[ RECORD 1 ]------------+-------
ivorysql.compatible_mode | oracle

18. ivorysql.database_mode

ivorysql.database_mode 表示当前数据库的模式(pg/oracle)。

19. ivorysql.datetime_ignore_nls_mask

表示日期格式是否会受 NLS 参数影响,默认为 0。

<!-- ivorysql=# show nls_date_format; -[ RECORD 1 ]---+----------- nls_date_format | YYYY-MM-DD

ivorysql=# select sys.current_date(); -[ RECORD 1 ]+----------- current_date | 2024-02-07

ivorysql=# show ivorysql.datetime_ignore_nls_mask; -[ RECORD 1 ]---------------------+-- ivorysql.datetime_ignore_nls_mask | 0

ivorysql=# set nls_date_format = 'YY/MM/DD'; SET ivorysql=# select sys.current_date(); -[ RECORD 1 ]+--------- current_date | 24/02/07

ivorysql=# set ivorysql.datetime_ignore_nls_mask = 1; SET ivorysql=# select sys.current_date(); -[ RECORD 1 ]+--------- current_date | 24/02/07

ivorysql=# ivorysql=# select sys.current_date(); -[ RECORD 1 ]+--------- current_date | 24/02/07 -->

20. ivorysql.enable_emptystring_to_NULL

取值为(on/off),该变量为 on 时,会将插入的空字符串转成 NULL 值存储。

示例:

ivorysql=# select name,setting from pg_settings where name like 'ivory%';
                name                 |   setting
-------------------------------------+-------------
 ivorysql.compatible_mode            | oracle
 ivorysql.database_mode              | oracle
 ivorysql.datetime_ignore_nls_mask   | 0
 ivorysql.enable_emptystring_to_NULL | on
 ivorysql.identifier_case_switch     | interchange
 ivorysql.listen_addresses           | localhost
 ivorysql.port                       | 1521
(7 rows)
...
ivorysql=# create table tnull (id int, sal varchar(20));
CREATE TABLE
ivorysql=# insert into tnull select 1,'';
INSERT 0 1
ivorysql=# select * from tnull where sal is null;
 id | sal
----+-----
  1 |
(1 row)

ivorysql=# set ivorysql.enable_emptystring_to_NULL = 0;
SET
ivorysql=# select * from tnull where sal is null;
 id | sal
----+-----
  1 |
(1 row)

ivorysql=# insert into tnull select 3,'';
INSERT 0 1
ivorysql=# select * from tnull where sal is null;
 id | sal
----+-----
  1 |
(1 row)

ivorysql=# select * from tnull where sal = '';
 id | sal
----+-----
  3 |
(1 row)

21. ivorysql.identifier_case_switch

用于设置字符大小写转换模式。

可设置为 NORMALLOWERCASEINTERCHANGE

22. ivorysql.listen_addresses

表示兼容模式监听的地址。

默认监听本地,可以设置为 *,允许所有地址访问。

ivorysql=# show ivorysql.listen_addresses;
-[ RECORD 1 ]-------------+--
ivorysql.listen_addresses | *

23. ivorysql.port

表示兼容模式下连接的端口号,这里默认为兼容 oracle 模式,端口号为 1521。

ivorysql=# show ivorysql.port;
-[ RECORD 1 ]-+-----
ivorysql.port | 1521

总结

IvorySQL 3 的新增参数提供了更多的配置和调优选项。通过了解这些参数,我们可以适当调整安全策略,更好的完成去 O 和国产化替代任务。在未来的工作中,建议持续关注 IvorySQL 的更新和优化,以便更好地利用这些新功能。

logo.jpg