Автоматическая очистка

Для тех, кому это не надо, чуть ниже готовая универсальная таблица с рекомендуемыми значениями параметров. Разумеется, каждый считает, что его случай – уникальный. Если суммарный объем всех ваших баз превышает десятки терабайт – то да, вам придется самим все просчитывать конкретно для вашего случая. А для всех остальных прошу брать значения из таблицы, от них явно хуже не станет.

Автоматическая очистка – это показательный пример того, что всегда придется чем-то жертвовать, потому что отключение autovacuum значительно повышает производительность, поскольку освободятся ресурсы CPU и RAM (в основном, конечно же речь про ресурсы дисковой подсистемы), но при этом объем баз со временем вырастет многократно. Так что отключать его не стоит ни при каких условиях.

Autovacuum не отличается от ручной SQL команды VACUUM ничем, кроме того, что работает автоматически (если не считать доп. параметры VACUUM). Его основная задача – оптимизация запросов и равномерное распределение нагрузки операций очистки. Автоматическая очистка не уменьшает размер баз. Она просто удаляет мертвые строки из таблиц, а дыры (пустые места, которые все равно занимают место на диске) от них остаются, и в эти дыры может быть записана новая нужная информация.

Опять же, нам не очень интересно, как он работает. А если кому интересно – в интернете полно статей с алгоритмами его работы. Нам лишь важно то, как его настроить таким образом, чтобы, с одной стороны, базы не пухли, а с другой, чтобы ресурсы распределялись равномерно. Эти настройки универсальны для всех приложений.

Все настройки автовакуума находятся в конфигурационном файле postgresql.conf.

autovacuum

Отвечает за то, будет ли служба автоматической очистки включена или нет. Обязательно раскомментируйте и выставьте значение on, просто на всякий случай.

track_counts

Не относится к автовакууму напрямую, однако все равно его следует включить (также раскомментировать и выставить значение on), чтобы процессы собирали статистику для каждой из таблиц БД. Статистика необходима, чтобы запросы работали более эффективно (в общем, немного повышает производительность системы в целом). Без статистики автовакуум сойдет с ума (перестанет распределять ресурсы эффективно). Статистика записывается на диск и сохраняется после перезапуска.

autovacuum_naptime

Определяет минимальную задержку между запусками автовакуума. Рекомендую задать значение 15-20 s.

autovacuum_max_workers

Определяет максимальное количество рабочих процессов. Чем их больше – тем больше объектов БД одновременно будут подвергнуты очистке (таблицы, индексы и т.п.). С одним объектом может работать несколько рабочих процессов (система распределяет их автоматически в зависимости от объема таблиц и количества мертвых строк в них). При этом в одной БД может работать сколько угодно рабочих процессов. Эти же рабочие процессы занимаются еще и сбором статистики, и разделить их пока что нельзя. Выставляйте значение равным 25-50% от количества всех логических ядер сервера (в зависимости от производительности на ядро по сравнению с остальными CPU на той же платформе). Четверть или половина – это также не золотая середина, потому что системы у всех разные. Но это все равно лучше, чем значение по умолчанию 3.

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

autovacuum_vacuum_cost_limit и autovacuum_vacuum_cost_delay

Я их объединил, потому что они взаимосвязаны. Первый отвечает за объем работы в условных единицах, который необходимо выполнить рабочим процессам перед тем, как они будут остановлены на промежуток времени, который задан во втором параметре. Иными словами, производительность не вырастет за счет увеличения числа рабочих процессов, потому что объем работы и «перерыв» для всех них все равно будут одинаковые (объем работы распределяется между всеми процессами, так что не надо думать, что мы задаем объем работы для каждого из процессов).

