×
Мы обрабатываем cookies, чтобы сделать наш сайт удобнее и персонализированнее для вас. Подробнее: политика использования «cookies» и «политики конфиденциальности».

Для самостоятельной настройки ознакомьтесь с инструкцией

Дополнительные настройки cookies в браузерах

Файлы cookie автоматически загружаются в ваш браузер при посещении веб-сайта. У вас есть возможность управлять этими файлами. Если Вы не согласны с использованием файлов cookies, запретите их сохранение на своём устройстве, удалите уже имеющиеся файлы cookies через настройки браузера или прекратите использование сайта.

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

Инструкция по отключению cookies
Принять
Настроить
Отклонить

ДОКУМЕНТАЦИЯ

Выберите версию, форк и язык для СУБД Digital Q.DataBase, чтобы прочитать или скачать всю документацию.
Техподдержка
Документация
Диасофт
Авторские права © 2016–2025 ООО "Диасофт Экосистема"
Скачать всю документацию:

3.9.1. Регулярная очистка

3.9.1.1. Основные сведения об очистке
3.9.1.2. Освобождение дискового пространства
3.9.1.3. Обновление статистики планировщика
3.9.1.4. Обновление карты видимости
3.9.1.5. Предотвращение сбоев, связанных с зацикливанием идентификаторов транзакций
3.9.1.6. Автоочистка

Digital Q.DataBase базы данных требуют периодического обслуживания, называемого vacuuming. Во многих случаях достаточно того, чтобы очистка выполнялась демоном автоочистки, описание которого приведено в Раздел 3.9.1.6. Для достижения наилучших результатов может потребоваться корректировка параметров автоочистки, описанных в соответствующем разделе. Некоторые администраторы баз данных предпочитают дополнять или заменять работу фонового процесса операциями, управляемыми вручную VACUUM командами, которые обычно выполняются по расписанию с помощью cron или Планировщика задач скриптов. Для корректной настройки очистки вручную необходимо изучить вопросы, рассматриваемые в следующих подразделах. Администраторам, использующим механизм автоочистки, также рекомендуется ознакомиться с данным материалом для понимания принципов работы и настройки параметров автоочистки.

3.9.1.1. Основные сведения об очистке #

В Digital Q.DataBase команда VACUUM должна регулярно обрабатывать каждую таблицу по нескольким причинам:

  1. Для освобождения или повторного использования дискового пространства, занятого измененными или удаленными строками.
  2. Для обновления статистических данных, используемых Digital Q.DataBase планировщиком запросов.
  3. Для обновления карты видимости, ускоряющей сканирование только по индексу.
  4. Для защиты от потери устаревших данных вследствие зацикливания идентификаторов транзакций или multixact ID wraparound.

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

Существует два варианта операции VACUUM: стандартная очистка VACUUM и VACUUM FULL. VACUUM FULL позволяет высвободить больше дискового пространства, но выполняется значительно медленнее. Кроме того, стандартная форма VACUUM может выполняться параллельно с обычными операциями в базе данных. (Команды SELECT, INSERT, UPDATEи DELETE продолжат работать в штатном режиме, однако изменение определения таблицы с помощью таких команд, как ALTER TABLE во время выполнения очистки.) VACUUM FULL требует ACCESS EXCLUSIVE блокировки таблицы, с которой производится работа, и, следовательно, не может выполняться параллельно с другим использованием этой таблицы. Как правило, администраторам следует стремиться к использованию стандартной функции VACUUM и избегать VACUUM FULL.

VACUUM создает значительный объем трафика ввода-вывода, что может привести к снижению производительности других активных сеансов. Существуют параметры конфигурации, которые можно настроить для снижения влияния механизма фоновой очистки на производительность — см. Раздел 3.4.4.4.

3.9.1.2. Освобождение дискового пространства #

В Digital Q.DataBase, UPDATE или DELETE строки не приводит к немедленному удалению ее старой версии. Данный подход необходим для обеспечения преимуществ многоверсионного управления конкурентным доступом (MVCC, см. Глава 2.10): версия строки не должна удаляться, пока она остается потенциально видимой для других транзакций. Но со временем устаревшая или удаленная версия строки перестает использоваться какими-либо транзакциями. Занимаемое ею место должно быть возвращено для повторного использования новыми строками во избежание неограниченного роста потребностей в дисковом пространстве. Это выполняется путем запуска VACUUM.

Стандартная форма команды VACUUM удаляет версии «мертвых» строк в таблицах и индексах и помечает освободившееся пространство как доступное для повторного использования. Однако она не возвращает пространство операционной системе, за исключением особых случаев, когда одна или несколько страниц в конце таблицы становятся полностью свободными и появляется возможность легко получить исключительную блокировку таблицы. В отличие от этого, VACUUM FULL активно уплотняет таблицы путем записи полностью новой версии файла таблицы без пустого пространства. Это минимизирует размер таблицы, но может занять много времени. Кроме того, до завершения операции требуется дополнительное дисковое пространство для хранения новой копии таблицы.

