分发命名序列
当创建命名序列时,其 CACHE
参数决定了每个节点在会话期间所保留的序列值的数量。默认缓存值为 250K,因此每个节点在每个会话期间为每个序列保留 250,000 个值。此默认缓存大小为大规模插入或复制操作提供了一种有效的方式。
如果将序列缓存设置为较低的数字,则节点可能会更频繁地请求一组新的缓存值。提供新缓存时,Vertica 必须锁定编录。在 Vertica 释放锁之前,其他数据库活动(例如表插入)会被阻止,这将对整体性能产生不利影响。
当一个新会话启动时,节点缓存最初为空。默认情况下,启动程序节点会为群集中的所有节点请求和保留缓存。可以通过将配置参数 ClusterSequenceCacheMode
设置为 0 来更改此默认值,以便每个节点都请求其自己的缓存。
有关 Vertica 如何请求缓存并在群集中的所有节点之间分发缓存的信息,请参阅序列缓存。
分布式会话的影响
Vertica 在所有节点之间分发会话。群集节点第一次对序列调用 NEXTVAL 函数以递增(或递减)其值时,该节点会请求其自己的序列值缓存。然后,该节点会为当前会话维护该缓存。当其他节点调用 NEXTVAL 时,它们也会创建和维护其自己的序列值缓存。
在会话期间,节点会以不同的频率独立调用 NEXTVAL。每个节点都使用其自己的缓存来填充序列。所有序列值都保证唯一,但是可能与另一个节点上执行的 NEXTVAL 语句出现乱序。因此,序列值通常不连续。
在所有情况下,每行仅递增序列一次。因此,如果多个列引用了同一序列,则 NEXTVAL 会将该行中的所有列设置为相同的值。这适用于联接表的行。
计算命名序列
Vertica 按如下方式计算序列的当前值:
-
在每个语句结束时,会话中使用的所有序列的状态都会返回到启动程序节点。
-
启动程序节点计算每个序列在所有节点上的所有状态下的最大
CURRVAL
。 -
此最大值将用作后续语句中的
CURRVAL
,直到调用另一个 NEXTVAL。
丢失序列值
在下列情况下,缓存中的序列值可能会丢失:
-
如果在调用 NEXTVAL 后某条语句失败了(因此耗用了缓存中的一个序列值),则值就会丢失。
-
如果连接断开了(如删除了会话),则缓存中尚未通过 NEXTVAL 返回的所有剩余值都会丢失。
-
一个或多个节点尚未用完其当前缓存分配时,启动程序节点便为每个节点分发新的缓存块。有关此场景的信息,请参阅序列缓存。
可以使用 ALTER SEQUENCE...RESTART 恢复丢失的序列值,这会在下一个会话中将序列重置为指定的值。