autovacuum_vacuum_cost_limit имеет по умолчанию значение 200, которое берется из параметра vacuum_cost_limit. Чем оно выше – тем автовакуум агрессивнее (успокоится, только когда будет выполнено больше работы перед очередным перерывом). Но это значение крайне меньше необходимого и не менялось, наверное, со времен первых версий PostgreSQL, даже несмотря на то, что задержку уменьшили в 10 раз (это параметр ниже). Оно настолько маленькое, что объем работы в 200 единиц будет выполнен одним рабочим процессом примерно за то же время, что и десятью (звучит очень странно, однако на деле так оно и есть, просто примите это). Высчитывать это очень долго и сложно, поэтому оставляйте 1000 при задержке в 2 ms, значениях стоимости (веса) операций обслуживания по умолчанию и количеству процессов, равным 25-50% от числа логических ядер. Однако, конечно же, 1000 – это универсальное значение, и на самом деле все зависит от объема ваших баз в кластере (что логично, потому что чем больше база – тем больше работы необходимо выполнить по ее очистке и оптимизации). Да, возможно, при таком значении автовакуум будет немного более или менее агрессивным, чем должен быть. Однако помните, что нагрузка на базы и так не всегда является равномерной.

autovacuum_vacuum_cost_delay определяет задержку между процессами запуска автовакуума. Она нужна, чтобы время от времени прерывать процесс очистки и равномерно распределять ресурсы в том числе и для других процессов. По умолчанию стоит значение 2 ms, и этого достаточно (в более старых версиях было 20 ms).

autovacuum_vacuum_scale_factor

Выставляйте значение 0.01 (т.е. 1%) или меньше. Этот параметр определяет долю мертвых строк в таблице (плюс значение из параметра autovacuum_analyze_threshold), по достижению которого autovacuum примется за работу. Иными словами, если у вас есть таблица весом 10 MB, в которой 15% мертвых строк, то 1,5 MB на диске будут заняты ненужной информацией. Проблема в том, что по умолчанию выставлено значение 0.2 (т.е. все ваши базы могут просто так занимать на 20% больше места, чем могли бы). Очередной параметр, стандартное значение которого вводит админов в недоумение.

autovacuum_vacuum_threshold

Как уже было сказано выше, этот параметр – константа, к которой прибавляется количество мертвых строк в таблице (из параметра autovacuum_vacuum_scale_factor). То есть, если у нас этот параметр по умолчанию равен 50, а доля мертвых строк в таблице подошла к значению autovacuum_vacuum_scale_factor (при этом само значение мы выставили в 0.01, а общее количество строк равно 1000), то автовакуум запуститься только, если количество мертвых строк в таблице превышает 60 (т.е. 1000 * 0,01 + 50). Можете его оставить, все равно 50 лишних строк в таблице из 50000 строк погоды не сделают. Разумеется, вы уже догадались, что можно выставить значение параметра autovacuum_vacuum_scale_factor равным нулю и отталкиваться только от константы, заданной в параметре autovacuum_vacuum_threshold, однако делать так не рекомендую, потому что это очень сильно увеличит чувствительность автовакуума, и он будет запускаться, если в таблице на 300 строк 4 из них являются мертвыми (если до этого мы задали долю в 1%). И с большими таблицами проблем нет, однако проблема именно в маленьких таблицах.

Казалось бы, какая разница? Ведь чем меньше мертвых строк – тем лучше? Да, это правда. Однако ради удаления пары десятков строк запускать процесс автоочистки, который должен пройтись по всем строкам для их анализа? Это просто невыгодно по ресурсам. Тем более, что очистить одну таблицу на 100 строк, в которой 10 мертвых – это не то же самое, что очистить 10 таблиц, в которых по 10 строк, одна из которых мертвая.

Два параметра выше работают точно также, как и параметры сбора статистики:

autovacuum_analyze_scale_factor (также выставляем 0.01 или меньше)

autovacuum_analyze_threshold (оставляем по умолчанию)

Отдельно отмечу, что не следует бояться выделять ресурсы для автоматической очистки больше, чем необходимо. Потому что процесс не сможет сожрать больше ресурсов, чем может сожрать. Если работы нет – значит работы нет, и ресурсы не будут задействованы (потому что автовакуум знает, надо ли ему работать или еще нет). Так что не бойтесь, что ресурсы сгорят впустую. Да, может быть, остальным процессам в какие-то периоды времени будет их не хватать, однако процесс очистки будет выполнен с большей скоростью, и, следовательно, быстрее будет выполнена оптимизация запросов. Я бы на вашем месте, наоборот, боялся выделить меньше рекомендованного, потому что это может привести к распуханию баз, а чем больше базы распухли – тем больше времени и ресурсов понадобиться на их очистку и оптимизацию запросов в дальнейшем (под словом распухание я имею ввиду именно неоправданное увеличение объема, то есть информация эта бесполезна и должна быть удалена).