Обычной целью регламентной очистки является выполнение стандартной функции VACUUMs достаточно часто, чтобы избежать необходимости вызова VACUUM FULL. Демон автоочистки настроен на работу именно в таком режиме и фактически никогда не инициирует выполнение команды VACUUM FULL. При таком подходе основная задача состоит не в удержании таблиц на уровне их минимального размера, а в поддержании стабильного потребления дискового пространства: каждая таблица занимает объем, эквивалентный ее минимальному размеру плюс то пространство, которое заполняется в промежутках между запусками очистки. Хотя VACUUM FULL может использоваться для сжатия таблицы до её минимального размера и возврата дискового пространства операционной системе, однако в этом мало смысла, если в будущем таблица снова вырастет. Таким образом, умеренно частое выполнение стандартной очистки VACUUM является более эффективным подходом, чем редкое выполнение VACUUM FULL для обслуживания интенсивно обновляемых таблиц.

Некоторые администраторы предпочитают настраивать расписание очистки самостоятельно, например, выполняя все работы ночью при низкой нагрузке. Трудность выполнения очистки по фиксированному расписанию заключается в том, что при неожиданном всплеске активности обновлений таблица может раздуться до такой степени, что VACUUM FULL становится действительно необходимой для высвобождения места. Использование демона автоочистки позволяет решить эту проблему, так как демон планирует задачи очистки динамически, реагируя на интенсивность обновлений. Не рекомендуется полностью отключать демон автоочистки, если только характер рабочей нагрузки не является крайне предсказуемым. Одним из возможных компромиссных решений является такая настройка параметров демона, при которой он будет реагировать только на аномально высокую активность обновлений, предотвращая критическое разрастание таблиц, в то время как плановая VACUUMдолжны выполнять основной объем работы при типичной нагрузке.

Для тех, кто не использует функцию автоочистки, стандартным подходом является планирование очистки всей базы данных VACUUM один раз в день в период минимальной нагрузки с дополнительным, более частым вакуумированием интенсивно обновляемых таблиц по мере необходимости. (В некоторых системах с чрезвычайно высокой интенсивностью обновлений очистка наиболее нагруженных таблиц может выполняться раз в несколько минут). Если в кластере имеется несколько баз данных, не забудьте обработать VACUUM каждую из них; использование программы vacuumdb может быть полезным.

Подсказка

Обычная операция VACUUM может оказаться неэффективной, если таблица содержит большое количество устаревших версий строк («мертвых строк») в результате массовых операций обновления или удаления. Если у вас есть такая таблица и вам необходимо освободить избыточное дисковое пространство, которое она занимает, потребуется использовать VACUUM FULL, либо CLUSTER или один из вариантов пересоздания таблицы с помощью команды ALTER TABLE. Данные команды полностью перезаписывают таблицу и перестраивают её индексы. Все эти операции требуют захвата ACCESS EXCLUSIVE блокировки. Обратите внимание, что для их выполнения также временно требуется дополнительное дисковое пространство, объем которого сопоставим с размером таблицы, так как старые копии таблицы и индексов невозможно освободить до завершения создания новых.

Подсказка

Если в таблице периодически удаляется всё содержимое, рекомендуется использовать команду TRUNCATE вместо вызова DELETE с последующим выполнением VACUUM. TRUNCATE немедленно удаляет всё содержимое таблицы, что исключает необходимость последующего вызова команды VACUUM или VACUUM FULL для возврата неиспользуемого дискового пространства. Недостатком данного метода является нарушение строгой семантики MVCC.

3.9.1.3. Обновление статистики планировщика #

Функция Digital Q.DataBase планировщик запросов использует статистические данные о содержимом таблиц для формирования оптимальных планов выполнения запросов. Сбор данной статистики осуществляется командой ANALYZE команда, которая может быть вызвана отдельно или как необязательный этап в VACUUM. Поддержание актуальности статистических данных имеет важное значение, поскольку выбор неоптимальных планов может привести к снижению производительности базы данных.

Демон автоочистки (если он включен) будет автоматически инициировать выполнение ANALYZE в тех случаях, когда содержимое таблицы претерпевает существенные изменения. Тем не менее, администраторы могут предпочесть использование планируемых вручную ANALYZE операций, особенно если известно, что операции обновления в таблице не повлияют на статистику «целевых» столбцов. Демон планирует выполнение ANALYZE исключительно на основании количества добавленных или обновленных строк; он не учитывает, приведет ли это к существенным изменениям статистических данных.

Изменение кортежей в секциях и дочерних таблицах при наследовании не инициирует автоматический сбор статистики (analyze) для родительской таблицы. Если родительская таблица пуста или редко обновляется, она может никогда не быть обработана демоном автоочистки, вследствие чего статистика для всего дерева наследования не будет собрана. Необходимо выполнять ANALYZE операцию для родительской таблицы вручную, чтобы поддерживать актуальность статистических данных.

