处理会话套接字阻止

针对给定查询等待客户端输入或输出时,会话套接字可能会被阻止。会话套接字通常因多种原因而被阻止 — 例如,当 Vertica 执行引擎将数据传输到客户端时,或 COPY LOCAL 操作等待从客户端加载数据时。

在极少数情况下,会话套接字可能会无限期地保持被阻止状态。例如,客户端上的查询超时,这会尝试强制取消查询或者依赖会话 RUNTIMECAP 设置来终止查询。在任何一种情况下,如果查询在等待消息或数据时结束,则套接字可能会保持阻止状态,会话将挂起,直到它被强制关闭。

配置宽限期

您可以为系统配置一个宽限期,在此期间滞后的客户端或服务器可以跟上并传递待定的响应。如果套接字保持被阻止状态的连续期间超过宽限期设置,服务器将关闭套接字并引发致命错误。随后,会话终止。如果没有设置宽限期,查询会使套接字无限期地保持被阻止状态。

您应该将会话宽限期设置为高到足以覆盖可接受的延迟范围并避免会话过早关闭 — 例如,为了对服务器进行响应而设置正常的客户端延迟。超大负载操作可能会要求您根据需要调整会话宽限期。

您可以将宽限期设置为四个级别,按优先级降序排列:

  1. 会话(最高)

  2. 用户

  3. 节点

  4. 数据库

为数据库和节点设置宽限期

在数据库和节点级别,可以通过 BlockedSocketGracePeriod 配置参数将宽限期设置为不超过 20 天的任意间隔

  • ALTER DATABASE db-name SET BlockedSocketGracePeriod = 'interval';
  • ALTER NODE node-name SET BlockedSocketGracePeriod = 'interval';

默认情况下,这两个级别的宽限期都设置为空字符串,允许无限期阻止。

为用户和会话设置宽限期

您可以为单个用户和给定会话设置宽限期,如下所示:

用户可以将会话设置为等于或小于为该用户设置的宽限期的任意间隔。超级用户可以将其他用户和他们自己的会话的宽限期设置为不超过 20 天(包含)的任意值。

示例

超级用户 dbadmin 将数据库宽限期设置为 6 小时。此限制仅适用于非超级用户。 dbadmin 可以将自己的会话宽限期设置为不超过 20 天的任意值 — 在本例中为 10 小时:

=> ALTER DATABASE VMart SET BlockedSocketGracePeriod = '6 hours';
ALTER DATABASE
=> SHOW CURRENT BlockedSocketGracePeriod;
  level   |           name           | setting
----------+--------------------------+---------
 DATABASE | BlockedSocketGracePeriod | 6 hours
(1 row)

=> SET SESSION GRACEPERIOD '10 hours';
SET
=> SHOW GRACEPERIOD;
    name     | setting
-------------+---------
 graceperiod | 10:00
(1 row)

dbadmin 创建未设置宽限期的用户 user777。因此,user777 的有效宽限期派生自数据库的 BlockedSocketGracePeriod 设置,即 6 小时。user777 将会话宽限期设置为大于 6 小时的任何尝试都会返回错误:


=> CREATE USER user777;
=> \c - user777
You are now connected as user "user777".
=> SHOW GRACEPERIOD;
    name     | setting
-------------+---------
 graceperiod | 06:00
(1 row)

=> SET SESSION GRACEPERIOD '7 hours';
ERROR 8175:  The new period 07:00 would exceed the database limit of 06:00

dbadminuser777 设置 5 分钟的宽限期。现在,user777 可以将会话宽限期设置为等于或小于用户级别设置的任何值:


=> \c
You are now connected as user "dbadmin".
=> ALTER USER user777 GRACEPERIOD '5 minutes';
ALTER USER
=> \c - user777
You are now connected as user "user777".
=> SET SESSION GRACEPERIOD '6 minutes';
ERROR 8175:  The new period 00:06 would exceed the user limit of 00:05
=> SET SESSION GRACEPERIOD '4 minutes';
SET