autovacuum_work_mem

Задает объем памяти для указателей на мертвые строки. По умолчанию берется из параметра maintenance_work_mem. Память выделяется сразу в полном объеме для каждого из рабочих процессов отдельно. То есть, если вы задали 128 MB, и у вас 8 рабочих процессов, то система сразу полностью выделит 1 GB памяти (если все процессы будут активны), даже если для них будет достаточным меньший объем памяти. Выделяемый объем зависит от количества рабочих процессов. Смотрите, чтобы в сумме он не превышал 1/64 от общего объема памяти сервера. То есть, если вы задали 32 рабочих процесса, а на сервере у вас всего 128 GB памяти, то задавайте значение равным не более 64 MB. Также имейте ввиду, что вы можете задать значение как в самом параметре autovacuum_work_mem, так и наследовать его из параметра maintenance_work_mem. Рекомендую именно первый способ, потому что так мы задаем объем памяти конкретно для автовакуума, и это упростит планирование ресурсов.

Итог

Процесс автоматической очистки – это ваш друг, который ест ровно столько, сколько ему надо.

Процесс очистки и сбора статистики выполняется автоматически, и не стоит запускать его вручную без веской на то причины. На форумах вы еще не раз увидите людей, которые отключали автовакуум и запускали через скрипт раз в сутки обычный vacuum без предварительного сбора статистики с доп. параметрами, а потом страдали из-за распухания баз и длительности самого процесса. Да, эта идея имеет право на жизнь, и дальше мы на нее посмотрим, поскольку автовакуум в первую очередь предотвращает распухание, но он не сильно поможет, когда база уже распухла (потому что автовакуум удаляет строки в таблицах, но эти пустые строки все равно занимают место в файловой системе; но зато в эти пустые строки потом может быть записана полезная информация).

С одной стороны, автоматическая очистка и анализ создают нагрузку на все подсистемы. Но, с другой стороны, если ее отключить, то в скором времени это приведет к распуханию баз, и тогда нагрузка вырастет многократно.

И тут вы можете задаться вопросом. А почему бы не отключить его в рабочие периоды времени для повышения производительности? К примеру, написать скрипт, который бы отключал автовакуум в период с 8:00 до 20:00. Поймите, что автовакуум – это, в первую очередь, профилактика (сбор статистики и оптимизация), а не хирургическое вмешательство. При должной профилактике хирургическое вмешательство не будет требоваться так часто. Оно должно быть дополнением к автовакууму, но не заменой, потому что автовакуум сам по себе не удаляет мертвые строки, чтобы освободить место на диске.

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

Параметр

Рекомендуемое значение

autovacuum

on

track_counts

on

autovacuum_naptime

15s

autovacuum_max_workers

CPU logical cores count / 2

autovacuum_vacuum_cost_limit

1000

autovacuum_vacuum_cost_delay

2ms

autovacuum_vacuum_scale_factor

0.01

autovacuum_analyze_scale_factor

0.01

autovacuum_work_mem

RAM total size / (64 * autovacuum_max_workers)

Ниже оставил ссылки на полезные ресурсы, если вы вдруг все еще сомневаетесь в том, что автовакуум следует держать включенным или в правильности подбора параметров. Просто имейте ввиду: без автовакуума будет еще хуже. Да, если его отключить, то производительность баз вырастет, однако на долго ли?

https://www.postgresql.org/docs/current/runtime-config-autovacuum.html

https://www.enterprisedb.com/blog/postgresql-vacuum-and-analyze-best-practice-tips

Выше я упомянул о некоем «хирургическом вмешательстве», в дополнение к автоматической очистке. Это команды vacuumdb и reindexdb.

Полная очистка

Команда vacuumdb проводит анализ и полностью очищает все таблицы от мертвых строк.

Необходимые параметры:

-a – выполняет очистку для всех баз. Если хотите для какой-то конкретной, то выставляете имя базы через параметр -d.

-d <db_name> – задает имя базы.

-f – выполняет полную (full) очистку. Без нее запускать команду нет смысла. Так что всегда задавайте этот параметр. Учтите только, что изменять содержимое баз будет нельзя.

