Skip to content

Что означают .ready и .done, и почему WAL задерживается

Автор: Richard Yen, A practical guide to what .ready and .done mean, and why WAL sticks around


9:12 утра в понедельник. Кто-то из вашей команды открывает каталог pg_wal/archive_status/ во время паники по поводу хранилища и видит длинный список файлов, оканчивающихся на .ready. Возникает вопрос, который многие из нас задавали хотя бы раз: «Сломалась ли репликация?» Потоковые реплики всё ещё выглядят в основном нормально, но файлы .ready продолжают накапливаться, использование диска продолжает расти, и никто до конца не уверен, что на самом деле означают .ready и .done.


Что такое .ready и какие (если вообще какие) действия мне нужно предпринять? Давайте поговорим об этом сегодня.



Подсказка: Это о доставке WAL


Представьте доставку WAL как три независимых шага:



  1. Генерация WAL

  2. Транспортировка WAL

  3. Воспроизведение или потребление WAL



archive_command — это один из способов транспортировки. Потоковая репликация — другой. Обратите внимание, что логическая репликация также имеет канал транспортировки, но она транспортирует декодированные данные логических изменений, а не сырые файлы сегментов WAL.

Продолжить чтение "Что означают .ready и .done, и почему WAL задерживается"

Всё о GUC по порядку:

Christophe Pettus: All Your GUCs in a Row: event_triggers


Событийный триггер (event trigger) срабатывает на события базы данных, а не на изменения строк: на ddl_command_start, sql_drop, table_rewrite и, начиная с PostgreSQL 17, на login. Они используются для аудита DDL или наложения запрета на DDL, и они идут с хорошо известным способом выстрелить себе в ногу. Напишите триггер на ddl_command_start, функция которого вызывает исключение, и теперь каждая команда DDL в базе данных завершается ошибкой, включая DROP EVENT TRIGGER, который вы использовали бы для его удаления. Документация содержит ровно этот пример — функцию abort_any_command, настроенную на прерывание всего, предположительно для того, чтобы вы узнали форму ошибки, когда уже её совершили.



Продолжить чтение "Всё о GUC по порядку: "

Всё о GUC по порядку: event_source

Автор: Christophe Pettus: All Your GUCs in a Row: event_source


event_source — это параметр для Windows, что означает, что для большинства читающих это не делает ровно ничего. Если вы запускаете PostgreSQL на Linux или в управляемом сервисе, там нет журнала событий Windows, с которым он мог бы взаимодействовать, и эта строка навсегда остаётся со значением по умолчанию. То, что следует далее, предназначено для меньшинства пользователей Windows, и сводится к одному факту, который стоит знать.

Продолжить чтение "Всё о GUC по порядку: event_source"

Любопытный случай с display(df)

Пересказ статьи Karthik. The curious case of display(df)


Вы просто хотите посмотреть ваши данные. Вы быстро набираете display(df) в ячейке notebook и жмете Выполнить. Это кажется совершенно безобидно - кроме того, это всего лишь предварительный просмотр вашего фрейма данных, не так ли?

Но через несколько мгновений ваш кластер начинает вращаться, ячейка работает намного дольше, чем ожидалось, и ваш браузер может даже заикаться.

Хотя display() является фантастическим инструментом для интерактивного исследования, но, если слишком сильно полагаться на него, он может незаметно задушить ваши задания Apache Spark. Давайте заглянем под капот, чтобы точно выяснить, что происходит, когда вы вызываете display(), почему все замедляется, и как простое переключение на show() может радикально улучшить вашу производительность.
Продолжить чтение "Любопытный случай с display(df)"

VACUUM — это ложь (о ваших индексах)

Автор: Radim Marek: VACUUM Is a Lie (About Your Indexes)


Существует распространённое заблуждение, которое беспокоит большинство разработчиков, использующих PostgreSQL: настройте VACUUM или запустите VACUUM, и ваша база данных останется здоровой. Мёртвые кортежи будут очищены. Идентификаторы транзакций переработаны. Пространство освобождено. Дальнейших действий не требуется.


