Возможен скачок идентификации с кэшем Больше 1?

#postgresql

Вопрос:

У меня есть таблица с идентификатором bigint кэш 10

 create table myschema.mytable
(
xid bigint NOT NULL GENERATED ALWAYS AS IDENTITY ( INCREMENT 1 minvalue -9223372036854775808 start -9223372036854775808 MAXVALUE 9223372036854775807 CACHE 10 ),
x1 text, xtimestamp ...
)

create function myshema.myfun(...)
returns table(...)
language 'plpgsql'
cost 100
volatile security definer
as $
declare vxid bigint;
begin
  insert into myschema.mytable(x1) values(...) 
  returning xid into vxid;
  return query select vxid;
end;
$
 

Использование pg-promise API узла:

 const pgp = require('pg-promise')();    // () = taking default initOptions
exports.db = pgp(
    {
        user: process.env.PGuser,
        host: process.env.PGhost,
        database: process.env.PGdatabase,
        password: process.env.PGpassword,
        port: process.env.PGport,
        max: 20,                     // default
        idleTimeoutMillis: 10000        // default
    }
);
 

Я заметил, что все новые рекорды с разрывом в 10, select xid, xtimestamp from mytable order by 1 desc limit 8 :

введите описание изображения здесь

У MS SQL возникает проблема с переходом на идентификацию при перезапуске, но в течение этого периода все мои Postgre, API и интерфейс работают.

Это невозможно воспроизвести, если выполнить следующие действия в pgAdmin, возможно, это всегда происходит в одном и том же сеансе:

 create table public.testidentitycache(xid bigint NOT NULL GENERATED ALWAYS AS IDENTITY ( INCREMENT 1 minvalue -9223372036854775808 start -9223372036854775808 MAXVALUE 9223372036854775807 CACHE 10 ), xtxt text)

insert into public.testidentitycache(xtxt) values('this is 6')
insert into public.testidentitycache(xtxt) values('this is 5')
...
select * from public.testidentitycache
 

pg версия 12

Комментарии:

1. CACHE Обстановка кусает тебя. Очевидно, в том pg_promise случае, если вы начинаете новый сеанс для каждого INSERT , и это приводит к удалению ранее кэшированных значений.

2. @Adrianklaverэто то, что я подозревал.

Ответ №1:

В параметрах последовательности идентификаторов вы проинструктировали использовать a CACHE 10 , что означает , что при вызове последовательности следующие 10 значений извлекаются и помещаются в память. Если одно и то же соединение вызывает одну и ту же последовательность, возвращается значение из памяти… но если используется другое соединение (например, при использовании пула), следующее значение снова извлекается из последовательности (и снова помещает следующие 10 в кэш).

Вы можете либо жить с этим, либо использовать кэш 1 (по умолчанию)

Комментарии:

1. Это то, что я подозревал. На самом деле почти все используют бассейн, кажется cache ## , это не помогает, но действительно вредит.

2. @Jeb50 это может быть полезно, если у вас начнет (намного) больше вызовов или если вы вставляете пакеты