-j <count> – задает количество одновременно работающих процессов. Не рекомендую использовать, поскольку приведет к ошибке deadlock, если запускается вместе с параметром -f.

-P – не путать с -j. Не работает с -f, поэтому для нас бесполезна. За нас и так все сделает автоматическая очистка.

-z – собирает еще и статистику (без нее запускать полную очистку также не имеет смысла).

-Z – собирает только статистику, без очистки. Пригодится дальше при работе с резервным копированием и репликацией.

-F – специально вынес в конец, поскольку мне есть что сказать про заморозку. Заморозка версий строк имеет смысл только в больших системах, где счетчик транзакций по-любому будет переполнен, и не один раз. Для всех остальных случаев он просто не нужен, это пустая трата ресурсов. Если хотите использовать – то не используйте постоянно, производительность все равно не вырастет. От него базы не пухнут, все дело именно в циферках, в номерах, которые выдаются объектам БД: они не бесконечны, и их надо обновлять круг за кругом. Для расчета периодичности запуска я предлагаю вот такую формулу: 365/TB. 365 дней делим на суммарный объем ваших баз в терабайтах. Если у вас объем баз равен 200 GB, то запускаете заморозку один раз в 5 лет. Если же объем баз равен 2 TB, то каждые полгода. Или вы можете при помощи SQL запросить объект с наибольшим XID. И, если он приближается к 2 млрд, выполнить заморозку. Но в целом это не требуется, потому что autovacuum делает эту работу за вас.

https://www.postgresql.org/docs/current/app-vacuumdb.html

Перестроение индексов

reindexdb – это команда для перестроения индексов, которая также позволит сократить объем баз.

Здесь нас интересует только один параметр:

--concurrently – позволяет запускать перестроение индексов на базах в продуктивной среде. Обязательно его используйте.

https://www.postgresql.org/docs/current/app-reindexdb.html

Итог

Казалось бы, все прекрасно, просто берем и добавляем выполнение этих команд в cron в периоды минимальной активности сервера. Но не все так просто. Проблема в том, что обе эти команды на деле во время их выполнения не позволяют изменять содержимое БД (там есть нюансы, свои ограничения и недостатки), так что не используйте их в продуктивной среде, если нагрузка на базы 24/7. Что делать в таком случае? Принудительно сбрасывать подключения, получать постоянные простои? Собирать кластер? Просто забить и пусть базы пухнут? Нет. Есть решение. Это модуль pg_repack, который делает все ровно то же самое, но быстрее и, что самое важное, позволяет изменять содержимое БД во время его работы. Этот модуль мы разберем под конец статьи. Но ничто не мешает вам использовать команды vacuumdb и reindexdb, к примеру, если ваша организация небольшая и работает 5/2 или 6/1.

Полную очистку с анализом можно запускать раз в сутки, раз в неделю или даже месяц, в зависимости от того, как растет объем баз и растет ли вообще (при включенном и настроенном автовакууме). Все зависит именно от графика роста объема баз в зависимости от времени. Так что внимательно следите за тем, какой объем у баз был до запуска полной очистки и перестроения индексов, а какой стал после. Вдруг вы увидите, что в них нет смысла, поскольку объем баз после их выполнения не уменьшается.

Перестроение индексов также важно. Однако частота его запуска зависит в первую очередь от приложения. Если у вас желтый кружочек, благодаря разработчикам которого у нас в базе на 150 GB приходится 30 GB индексов, то их перестроение очень желательно запускать каждую неделю или чаще. Если же у вас нормальное приложение, разработанное людьми со здоровой головой, то можно запускать раз в несколько месяцев. Все также зависит от объема баз и нагрузки на них.

Ваша задача как администратора – следить в первую очередь за объемом баз, все остальное вторично и будет сделано благодаря autovacuum и pg_repack (или vacuumdb вместе с reindexdb).

На рисунке ниже я привел пример, где за 3 недели по дням отражен размер баз. Организация N работает по графику 5/2, размер баз замерялся ежедневно в 23:00. Красным отмечены дни, когда базы были очищены при помощи pg_repack. Синим отмечены дни, когда был отключен autovacuum. При включенном автовакууме скорость роста баз снизилась бы как минимум в 5 раз.