Как и в случае с очисткой (vacuuming) для высвобождения места, частое обновление статистики более эффективно для таблиц с интенсивным изменением данных, нежели для редко обновляемых таблиц. Однако даже при интенсивном изменении данных в таблице необходимость в обновлении статистики может отсутствовать, если статистическое распределение данных меняется незначительно. Согласно простому эмпирическому правилу, следует оценить степень изменения минимальных и максимальных значений в столбцах таблицы. Например, столбец типа timestamp , в котором фиксируется время обновления строки, будет иметь постоянно растущее максимальное значение по мере добавления и изменения записей; для такого столбца, вероятно, потребуется более частое обновление статистики, чем, например, для столбца, содержащего URL-адреса посещенных веб-страниц. Данные в столбце с URL-адресами могут обновляться так же часто, но статистическое распределение его значений, скорее всего, меняется относительно медленно.

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

Подсказка

Хотя индивидуальная настройка частоты ANALYZE для каждого столбца может быть малоэффективной, целесообразно рассмотреть возможность настройки уровня детализации статистики, собираемой механизмом ANALYZE. Для столбцов, которые активно используются в WHERE условиях и характеризуются крайне неравномерным распределением данных, может потребоваться более детальная гистограмма, чем для других столбцов. См. ALTER TABLE SET STATISTICS, или измените значение по умолчанию для всей базы данных, используя default_statistics_target параметр конфигурации.

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

Подсказка

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

Подсказка

Демон автоочистки не инициирует выполнение ANALYZE команд для партиционированных таблиц. Родительские таблицы в иерархии наследования анализируются только при изменении самой родительской таблицы: изменения в дочерних таблицах не инициируют автоматический сбор статистики (autoanalyze) для родительской таблицы. Если для корректного планирования запросов требуются статистические данные по родительским таблицам, необходимо периодически выполнять операцию ANALYZE на таких таблицах вручную для поддержания актуальности статистики.

3.9.1.4. Обновление карты видимости #

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

Во-вторых, это позволяет Digital Q.DataBase отвечать на некоторые запросы, используя только индекс, без обращения к исходной таблице. Поскольку Digital Q.DataBase индексы не содержат информации о видимости кортежей, при обычном сканировании индекса для каждой найденной записи извлекается кортеж из кучи (heap), чтобы проверить, должен ли он быть виден в рамках текущей транзакции. Исключительно индексное сканирование, напротив, сначала проверяет карту видимости. Если известно, что все кортежи на странице видимы, обращение к куче можно пропустить. Данный механизм наиболее эффективен при работе с большими наборами данных, когда карта видимости позволяет исключить обращения к диску. Карта видимости значительно меньше основного хранилища (кучи), поэтому она легко кэшируется даже при очень больших размерах таблиц.

3.9.1.5. Предотвращение сбоев, связанных с зацикливанием идентификаторов транзакций #

Digital Q.DataBaseкоманды MVCC функционирование семантики транзакций основано на возможности сравнения идентификаторов транзакций (XID): версия строки, имеющая XID вставки больше, чем XID текущей транзакции, относится к «будущему периоду» и не должна быть видима в текущей транзакции. Однако ввиду ограниченности размера идентификатора транзакции (32 бита), в кластере, работающем непрерывно в течение долгого времени (более 4 миллиардов транзакций), может произойти зацикливание идентификаторов транзакций: значение счетчика XID сбрасывается в ноль, вследствие чего транзакции из прошлого ошибочно воспринимаются как транзакции из будущего — в результате чего содержащиеся в них данные становятся невидимыми. Говоря кратко, это приведет к катастрофической потере данных (на самом деле данные сохраняются, но это не имеет значения, если к ним невозможно получить доступ). Во избежание этой ситуации необходимо выполнять вакуумирование каждой таблицы во всех базах данных как минимум один раз на каждые два миллиарда транзакций.

Причина, по которой периодическая очистка решает данную проблему, заключается в том, что механизм VACUUM помечает строки как «замороженные», указывая на то, что они были вставлены транзакцией, зафиксированной достаточно давно, чтобы результаты этой транзакции гарантированно были видны всем текущим и будущим транзакциям. Сравнение обычных идентификаторов XID выполняется с использованием арифметики по модулю 232 arithmetic. Это означает, что для каждого обычного XID существует два миллиарда «более старых» и два миллиарда «более новых»; идентификаторов XID; иначе говоря, пространство обычных XID является циклическим и не имеет конечной точки. Следовательно, если версия строки была создана с определенным обычным XID, она будет восприниматься как «в прошлом» для следующих двух миллиардов транзакций, независимо от того, о каком обычном идентификаторе транзакции (XID) идёт речь. Если версия строки всё ещё существует по прошествии более двух миллиардов транзакций, она внезапно окажется в будущем. Для предотвращения этой ситуации Digital Q.DataBase резервируется специальный идентификатор транзакции (XID) — FrozenTransactionId, который не подчиняется обычным правилам сравнения XID и всегда считается более старым, чем любой обычный XID. Замороженные версии строк обрабатываются так, как если бы вставляющий XID имел значение FrozenTransactionId, что делает их «в прошлом» для всех обычных транзакций независимо от проблем с закольцовыванием (wraparound), и такие версии строк остаются действительными до тех пор, пока не будут удалены.

