Skip to content

SQL requests synchronization

В современной реализации picodata есть несколько способов получить неожиданные результаты (read phenomena) при работе с данными. См предшествующие дискуссии:

29.05.2024

https://t.me/c/1445372156/16517

Дмитрий Кольцов, [29/05/2024 15:11]

как работают чтения из глобальных таблиц? Они ходят на рафт лидер? есть возможность принудительно сходить на лидер, если я хочу свежайшие данные?

Yaroslav Dynnikov, [29/05/2024 15:17]

Спрашивай по другому. Делает ли кто-нибудь операцию read_index (кворумное чтение)? Я полагаю что нет

Короче, это интересная тема, давайте обсудим. Кворумное чтение как операция существует, но как пробросить это через sql вопрос хороший.

Клиент делает SELECT * FROM t_global

Как явно поросить пикодату сделать ридиндекс?

Костя Осипов, [29/05/2024 15:39]

это называется repeatable read

01.07.2024

https://t.me/c/1445372156/18874

Dmitry Rodionov, [01/07/2024 12:47]

Обратил внимание на следующее поведение, когда мы выполняем двухфазный ddl мы ждем применения опа только на текущем узле. Т е в остальном кластере изменение еще могло не доехать. Я к этому пригреб через флакнувший тест: #726 (closed) и задумался то ли это поведение которое нам нужно. Т е в команде мы могли бы ждать ака от всех узлов чтоб не было такой ситуации. Могло бы быть полезно для миграций, т е как скрипт миграций закончил работу мы сможем гарантировать что все узлы накатили изменения и прилоежние не встретит spurious ошибок из-за того что объект не был создан. Из минусов если мы ждем всех это значит что если в кластере какая-то авария то мы повиснем. Мб это ок и нужно сначала чинить кластер а потом звать ddl. Что думаете? @y_dynnikov @gmoshkin2

Результат нужно задокументировать, в текущей доке страница с изменением схемы work in progress: https://docs.picodata.io/picodata/stable/architecture/clusterwide_schema/#two_phase_algorithm

Georgy Moshkin, [01/07/2024 12:58]

ЕМНИП разрабатывая DDL мы представляли себе такую картину, что клиент в ответ на свой запрос получает raft_index, который можно использовать чтобы синхронизироваться с кластером: когда у всех инстансов applied будет больше этого, операция будет применена. Потом в какой-то момент у нас несколько сменилась парадигма на той, что мы SQL-first СУБД, и соответственно в стандарте SQL возврат raft index не предусмотрен, поэтому мы должны сделать что-то такое универсальное, чего ожидает большинство пользователей. Как ты правильно заметил, автоматически дожидаться применения на всё кластере -- это может привести к нежелательным последствиям. Но и рафт индекс из SQL мы никак получить не можем. В результате мы оказались в такой ситуации.

как вариант можно добавить в SQL запрос какой-нибудь option WAIT_APPLIED_EVERYWHERE или ещё какой-то синтаксис

Dmitry Rodionov, [01/07/2024 13:03]

Я бы скорее сделал наоборот, по умолчанию ждал и сделал опцию на не ждать. В такой картине опция пригодится только если кластер нездоров, а happy path без дополнительных приседаний

Костя Осипов, [01/07/2024 13:18]

Как сказал Дима

По умолчанию ждать что применится везде

У нас уже есть тайм-аут в опциях

Ну не дождемся, сработает тайм-аут, это не то же самое что старое поведение конечно .. но похоже

В идеале конечно возвращать в ответе в warning дополнительную информацию

Из серии, не дождались кворума или не дождались применения на всех нодах

Обсуждения сводятся к тому, что мы хотим из sql управлять синхронизацией DDL запросов:

CREATE TABLE ... OPTION WAIT_APPLIED_EVERYWHERE
CREATE TABLE ... OPTION WAIT_APPLIED_LOCALLY ; default
CREATE TABLE ... OPTION WAIT_COMMITTED

Этот же набор опций применим для DML в глобальные таблицы. Для шардированных таблиц применим только WAIT_APPLIED_LOCALLY, хотя everywhere мог бы тоже использоваться, с другой семантикой (на все реплики репликасета)

Для DQL нужна другая опция:

SELECT ... OPTION QUORUM_READ

Открытым остается вопрос какая из опций должна использоваться по-умолчанию. Я полагаю компромисс — это WAIT_APPLIED_LOCALLY. Everywhere обычно не требуется тк есть фенсинг запросов (см. Google Docs — RFC — Storage Schema)

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information