Вы как системный администратор обязаны собирать данные в подобном виде, чтобы у вас всегда на руках была готовая статистика с графиками для наглядности и понимания того, что вообще происходит. Разумеется, в идеале это все дело следует автоматизировать при помощи какой-либо системы мониторинга, а сбор статистики сделать не в конце рабочего дня, а, к примеру, по часам, и на протяжении года, а не трех недель. Ну и разумеется, у всех все будет по-разному, так что не следует считать рисунок выше применимым к вашему случаю.

WAL и checkpoint

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

WAL (Write-Ahead Logging или Write Ahead Log) – это журнал упреждающей (предварительной) записи.

Некоторые думают, что WAL и transaction logs это разные технологии. На самом деле эти два термина описывают технологии, выполняющие одну и ту же задачу. Просто они называются и устроены по-разному. В PostgreSQL – WAL, а в других СУБД может называться transaction logs.

Основная задача WAL – сохранение данных при сбое сервера. Именно тех данных, которые еще не успели записаться в БД. СУБД записывает данные параллельно и в WAL, и в БД. Потому что запись в БД более долгая, и при сбое изменения, которые еще не успели записаться в БД, будут потеряны. К примеру, если у вас внезапно отключили питание, то после перезагрузки физического сервера СУБД начнет восстановление данных из WAL.

Второй момент: данные WAL находятся в той же директории, в которой находятся БД, а конкретно – в поддиректории pg_wal. Нам не очень важно знать устройство файлов в ней. Просто имейте ввиду, что директория pg_wal всегда должна быть доступной и иметь достаточный объем свободного пространства.

Третий момент: WAL является общим для всего кластера. Просто имейте это ввиду. Его невозможно распределить для отдельных БД, для этого придется создавать множество кластеров по одной БД в каждом.

При восстановлении сначала считывается информация из самой БД, а только потом из WAL (что логично, потому что изменения из WAL более поздние). Разумеется, восстановление данных из WAL происходит гораздо дольше. А при восстановлении каждая сэкономленная секунда очень важна.

Изменения из WAL записываются в базу при помощи процесса checkpointer. Выше я упомянул, что изменения записываются и в WAL, и в БД параллельно, просто в первом случае запись гораздо быстрее. Чекпоинт нужен, чтобы время от времени освобождать место в WAL путем записи данных из него в БД, потому что иначе объем журнала вырастет, а в случае сбоя нам придется очень долго восстанавливать огромный объем дынных из WAL.

В основном конфигурационном файле postgresql.conf целый раздел посвящен WAL. Большинство значений можно оставить по умолчанию, с ними все нормально. Возможно, понадобится их изменить только при настройке системы резервного копирования или репликации.

Отмечу лишь несколько важных для нас параметров:

checkpoint_timeout

Определяет периодичность создания чекпоинта. По умолчанию – 5min, этого в принципе достаточно, однако можно выставить и меньше, чтобы снизить время восстановления, или больше, чтобы снизить нагрузку на дисковую подсистему. Но обычно рекомендуют задавать в диапазоне 30-60 минут.

max_wal_size

Определяет объем данных WAL, по достижению которого они чекпоинтом будут записаны в БД. По умолчанию задан 1 GB. Но зачем он нам, если у нас и так чекпоинт записывает изменения время от времени? Потому что за это самое время объем изменений может быть большим. К примеру, у нас чекпоинт работает с периодичностью 5 минут, и за 2 минуты WAL мог насобирать информации на 500 MB, но в случае сбоя сервера эти 500 MB еще могут не успеть записаться в БД, так что восстанавливать их из WAL придется долго. Можете задать значение меньше, к примеру, 100 MB, однако позже вы поймете, что это неправильно. Задавайте сразу побольше, 10 GB и более (берите с расчетом 3-5% от общего объема всех баз этого кластера). Также имейте ввиду, что это не жесткий лимит, и суммарный объем WAL может быть больше max_wal_size. Например, когда нагрузка на диск слишком большая, и чекпоинт не может записать данные из журнала в БД.

checkpoint_completion_target