Примечание

В Digital Q.DataBase В версиях до 9.4 механизм заморозки реализовывался посредством замены XID вставки строки на FrozenTransactionId, что отображалось в системном столбце xmin system column. В более новых версиях просто устанавливается бит флага, при этом сохраняется исходный xmin для возможного последующего анализа. Однако строки с xmin равным FrozenTransactionId (2) всё ещё могут встречаться в базах данных, pg_upgradeперенесённых с версий до 9.4.

Кроме того, системные каталоги могут содержать строки с xmin равным BootstrapTransactionId (1), указывающим на то, что они были вставлены на первом этапе работы initdb. Как и FrozenTransactionId, этот специальный XID считается более старым, чем любой обычный XID.

vacuum_freeze_min_age определяет возраст значения XID, при достижении которого строки с этим XID будут заморожены. Увеличение значения данного параметра позволяет избежать избыточных операций, если строки, подлежащие заморозке, вскоре будут изменены снова, но уменьшение этого значения увеличивает число транзакций, которые могут быть выполнены до того, как потребуется очередная очистка таблицы.

VACUUM использует карту видимости для определения того, какие страницы таблицы необходимо просканировать. Обычно данный механизм пропускает страницы, не содержащие «мертвых» версий строк, даже если на этих страницах могут оставаться версии строк со старыми значениями XID. Таким образом, обычная VACUUMочистка не всегда выполняет заморозку каждой старой версии строки в таблице. В таких случаях VACUUM со временем потребуется выполнение операции агрессивное вакуумирование, в ходе которой будут заморожены все подходящие незамороженные значения XID и MXID, включая значения на полностью видимых (all-visible), но не полностью замороженных (not all-frozen) страницах. На практике для большинства таблиц требуется периодическое проведение агрессивной очистки. vacuum_freeze_table_age управляет моментом, когда VACUUM выполняет данную операцию: полностью видимые, но не полностью замороженные страницы сканируются, если количество транзакций, совершенных с момента последнего аналогичного сканирования, превышает значение vacuum_freeze_table_age за вычетом vacuum_freeze_min_age. Установка параметра vacuum_freeze_table_age в значение 0 принудительно заставляет механизм VACUUM всегда использовать агрессивную стратегию.

Максимальный период, в течение которого таблица может оставаться без очистки, составляет два миллиарда транзакций минус значение vacuum_freeze_min_age на момент последнего агрессивного вакуумирования. Если процедура очистки не будет выполнена в течение более длительного срока, возможна потеря данных. Для предотвращения подобной ситуации механизм автоочистки вызывается для любой таблицы, которая может содержать незамороженные строки с XID, возраст которых превышает значение, установленное параметром конфигурации autovacuum_freeze_max_age. (Это будет происходить даже в том случае, если механизм автоочистки отключен.)

Это означает, что если очистка таблицы не выполняется иным способом, механизм автоочистки будет запущен для неё примерно один раз на каждые autovacuum_freeze_max_age за вычетом vacuum_freeze_min_age транзакций. Для таблиц, в которых регулярно выполняется очистка для возврата свободного места, данный аспект не имеет существенного значения. Однако для статических таблиц (включая те таблицы, в которых выполняются операции вставки, но не обновления или удаления) необходимость в очистке для повторного использования места отсутствует, поэтому целесообразно максимально увеличить интервал между принудительными запусками автоочистки для очень больших статических таблиц. Очевидно, что этого можно добиться либо путем увеличения autovacuum_freeze_max_age или уменьшение параметра vacuum_freeze_min_age.

Эффективное максимальное значение для vacuum_freeze_table_age составляет 0.95 * autovacuum_freeze_max_age; значение выше указанного будет ограничено максимально допустимым. Установка значения выше чем autovacuum_freeze_max_age не имеет смысла, так как в этой точке в любом случае будет запущена автоочистка для предотвращения зацикливания (anti-wraparound), а множитель 0.95 оставляет определенный запас времени для выполнения ручной VACUUM до того, как это произойдет. Как правило, vacuum_freeze_table_age следует устанавливать в значение несколько ниже, чем autovacuum_freeze_max_age, оставляя достаточный интервал для того, чтобы регулярно планируемая VACUUM или автоочистка, инициируемая стандартными операциями удаления и обновления данных, выполнялась в данном окне. Установка слишком близкого значения может привести к запускам автоочистки для предотвращения зацикливания, даже если таблица недавно подвергалась очистке для высвобождения места, тогда как более низкие значения приводят к более частому выполнению агрессивной очистки.

