кластер патрони из двух нод, в нем табличка:
CREATE TABLE test(
id serial PRIMARY KEY,
text VARCHAR (255) NOT NULL
);
сделано было следующее :
- инсерт одной записи (insert into test (text) values ('some text');)
- смена мастера, посредством выключения юнита патрони
- инсерт одной записи
- смена мастера
- инсерт одной записи
в результате вот такая картина :
postgres=# select * from test;
id | text
----+-----------
1 | some text
34 | some text
67 | some text
при этом
postgres=# \d test_id_seq
Sequence "public.test_id_seq"
Type | Start | Minimum | Maximum | Increment | Cycles? | Cache
---------+-------+---------+------------+-----------+---------+-------
integer | 1 | 1 | 2147483647 | 1 | no | 1
вопрос, если для сиквенса не задан кеш (кеш = 1),
почему при смене мастера ( смена таймлинии), значение сиквенса убегает вперед ? (на 32 записи насколько могу судить)
пример простой, реально выполненный, интересна механика происходящего, и можно ли (нужно ли) с этим что-то делать ?
Где-то писали, что при репликации сиквенсы передаются наперёд, т.к. передача сиквенса на каждый nextval - слишком большой оверхед.
хм, интересно, возможно, хочу пруфы )
По моему, вы только что этот пруф получили, когда эксперимент провели
> почему при смене мастера ( смена таймлинии), значение сиквенса убегает вперед ? Потому что выполняется recovery. > (на 32 записи насколько могу судить) Да, максимум на 32. > интересна механика происходящего Суть в предназначении sequence (быстрой генерации гарантированно уникальных значений). И эта гарантия должна быть durable, т.е. и в случае "падения" сервера PostgreSQL sequences тоже не должны выдавать дубликатов. Чтобы этого добиться, их изменения нужно писать в WAL. Но если писать каждое изменение, то быстрой генерации уже не получается. Поэтому пишется только каждое 32-ое изменение, причём пишется "заранее", т.е. в WAL записывается состояние, как если бы сервер уже использовал будущие 32 значения, естественно. Отсюда и "прыжки" sequences при recovery (другие СУБД, кстати, ведут себя так же и по тем же причинам). Что касается реализации — см. https://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/backend/commands/sequence.c;h=72bfdc07a49e83fcb720ed39b90d5405bd5c2ad9;hb=HEAD#l661 (код nextval_internal(), определение SEQ_LOG_VALS). > и можно ли (нужно ли) с этим что-то делать ? Соответственно, нет и нет.
примерно такого ответа и я ждал, большое спасибо )
Обсуждают сегодня