Но есть пара «грязных» секретов, о которых люди не знают. Первый из них заключается в том, что VACUUM лжёт вам о ваших индексах.

Продолжить чтение "VACUUM — это ложь (о ваших индексах)"

Всё о GUC по порядку: escape_string_warning

Автор: Christophe Pettus: All Your GUCs in a Row: escape_string_warning


escape_string_warning включён по умолчанию уже около двадцати лет, и на современном PostgreSQL, настроенном обычным образом, он никогда не скажет вам ни слова. Это не неисправность. Условие, о котором он предупреждает, перестало быть поведением по умолчанию в 2011 году.

Продолжить чтение "Всё о GUC по порядку: escape_string_warning"

Всё о GUC по порядку: enable_tidscan

Автор: Christophe Pettus: All Your GUCs in a Row: enable_tidscan


enable_tidscan — это параметр enable_*, который вы почти наверняка никогда не установите, и на этот раз это не предупреждение, а просто факт о том, как происходят сканирования TID. Вы не натыкаетесь на него случайно, как на последовательное сканирование или сортировку. Сканирование TID появляется только тогда, когда вы явно написали условие на ctid, поэтому тип плана, которым управляет этот параметр, появляется именно тогда, когда вы его запросили, и никак иначе.



(Для протокола: я за всю свою жизнь ни разу не видел узел tidscan.)


Продолжить чтение "Всё о GUC по порядку: enable_tidscan"

Посмотрим, что делает VACUUM на уровне страницы

Автор: Radim Marek: VACUUM at the Page Level


В статье о HOT-обновлениях в Postgres мы рассмотрели, как обрезка страниц (page pruning) очищает HOT-цепочки — элегантное сокращение, с помощью которого PostgreSQL освобождает место мёртвых кортежей во время обычных операций чтения. И всё это без ожидания фонового процесса. Но обрезка — это именно сокращение. Она работает только в пределах одной страницы и только для кортежей, обновлённых через HOT. Для всего остального (холодные обновления, затрагивающие индексированные столбцы, обычные DELETE, очистка записей индексов, регистрация в карте свободного пространства, обслуживание карты видимости) необходим VACUUM.



Эта статья не будет повторять то, что VACUUM делает с эксплуатационной точки зрения. Статья DELETEs are difficult охватывает настройку autovacuum, распределение рабочих процессов и эксплуатационную сторону очистки мёртвых кортежей. Здесь мы будем наблюдать за работой VACUUM побайтово. Мы сделаем снимок страницы до и после каждого этапа, отслеживая, что именно меняется в заголовке страницы, указателях строк, заголовках кортежей, карте свободного пространства и карте видимости. Инструменты всё те же: pageinspect, pg_visibility и pg_freespacemap.


Продолжить чтение "Посмотрим, что делает VACUUM на уровне страницы"

Всё о GUC по порядку: enable_sort

Автор: Christophe Pettus, All Your GUCs in a Row: enable_sort


Обращение к enable_sort = off, потому что в запросе есть медленная сортировка, обычно бьёт мимо цели. Когда сортировка медленная, это обычно происходит из-за того, что она сбрасывается на диск, что является проблемой work_mem. Если сортировки вообще не должно быть, исправление — это индекс. enable_sort не изменяет ни одного из этих факторов, и его отключение редко бывает тем, что вам действительно нужно.

Продолжить чтение "Всё о GUC по порядку: enable_sort"

Новости за 2026-08-15 - 2026-08-21

§ Изменения среди лидеров рейтинга

Рейтинг	Участник (решенные задачи)
14 gennadi_s (206)
35 Шведа Сауля (160)

§ Лидеры недели

	Участник		w_sel	all_sel	select	dml	Всего	Рейтинг
Шибаев (saah) 5 85 12 0 12 622
Виноградова С.М. (Tigra1) 2 150 5 0 5 151
Саркисьян Г. (gennadi_s) 1 223 4 0 4 14
Чвикова А.М. (Chvikova) 3 14 4 0 4 5150

§ Претенденты на попадание в TOP 100