Единственным недостатком увеличения параметра autovacuum_freeze_max_agevacuum_freeze_table_age вместе с ним) является то, что pg_xact и pg_commit_ts подкаталоги кластера базы данных будут занимать больше места, так как в них должны храниться статус фиксации и (если track_commit_timestamp включена) метки времени всех транзакций вплоть до autovacuum_freeze_max_age событий. Для хранения статуса фиксации используется два бита на транзакцию, поэтому если параметр autovacuum_freeze_max_age установлен в максимально допустимое значение (два миллиарда), pg_xact может вырасти примерно до 500 МБ, а pg_commit_ts — примерно до 20 ГБ. Если этот объем незначителен относительно общего размера базы данных, рекомендуется установить для параметра autovacuum_freeze_max_age рекомендуется устанавливать максимально допустимое значение данного параметра. В противном случае установите его в зависимости от допустимого объема дискового пространства для pg_xact и pg_commit_ts хранения данных. (Значение по умолчанию, 200 миллионов транзакций, соответствует примерно 50 МБ для pg_xact и примерно 2 ГБ для pg_commit_ts данных.)

Недостаток уменьшения значения параметра vacuum_freeze_min_age заключается в том, что это может привести к выполнению механизмом VACUUM избыточной работы: замораживание версии строки нецелесообразно, если вскоре после этого строка будет изменена (что приведет к получению нового XID). Следовательно, значение параметра должно быть достаточно большим, чтобы строки не замораживались до тех пор, пока сохраняется высокая вероятность их изменения.

Для отслеживания возраста старейших незамороженных идентификаторов транзакций (XID) в базе данных VACUUM сохраняет статистику XID в системных таблицах pg_class и pg_database. В частности, параметр relfrozenxid в столбце pg_class соответствующей строки таблицы содержит старейший из оставшихся незамороженных XID по завершении последней операции VACUUM которая обеспечила успешное продвижение relfrozenxid (как правило, последней агрессивной очистки VACUUM). Аналогичным образом, datfrozenxid в столбце pg_database строки базы данных является нижней границей для незамороженных XID, используемых в этой базе данных — это минимальное из всех значений relfrozenxid в пределах данной базы данных. Для получения этой информации удобно использовать следующие запросы:

SELECT c.oid::regclass as table_name,
       greatest(age(c.relfrozenxid),age(t.relfrozenxid)) as age
FROM pg_class c
LEFT JOIN pg_class t ON c.reltoastrelid = t.oid
WHERE c.relkind IN ('r', 'm');

SELECT datname, age(datfrozenxid) FROM pg_database;

Параметр age содержит количество транзакций от граничного значения XID до XID текущей транзакции.

Подсказка

Когда для VACUUM команды VERBOSE VACUUM выводятся различные статистические данные о таблице. Эта информация включает сведения о том, как relfrozenxid и relminmxid продвинулись вперед, а также количество вновь замороженных страниц. Те же подробности записываются в журнал сервера, когда механизм ведения журнала автоочистки (управляемый параметром log_autovacuum_min_duration) сообщает об VACUUM операции, выполненной процессом автоочистки.

VACUUM обычно сканирует только те страницы, которые были изменены с момента последней очистки, однако значение relfrozenxid может быть продвинуто только при сканировании всех страниц таблицы, которые могут содержать незамороженные XID. Это происходит, когда значение relfrozenxid превышает vacuum_freeze_table_age старых транзакций, когда VACUUM's FREEZE используется данная опция или когда все страницы, не помеченные как полностью замороженные, требуют очистки для удаления «мертвых» версий строк. Когда VACUUM сканирует каждую страницу в таблице, которая еще не была полностью заморожена, он должен установить age(relfrozenxid) в значение, лишь немного превышающее vacuum_freeze_min_age использованное значение параметра (в большей степени числом транзакций, инициированных с момента VACUUM начался). VACUUM установит relfrozenxid значение самого старого XID, остающегося в таблице, поэтому итоговое значение может оказаться гораздо более новым, чем строго требуется. Если никакая relfrozenxidпродвигающая VACUUM операция не будет выполнена для таблицы до достижения порога autovacuum_freeze_max_age , для этой таблицы вскоре будет принудительно запущена процедура автоочистки.

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

ПРЕДУПРЕЖДЕНИЕ:  база данных "mydb" должна быть очищена в течение 39985967 транзакций
ПОДСКАЗКА:  Во избежание сбоев при назначении XID выполните операцию VACUUM во всей базе данных.

