Если мы сравним несколько типов репликации (с одним лидером, несколькими лидерами или без лидеров), репликация с одним лидером может быть линеаризуемой. Насколько я понимаю, линеаризуемость означает, что после завершения записи все последующие чтения должны возвращать это значение или более позднюю запись. Или другими словами, должно быть впечатление, что база данных всего одна, но не более того. Так что я думаю, не устаревшие чтения.
PostgreSQL в своей потоковой репликации имеет возможность сделать все свои реплики синхронными с помощью synchronous_standby_names
, а также имеет возможность точной настройки с помощью параметра synchronous_commit
, где для него можно установить значение remote_apply
, поэтому лидер ждет, пока транзакция не будет воспроизведена на резервный (что делает его видимым для запросов). В документации, в абзаце, где говорится что касается параметра remote_apply, в нем говорится, что он позволяет балансировать нагрузку в простых случаях с причинно-следственной согласованностью.
Несколько страниц назад там написано это:
,,Некоторые решения являются синхронными, что означает, что транзакция, изменяющая данные, не считается зафиксированной до тех пор, пока все серверы не зафиксируют транзакцию. Это гарантирует, что при отработке отказа данные не будут потеряны и что все серверы с балансировкой нагрузки будут возвращать согласованные результаты независимо от того, какой сервер запрашивается.
Поэтому я изо всех сил пытаюсь понять, что можно гарантировать и какие аномалии могут произойти, если мы балансируем запросы на чтение к репликам чтения. Могут ли еще быть устаревшие чтения? Может ли это произойти, когда я запрашиваю разные реплики, чтобы получить разные результаты, даже если запись не происходит после того, как на лидере? Мое впечатление - да, но я не совсем уверен. Если нет, то как PostgreSQL предотвращает устаревшие чтения? Я не нашел ничего с более подробной информацией о том, как это работает в полной мере под капотом. Использует ли он двухфазную фиксацию или какую-то его модификацию, или использует какой-то другой алгоритм для предотвращения устаревших операций чтения?
Если он не обеспечивает возможность чтения без устаревших данных, есть ли способ сделать это? Я видел, что у PgPool есть возможность балансировать нагрузку на реплики, которые отстают не более чем от определенного порога, но я не понял, можно ли определить балансировку нагрузки на реплики, которые находятся выше лидера.
Меня действительно сбивает с толку, чтобы действительно понять, могут ли быть аномалии в полностью синхронной репликации в PostgreSQL.
Я понимаю, что у такой установки есть проблемы с доступностью, но сейчас это не проблема.