Рейтинг	 Участник (решенные задачи, время в днях)
135 Murderface_ (155, 714.490)
151 Tigra1 (150, 28.918)
Продолжить чтение "Новости за 2026-08-15 - 2026-08-21"

Всё о GUC по порядку: enable_seqscan

Christophe Pettus: All Your GUCs in a Row: enable_seqscan


enable_seqscan не отключает последовательные сканирования. Он не может этого сделать, и никогда не был для этого предназначен. В документации прямо сказано: последовательные сканирования невозможно полностью подавить, потому что иногда чтение всей таблицы является единственным способом ответить на запрос. На самом деле, значение off говорит планировщику избегать последовательного сканирования, только когда у него есть любая другая альтернатива. Это диагностическая инструкция, а не конфигурационная, и это различие — весь смысл данного параметра.



По умолчанию включён, контекст — пользовательский. Вы отключаете его в сессии, чтобы задать вопрос планировщику. Вы никогда не отключаете его в postgresql.conf, и мы объясним почему.

Продолжить чтение "Всё о GUC по порядку: enable_seqscan"

Анализ причин бага контрольной точки PostgreSQL

Автор: Warda Bibi, Inside a PostgreSQL Checkpointer Bug: A Production Postmortem


В одной из производственных баз данных PostgreSQL 16.8 нашего клиента в журнале начала появляться ошибка, похожая на ошибку памяти:



ERROR: invalid memory alloc request size


Ошибка сразу указывала на двух вероятных виновников:



  • Исчерпание памяти

  • Повреждение памяти



Как оказалось, ни то, ни другое не было причиной. Вместо этого мы столкнулись с известной ошибкой PostgreSQL, которая заперла процесс контрольной точки (checkpointer) в бесконечном цикле повторных попыток. Единственным способом восстановления была принудительная перезагрузка, за которой последовало длительное воспроизведение WAL во процессе аварийного восстановления.



Эта статья объясняет, что произошло, почему ручные контрольные точки не могли это исправить, и как обновление до минорной версии PostgreSQL окончательно решило проблему.

Продолжить чтение "Анализ причин бага контрольной точки PostgreSQL"

Всё о GUC по порядку: enable_self_join_elimination

Christophe Pettus: All Your GUCs in a Row: enable_self_join_elimination


Вы редко являетесь единственным, кто пишет ваш SQL. Ваша ORM пишет часть его, ваши вложенные представления пишут ещё больше, и рано или поздно одно из них соединяет таблицу саму с собой по её собственному первичному ключу. Это соединение возвращает ровно те строки, с которых началось. enable_self_join_elimination — это оптимизация PostgreSQL 18, которая замечает и удаляет такое соединение.

Продолжить чтение "Всё о GUC по порядку: enable_self_join_elimination"

Сброс последовательности PostgreSQL: объяснение START With против RESTART With или SETVAL

Пересказ статьи PostgreSQL Sequence Reset: START WITH vs RESTART WITH vs SETVAL Explained


Недавно во время одной из миграций Oracle на PostgreSQL с корпоративным клиентом при разработке резервного модуля runbook мы оценивали шаги по выполнению сброса значения последовательности для соответствия исходному значению так, чтобы каждый новый запрос значения с использованием NextVal был новым и не приводил к сбою транзакций.

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

Мы использовали экспорт SEQUENCE_VALUES в ora2pg для генерации команд DDL, чтобы установить последние значения последовательностей.

Пример команды Ora2pg для экспорта DDL последовательности. Продолжить чтение "Сброс последовательности PostgreSQL: объяснение START With против RESTART With или SETVAL"

Всё о GUC по порядку: enable_presorted_aggregate

Christophe Pettus, All Your GUCs in a Row: enable_presorted_aggregate


enable_presorted_aggregate включён, он включён с момента появления в PostgreSQL 16, и самое полезное, что вы когда-либо сделаете с ним, — это отключите его ровно для одного запроса.



По умолчанию включён, контекст — пользовательский: может быть установлен для сессии, роли, базы данных или встроен в одну транзакцию. Последний вариант — это и есть вся рекомендация, так что запомните его.

Продолжить чтение "Всё о GUC по порядку: enable_presorted_aggregate"