(Выполняемая вручную VACUUM должна решить проблему, согласно приведенной подсказке; однако следует учитывать, что VACUUM должна инициироваться суперпользователем, иначе не удастся обработать системные каталоги, что не позволит продвинуть datfrozenxid.) Если данные предупреждения игнорируются, система перестанет назначать новые XID, как только до момента закольцовывания останется менее трех миллионов транзакций:

ОШИБКА:  база данных не принимает команды, назначающие новые XID, во избежание потери данных из-за закольцовывания в базе данных "mydb"
ПОДСКАЗКА:  Выполните операцию VACUUM во всей базе данных.

В данном состоянии любые уже выполняющиеся транзакции могут быть продолжены, но запуск новых транзакций возможен только в режиме «только чтение». Операции, изменяющие записи базы данных или усекающие отношения, будут завершаться ошибкой. Параметр VACUUM команда по-прежнему может быть выполнена в обычном режиме. Обратите внимание, что вопреки рекомендациям, приводимым в предыдущих выпусках, для восстановления нормальной работы не требуется и не рекомендуется останавливать процесс postmaster или переходить в однопользовательский режим. Вместо этого выполните следующие действия:

  1. Завершите старые подготовленные транзакции. Их можно найти, проверив представление pg_prepared_xacts на наличие строк, в которых значение age(transactionid) является большим. Такие транзакции должны быть зафиксированы или откачены.
  2. Завершите длительные открытые транзакции. Их можно найти, проверив представление pg_stat_activity на наличие строк, в которых значение age(backend_xid) или age(backend_xmin) имеет большое значение. Такие транзакции должны быть зафиксированы или откачены, либо сеанс может быть завершен с помощью функции pg_terminate_backend.
  3. Удалите все старые слоты репликации. Используйте представление pg_stat_replication для поиска слотов, в которых age(xmin) или age(catalog_xmin) имеет большой размер. Во многих случаях такие слоты создавались для репликации на серверы, которые более не существуют или были отключены в течение длительного времени. Если удалить слот для сервера, который все еще существует и может попытаться подключиться к этому слоту, такую реплику, возможно, потребуется создать заново.
  4. Выполните команду VACUUM в целевой базе данных. Очистка VACUUM всей базы данных — наиболее простой вариант; для сокращения требуемого времени также возможно выполнение команд VACUUM вручную для тех таблиц, в которых параметр relminxid является наиболее старым. Не используйте VACUUM FULL в данном сценарии, так как это требует идентификатора транзакции (XID) и приведет к ошибке, за исключением режима суперпользователя, в котором команда потребит XID и увеличит риск зацикливания идентификатора транзакции зацикливание. Не используйте VACUUM FREEZE эту команду, так как это приведет к выполнению объема работ, превышающего необходимый минимум для восстановления нормального функционирования.
  5. После восстановления нормального функционирования убедитесь, что механизм автоочистки правильно настроен в целевой базе данных во избежание повторных проблем.

Примечание

В ранних версиях иногда требовалось остановить postmaster и запустить VACUUM базу данных в однопользовательском режиме. В типичных сценариях это более не требуется, и этого следует по возможности избегать, так как это требует остановки системы. Это также более рискованно, поскольку при этом отключаются защитные механизмы от зацикливания идентификаторов транзакций, предназначенные для предотвращения потери данных. Единственной причиной для использования однопользовательского режима в данном сценарии является необходимость выполнить TRUNCATE или DROP лишних таблиц, чтобы избежать необходимости выполнять их VACUUM очистку. Запас прочности в три миллиона транзакций предусмотрен для того, чтобы администратор мог выполнить эти действия. См. postgres справочную страницу для получения подробных сведений об использовании однопользовательского режима.

3.9.1.5.1. Мультитранзакции и закольцовывание #

Идентификаторы мультитранзакций используются для обеспечения блокировки строк несколькими транзакциями. Так как место в заголовке кортежа для хранения информации о блокировках ограничено, эта информация кодируется как «составной идентификатор транзакции», или сокращенно multixact ID, в тех случаях, когда строку одновременно блокируют несколько транзакций. Информация о том, какие именно идентификаторы транзакций входят в конкретный multixact ID, хранится отдельно в pg_multixact подкаталоге, и только идентификатор мультитранзакции фигурирует в xmax поле заголовка кортежа. Как и идентификаторы транзакций, идентификаторы мультитранзакций реализованы в виде 32-разрядного счетчика и соответствующего хранилища, что требует тщательного управления механизмом устаревания, очистки хранилища и обработки закольцовывания (wraparound). Существует отдельная область хранения для списка участников каждой мультитранзакции, в которой также используется 32-разрядный счетчик и которой также необходимо управлять.