Определяет текущую долю от max_wal_size, по достижении которой данные WAL будут записаны в БД. По умолчанию равен 0,5. К примеру, если max_wal_size равен 1 GB, а текущий объем WAL равен 512 MB, то данные WAL начнут записываться в БД. Почти везде рекомендуется задать значение 0,9, однако на самом деле все зависит от максимального объема журнала и периодичности создания чекпоинтов. Возможно, вы уже это поняли, и вам показалось, что параметр checkpoint_timeout действительно можно выставить в 1 день. Не делайте этого. За сутки изменений WAL может накопиться в 5-10 и более раз больше, чем объем самих баз в кластере, так что хранить все записи WAL очень накладно, но теоретически возможно.

Что касается самого параметра checkpoint_completion_target – то задавайте значение 0,1. То есть, если у вас максимальный объем журнала 30 GB, то чекпоинт начнет запись информации из журнала в базы по достижении 3 GB. Нет, вы, конечно, можете задать значение больше или меньше. И все знают, что системе проще записать один большой файл, чем много маленьких. Дело в первую очередь в равномерном распределении ресурсов, чтобы в случае пиковой нагрузки со стороны приложения вместе с записью чекпоинта производительность дисковой подсистемы не уперлась в потолок.

Дело также в скорости восстановления данных после сбоя. И здесь опять дилемма: увеличить нагрузку на диск, но при этом восстановится быстрее, или снизить нагрузку на диск, но восстанавливаться медленнее. Но если изменений не было и записывать нечего – то записывать нечего, и ресурсы дисковой подсистемы не будут использованы. Если у вас будет мало больших чекпоинтов, то в случае сбоя восстанавливаться вы будете дольше. Насколько дольше – зависит от объема WAL и кучи других факторов. Просчитать это невозможно.

Отмечу еще несколько параметров:

wal_compression – не рекомендую оставлять выключенным. Задавайте алгоритм zstd, он самый лучший. Учтите только, что сжатие относится именно к данным WAL, а не к базам. Возрастет ли время восстановления или, наоборот, уменьшится – зависит от вашей системы, однако в обоих случаях разница будет на уровне погрешности, если текущий объем WAL не превышает 5% от объема баз. Сжатие журнала просто позволяет освободить немного места не диске. Соответственно, чем больше объем журнала – тем больше пользы от сжатия.

wal_level – по умолчанию стоит значение replica, но лучше его задать явно. В старых версиях по умолчанию стояло minimal. Значение logical выставляйте, если оно вам действительно необходимо (к примеру, для какого-либо расширения), logical просто собирает больше данных, чем replica, то есть немного увеличивает нагрузку. Взамен мы получаем большую гибкость для логической репликации. Пока что не будем лезть в эти дебри. Просто учтите, что для наших задач достаточно значения replica. Но ни в коем случае не оставляйте minimal, оно, конечно, позволит вам восстановить сервер после сбоя, но вот про репликацию и бэкапы вы можете забыть.

fsync – всегда должно быть значение on. Если отключить, то производительность немного вырастет, однако восстановить данные вы не сможете. Десятки уровней кеша сделали свое дело.

full_page_writes – аналогично fsync, также всегда выставляем on.

ssl – тоже влияет на производительность. Коротко говоря, повышает безопасность и потребление ресурсов CPU. Рекомендую ознакомиться с этим механизмом в документации, потому что все зависит от того, как именно в вашей компании организована защита информации.

Итог

Остальные значения не рекомендую менять. Настройка других параметров, таких как min_wal_size также не имеет смысла из-за высокой производительности нынешних файловых систем и дисков (к примеру, проще удалить файл и создать новый, чем редактировать содержимое текущего или изменять его имя). У вас вряд ли будут настолько большие нагрузки, что неправильный подбор этих параметров уменьшит производительность более чем на 0,1%.

https://www.postgresql.org/docs/current/wal-configuration.html

https://www.enterprisedb.com/blog/postgresql-wal-write-ahead-logging-management-strategy-tradeoffs

https://www.enterprisedb.com/blog/basics-tuning-checkpoints

https://www.enterprisedb.com/blog/you-can-now-pick-your-favorite-compression-algorithm-your-wals

Логирование

Логи нужны трем типам людей:

Тем, кто вбивает команды бездумно, а только потом думает, что натворил.

Тем, кто не мониторит никакие из локальных систем и не может понять, почему ничего не работает.

Тем, кто хочет убедится, что все работает.

Все логи записываются в директорию по умолчанию /var/log/postgresql в файл для каждого отдельного кластера в виде:

postgresql-<cluster_version>-<cluster_name>.log

Узнать текущее расположение логов для кластера можно командой pg_lsclusters.

Следить необходимо только за сообщениями уровня FATAL и PANIC, все остальные – это просто вывод информации (об успешных или прерванных операциях, к примеру). Если что-то пошло не по плану, вы всегда можете обратиться к последним логам.

Параметры, которые необходимо задать в postgresql.conf:

logging_collector

Выставляем on. Позволяет снизить нагрузку на систему (запись логов тоже жрет ресурсы). И даже не снизить, а сделать так, чтобы процесс записи логов долго не висел и не отжирал ресурсы у процессов обработки запросов. Все ненужные сообщения будут записываться в сокращенном виде.

log_directory

Нужен, если вы хотите изменить директорию записи логов. Обычно, в нормальной инфраструктуре, все логи хранятся на одном выделенном сетевом ресурсе. Не забывайте только назначать отдельные директории для каждого приложения, а конкретно для PostgreSQL – еще и отдельные директории с версией и именем кластера, потому что кластеров у вас будет много.

log_filename

Изменяет имя файла логов. Не рекомендую менять, потому что потом запутаетесь.

log_timezone

Не трогать. Время и часовой пояс должны настраиваться отдельно. Просто смотрите, чтобы была правильная временная зона. Если же нет, то вы накосячили с ее настройкой.

log_connections и log_disconnections

Рекомендую включить (выставить 1). По умолчанию они отключены, но могут быть полезны, особенно для разработчиков. Только готовьтесь к тому, что в логи будет записана вообще вся информация обо всех удачных и неудачных подключениях. Если вы логи просматриваете самостоятельно – то лучше не включайте.

log_statement

Этот параметр также выел мне весь мозг, прямо как shared_buffers. Единого решения нет. В общем, если у вас идет разработка или очень высокие требования к безопасности – то ставьте all. Если обычная продуктивная система – то mod, он сильно снизит нагрузку. Ставить ли значения off и ddl – не знаю. В них просто нет смысла, они уже не так сильно снижают потребление ресурсов.

log_min_messages и log_min_error_statement

Оставляйте, их значения по умолчанию WARNING и ERROR нас устраивают.

log_error_verbosity

Оставляйте standard. Другие значения будут полезны только разработчикам.

log_rotation_age и log_rotation_size

Логи не записываются в один большой файл. Они создаются автоматически каждый раз, когда проходит время log_rotation_age или файл становится больше log_rotation_size. По умолчанию их значения равны 24 часам и 10 магабайтам соответственно. То есть, у вас как минимум один раз в сутки создается новый файл (или когда в течение одних суток размер файла превысит 10 MB). Можете оставить значение времени по умолчанию или в течение одной недели (не забудьте только изменить маску файла). Менять максимальный размер не имеет большого смысла, 10 MB хватит за глаза.

Главное, не выставляйте значения 0, а то логи у вас будут храниться вечно в одном огромном файле.

Но есть одна проблема: поскольку это логи, то файлы не удаляются автоматически никогда. Вы можете их удалять вручную или добавить скрипт в cron. Но в целом они не занимают так много места, чтобы их пришлось когда-либо удалять. Помните только, что их объем напрямую зависит от настроек.

Например, в Ubuntu есть интересная утилита для ротации логов.

https://manpages.ubuntu.com/manpages/noble/man8/logrotate.8.html

Если у вас множество серверов, то из бесплатных систем анализа логов конкретно для PostgreSQL есть pgBadger, либо вы можете использовать что-либо свое, потому что все это проверять вручную вы просто не сможете.

https://www.postgresql.org/docs/current/runtime-config-logging.html

https://github.com/darold/pgbadger

Третья часть:
https://habr.com/ru/articles/843076/

Комментарии (1)


  1. erogov
    14.09.2024 20:02

    Вам уже советовали RTFM в первой статье, ну ещё раз посоветую — почитайте про контрольные точки, чтобы не писать такое:

    Чекпоинт нужен, чтобы время от времени освобождать место в WAL путем записи данных из него в БД

    А совет выставить checkpoint_completion_target в 0.1 не приведет ни к чему, кроме пиковых нагрузок на ввод-вывод.