#федичитальня #PostgreSQL #PostgreSQL15 #контрольные_точки #фоновая_запись
За полгода я прочитал треть книжки. За выходные на природе прочитал 30 страниц. Медленно.
Контрольная точка - это две метки в #wal с началом и концом. В начале фиксируется список грязных буферов, в конце - все зафиксированные на момент начала грязные буферы сдамплены на диск. По контрольной точке восстановливается согласованное состояние на момент её начала при восстановлении из резервных копий. Файлы wal, кроме предыдущей завершённой и текущей контрольной точки бесполезны. При достижении `max_wal_size` форсируется _внеплановая_ контрольная точка. Много внеплановых контрольных точек – плохо. С ними вообще любопытно: делаешь часто - лишние накладные расходы, плохо, делаешь редко – плохо, возрастает время восстановления, растёт объём хранимых wal-файлов. Это как менеджер, спрашивающий как дела по задаче. Подстраивать интервалы для checkpointer'а нужно по обратной связи из мониторинга, учитывая профиль нагрузки на систему. Такое себе, я ожидал больше динамики и автоматизации.
Мне понравился подход в сбросе грязных буферов на диск - трэкать скользящим окном время и объём IO на обработку предыдущих контрольных точек, если успеваем, то _замедляемся_, чтобы не создавать пиковую нагрузку в бутылочном горлышке системы (дисковой записи) на ровном месте. Это резервирует дополнительные ресурсы для штатного функционирования системы, которые могут _внезапно_ понадобиться.
#Журнал можно записывать синхронно и асинхронно.
Синхронный режим это медленная жопа, а много OLTP транзакций её насилуют. Поэтому для синхронного режима придумали батчинг записи коммитов в журнал, по дефолту он выключен, регулируется опцией commit_delay. Нравится метафора из книги с удерживаемой кнопкой дверью лифта, когда первая транзакция, которая готова закоммититься, ждёт немного, вдруг с ней за компанию ещё одна транзакция влетит записываться на диск.
Асинхронный режим допустим, если вы готовы потерять пару сотен последних транзакций, даже если нужно будет повторить их в ручном режиме или компенсировать убытки из своего кармана. Исправный ИБП, сигнал о потере питания от которого вызывает штатное завершение работы системы, снижает вероятность такой ситуации раз в десять.
У журнала несколько уровней записи - minimal, replica, logical. Как я понял, logical это для master, replica это для slave, minimal это для fucking slaves. Про logical надо бы подробнее почитать, в книжке он мимоходом упоминается. Синхронная репликация журнала, когда коммит записи на мастере означает гарантию чтения этой записи на реплике, звучит как головная боль для администратора БД и тормоза. Мастер-мастер репликация звучит ещё более сложной. Асинхронная репликация журнала _без_ гарантии чтения с реплики выглядит гораздо проще, кажется большинству систем этого за глаза хватать должно.
Видел в https://highload.guide милую схемку с:
- 1 master,
- 1-2 slaves, выделенных для снятия резервных копий,
- N-slaves для readonly OLAP-нагрузки.
Интересно, кстати, как с использованием этого у #mastodon обстоят дела, уж чего-чего, а readonly нагрузки тут достаточно.
Возникшие вопросы, которые пока остаются без ответа
- Как в PostgreSQL выглядит инициализация дополнительной реплики и какую нагрузку это создаёт на master?
- Возможна ли иерархическая репликация для распределения сетевой нагрузки на Master?
- Как себя в таком случае чувствуют промежуточные полумастер-реплики?