Всякий раз, когда VACUUM сканирует любую часть таблицы, он заменяет любые встреченные идентификаторы мультитранзакций (multixact ID), возраст которых превышает значение vacuum_multixact_freeze_min_age на другое значение, в качестве которого может выступать нулевое значение, одиночный идентификатор транзакции или более новый идентификатор мультитранзакции. Для каждой таблицы pg_class.relminmxid сохраняет минимально возможный идентификатор мультитранзакции, который все еще встречается в кортежах этой таблицы. Если это значение старше, чем vacuum_multixact_freeze_table_age, инициируется принудительная агрессивная очистка. Как указано в предыдущем разделе, агрессивная очистка означает, что будут пропущены только те страницы, которые заведомо являются полностью замороженными (all-frozen). mxid_age() может применяться к pg_class.relminmxid для определения их возраста.

Агрессивная VACUUMочистка, независимо от причин ее вызова, гарантирует возможность продвижения параметра таблицы relminmxid. Со временем, по мере того как сканируются все таблицы во всех базах данных и обновляются их старейшие значения multixact, место на диске, занятое устаревшими данными multixact, может быть освобождено.

В качестве защитного механизма для любой таблицы, чей возраст мультитранзакций (multixact-age) превышает установленный предел, будет инициироваться процедура агрессивной очистки. autovacuum_multixact_freeze_max_age. Кроме того, если объем данных, занимаемый участниками мультитранзакций, превышает 2 ГБ, агрессивная очистка будет проводиться чаще для всех таблиц, начиная с тех, которые имеют наибольшее значение multixact-age. Оба этих типа агрессивной очистки будут выполняться даже в том случае, если механизм автоочистки (autovacuum) формально отключен.

Как и в случае с идентификаторами транзакций (XID), если функции автоочистки не удастся удалить старые MXID из таблицы, система начнет выводить предупреждения, когда старейшим MXID в базе данных останется сорок миллионов транзакций до точки зацикливания. Аналогично ситуации с XID, если эти предупреждения будут проигнорированы, система прекратит генерацию новых MXID, как только до точки зацикливания останется менее трех миллионов значений.

Штатный режим работы при исчерпании MXID восстанавливается так же, как и при исчерпании XID. Выполните действия, описанные в предыдущем разделе, учитывая следующие отличия:

  1. Активные и подготовленные транзакции можно игнорировать, если отсутствует вероятность их вхождения в мультитранзакции (multixact).
  2. Сведения о MXID не отображаются напрямую в системных представлениях, таких как pg_stat_activity; однако поиск устаревших XID по-прежнему остается эффективным способом определения транзакций, вызывающих проблемы с круговым переполнением MXID.
  3. Исчерпание лимита XID блокирует все транзакции на запись, в то время как исчерпание MXID блокирует лишь подмножество транзакций записи, в частности те, которые используют блокировки строк, требующие формирования MXID.

3.9.1.6. Автоочистка #

Digital Q.DataBase имеет необязательную, но крайне рекомендуемую функцию автоочистки, предназначенную для автоматизации выполнения VACUUM и ANALYZE команд. При включении данный механизм проверяет таблицы, в которых было добавлено, изменено или удалено большое количество кортежей. Для этих проверок используется средство сбора статистики; следовательно, работа автоочистки возможна только при условии, если параметр track_counts имеет значение true. В конфигурации по умолчанию функция автоочистки включена, а соответствующие параметры конфигурации настроены надлежащим образом.

Функция «автоочистки» фактически состоит из нескольких процессов. Существует постоянно работающий процесс демона, называемый процессом запуска автоочистки, отвечающий за запуск рабочих процессов автоочистки для всех баз данных. Механизм запуска распределяет нагрузку во времени, пытаясь инициировать по одному рабочему процессу для каждой базы данных каждые autovacuum_naptime секунд. (Следовательно, если в экземпляре имеется N баз данных, новый рабочий процесс будет запускаться каждые autovacuum_naptime/N секунд.) Одновременно autovacuum_max_workers может быть запущено не более заданного количества рабочих процессов. Если количество баз данных превышает autovacuum_max_workers баз данных для обработки; следующая база данных будет обработана, как только первый рабочий процесс завершит выполнение. Каждый рабочий процесс проверяет все таблицы в своей базе данных и выполняет VACUUM и/или ANALYZE по мере необходимости. log_autovacuum_min_duration можно использовать для мониторинга активности рабочих процессов автоочистки.

Примечание

В Digital Q.DataBase также есть возможность использовать параметр qdb_autovacuum_max_db_workers, позволяющий задать максимальное количество процессов автоочистки для конкретной базы данных. Установить конкретное значение можно с помощью команды

ALTER DATABASE SET qdb_autovacuum_max_db_workers = N;

где N — максимальное количество процессов автоочистки для базы данных db_name. По умолчанию установлено значение 0 (ограничений нет). Параметр необходимо устанавливать для каждой базы данных отдельно.

Если за короткий промежуток времени критериям очистки начинают соответствовать сразу несколько больших таблиц, все рабочие процессы автоочистки могут быть заняты их обработкой в течение длительного времени. В результате очистка остальных таблиц и баз данных будет отложена до тех пор, пока не освободится рабочий процесс. Количество рабочих процессов в одной базе данных не ограничено, однако они стремятся избегать повторного выполнения работы, уже проделанной другими процессами. Обратите внимание, что количество запущенных рабочих процессов не влияет на max_connections или superuser_reserved_connections лимиты.

Таблицы, чье relfrozenxid значение превышает autovacuum_freeze_max_age транзакций, всегда проходят процедуру очистки (это также относится к таблицам, для которых значение freeze max age было переопределено через параметры хранения; см. ниже). В противном случае, если число кортежей, ставших неактуальными с момента последней VACUUM превышает «порог очистки», выполняется очистка таблицы. Порог очистки определяется следующим образом:

порог очистки = базовый порог очистки + коэффициент очистки * количество кортежей

где базовый порог очистки — это autovacuum_vacuum_threshold, коэффициент очистки — это autovacuum_vacuum_scale_factor, а количество кортежей — это pg_class.reltuples.

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

порог очистки по вставкам = базовый порог очистки по вставкам + коэффициент очистки по вставкам * количество кортежей

где базовый порог очистки по вставкам — это autovacuum_vacuum_insert_threshold, а коэффициент очистки по вставкам — это autovacuum_vacuum_insert_scale_factor. Такая очистка позволяет пометить части таблицы как all visible а также позволяет выполнить замораживание кортежей, что может сократить объем работы при последующих очистках. Для таблиц, в которых выполняются INSERT операций, однако при отсутствии или практически полном отсутствии UPDATE/DELETE операций может быть целесообразно снизить для данной таблицы параметр autovacuum_freeze_min_age так как это может позволить выполнить заморозку кортежей при более ранних циклах очистки. Количество устаревших и вставленных кортежей извлекается из системы сбора кумулятивной статистики; данный счетчик является согласованным в конечном счете и обновляется при каждой UPDATE, DELETE и INSERT операции. Если relfrozenxid возраст таблицы превышает vacuum_freeze_table_age транзакций выполняется агрессивная очистка для заморозки старых кортежей и продвижения relfrozenxid; в противном случае сканируются только те страницы, которые были изменены с момента последней очистки.

Для операции analyze используется аналогичное условие; порог определяется как:

analyze threshold = analyze base threshold + analyze scale factor * number of tuples

сравнивается с общим количеством кортежей, вставленных, обновленных или удаленных с момента последней ANALYZE.

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

Механизм автоочистки не имеет доступа к временным таблицам. Таким образом, надлежащие операции очистки (vacuum) и анализа (analyze) следует выполнять с помощью соответствующих SQL-команд в рамках текущего сеанса.

Значения порогов и коэффициентов по умолчанию берутся из файла postgresql.conf, однако их (как и многие другие параметры управления автоочисткой) можно переопределить на уровне отдельных таблиц; см. Storage Parameters для получения более подробной информации. Если значение было изменено через параметры хранения таблицы, то при обработке этой таблицы используется именно это значение; в противном случае используются глобальные параметры. См. Раздел 3.4.10 для получения подробной информации о глобальных параметрах.

При работе нескольких рабочих процессов параметры задержки стоимости автоочистки (см. Раздел 3.4.4.4) «распределяются» между всеми активными рабочими процессами таким образом, чтобы суммарное влияние на подсистему ввода-вывода оставалось неизменным независимо от количества запущенных процессов. Однако рабочие процессы, обрабатывающие таблицы с установленными для них индивидуальными autovacuum_vacuum_cost_delay или autovacuum_vacuum_cost_limit параметрами хранения, не учитываются в алгоритме распределения нагрузки.

Рабочие процессы автоочистки обычно не блокируют выполнение других команд. Если какой-либо процесс пытается получить блокировку, конфликтующую с блокировкой типа SHARE UPDATE EXCLUSIVE , удерживаемой механизмом автоочистки, то процедура получения блокировки прервет работу автоочистки. Информацию о конфликтующих режимах блокировки см. в Таблица 2.10.2. Однако, если автоочистка выполняется для предотвращения зацикливания идентификатора транзакции (т. е. если имя запроса автоочистки в pg_stat_activity представление заканчивается на (для предотвращения зацикливания идентификаторов транзакций)), механизм автоочистки не прерывается автоматически.

Предупреждение

Регулярное выполнение команд, запрашивающих блокировки, которые конфликтуют с SHARE UPDATE EXCLUSIVE блокировкой (например, ANALYZE), может фактически препятствовать завершению процессов автоочистки.

Наверх
свяжитесь
с нами
контакты
Для прямой связи с нами вы можете использовать контакты ниже, либо оставить заявку через форму обратной связи, и мы обязательно свяжемся с вами

*поля обязательные к заполнению