SlideShare a Scribd company logo
Девять кругов ада
или PostgreSQL Vacuum
Лесовский Алексей, 2016.11
PostgreSQL-Consulting
Как быстро сломать Postgres
Часто и много обновлять таблицу.
Отключить вакуум.
До: 3565.5 tps, 0.839 ms.
После: 172.8 tps, 17.373 ms.
Как воспроизвести: https://goo.gl/Tql87l
Take home messages
Вакуум это важно, его не стоит игнорировать.
Если вакуум ненастроен производительность деградирует.
Вакуум не страшен, настраивать его не сложно.
Вакуум и как это работает
MVCC, Postmaster, Autovacuum Launcher & Workers.
Что там внутри Worker'а.
Подготовка к вакууму, costs, wraparound.
Вакуум индексов, таблиц и их страниц.
Слайды: ХХ-ХХ-ХХ
MVCC
MVCC – Multiversion Concurrency Control:
● предлагает хорошую конкурентность;
● в условиях значительной read/write активности;
● читатели не блокируют писателей и наоборот.
MVCC
MVCC – Multiversion Concurrency Control:
● предлагает хорошую конкурентность;
● в условиях значительной read/write активности;
● читатели не блокируют писателей и наоборот.
● Почти ;)
MVCC
MVCC
MVCC
MVCC
MVCC
MVCC
Postmaster
Postmaster работает в бесконечном цикле.
● запуск фоновых процесов (checkpointer, bgwriter, walwriter, ...);
● и в т.ч. autovacuum launcher;
● вообще там много всего…
AV Launcher будет перезапущен если что-то пойдет не так.
Autovacuum Launcher
Инициализация
Запуск воркера в случае emergency.
Создание списка БД.
Запуск бесконечного цикла (SIGTERM ?):
Autovacuum Launcher
Инициализация
Запуск воркера в случае emergency.
Создание списка БД.
Запуск бесконечного цикла (SIGTERM ?):
● обработка SIGTERM, SIGHUP, SIGUSR2;
● запуск воркера для баз в списке (autovacuum_naptime).
Как выбирается база для обработки?
Определяем xidForceLimit = recentXid – autovacuum_freeze_max_age.
Риск wraparound с самым старым datfrozenxid/datminmxid.
Базы которые давно не посещал вакуум.
Пропускаем базы обработанные недавно.
Кандидат выбран
Отметка в shared памяти (имя БД, время запуска).
Отправка сигнала Postmaster“у (флажок + SIGUSR1).
Postmaster принимает сигнал и делает fork (connection limit?).
Воркер запущен.
Postmaster & Co
Worker
Инициализация (signals, file descriptors, filemgr, bufmgr, smgr, shm, local struct).
Установка параметров:
● zero_damaged_pages=false
● statement_timeout=0, lock_timeout=0
● default_transaction_isolation="read commited"
● synchronous_commit=local
Worker
Получение имени БД из av_startingWorker.
Регистрация в runningWorkers и сброс av_startingWorker.
Отправка SIGUSR2 процессу AV Launcher.
Инициализация в качестве postgres backend.
pg_class
Составляем список таблиц для обработки
● таблицы и мат. представления;
● TOAST таблицы.
pg_class
Выбираются только таблицы и мат. представления (pg_class.relkind):
● чтение статы и параметров таблиц (pg_class.reloptions);
● запуск relation_needs_vacanalyze() – vaccum, analyze или wraparound?
● таблица является временной (pg_class.relpersistence)?
Для TOAST запоминаем ассоциацию с родительской таблицей.
Wraparound
Wraparound
recentXid – текущая транзакция.
vacuum_freeze_min_age – строки с возрастом
старше должны быть заморожены.
vacuum_freeze_table_age – полное сканирование
если достигнут возраст.
autovacuum_freeze_max_age – возраст
принудительного запуска wraparound вакуума.
А нужен ли вакуум?
Проверка необходимости вакуума или сбора статистики (или все вместе).
Определение пороговых параметров:
● параметры reloptions (от основной или TOAST таблицы);
● параметры конфигурации (postgresql.conf);
● для freeze_max_age выбираем минимум (reloptions vs. postgresql.conf);
А нужен ли вакуум?
Принудительный вакуум если есть риск wraparound:
● xidForceLimit = recentXid – freeze_max_age;
● multiForceLimit = recentMulti – multixact_freeze_max_age;
● вакуум обязателен если pgclass.relfrozenxid или relminmxid старше порогов;
● если нет риска wraparound и AV отключен – пропускаем таблицу.
А нужен ли вакуум?
pg_stat_all_tables.n_dead_tup, pg_stat_all_tables.n_mod_since_analyze
reltuples = classForm->reltuples;
vactuples = tabentry->n_dead_tuples;
anltuples = tabentry->changes_since_analyze;
vacthresh = (float4) vac_base_thresh + vac_scale_factor * reltuples;
anlthresh = (float4) anl_base_thresh + anl_scale_factor * reltuples;
*dovacuum = force_vacuum || (vactuples > vacthresh);
*doanalyze = (anltuples > anlthresh);
А нужен ли вакуум?
autovacuum_vacuum_threshold = 50 # min number of row updates
# before vacuum
autovacuum_analyze_threshold = 50 # min number of row updates
# before analyze
autovacuum_vacuum_scale_factor = 0.2 # fraction of table size
# before vacuum
autovacuum_analyze_scale_factor = 0.1 # fraction of table size
# before analyze
Подготовка к вакууму
Все таблицы проверены – список составлен – закрываем pg_class.
Выбор стратегии работы с shared памятью:
● BAS_BULKREAD: ring_size = 256 * 1024 / BLCKSZ;
● BAS_BULKWRITE: ring_size = 16 * 1024 * 1024 / BLCKSZ;
● BAS_VACUUM: ring_size = 256 * 1024 / BLCKSZ; (32kB).
Выбор первой таблицы из списка.
Расчет cost параметров
vacuum_cost_delay = 0 # 0-100 milliseconds
vacuum_cost_page_hit = 1 # 0-10000 credits
vacuum_cost_page_miss = 10 # 0-10000 credits
vacuum_cost_page_dirty = 20 # 0-10000 credits
vacuum_cost_limit = 200 # 1-10000 credits
autovacuum_vacuum_cost_delay = 20ms # default vacuum cost delay for
# autovacuum, in milliseconds;
# -1 means use vacuum_cost_delay
autovacuum_vacuum_cost_limit = -1 # default vacuum cost limit for
# autovacuum, -1 means use
# vacuum_cost_limit
Расчет cost параметров
Разделение I/O поровну между всеми воркерами.
Объем I/O определяется с помощью cost_limit, cost_delay.
● autovacuum_vacuum_cost_limit или vacuum_cost_limit;
● autovacuum_vacuum_cost_delay или vacuum_cost_delay;
Ничего не делать если параметры не установлены (<= 0).
Вакуум, вакуум
Вакуум, вакуум
autovacuum_do_vac_analyze() – автовакуум и/или autoanalyze.
ExecVacuum() – точка входа ручных VACUUM и ANALYZE команд.
vacuum() – точка входа для вакуума и сбора статистики.
Вакуум или Аналайз
Cost-based вакуум в случае VacuumCostDelay > 0.
Обработка таблицы в зависимости от потребности:
● vacuum_rel() и analyze_rel();
Завершение обработки:
● обновление pg_database.datfrozenxid и чистка pg_clog;
● завершение работы.
Блокировки
Проверка отмены со стороны пользователя.
Выбор блокировки: ExclusiveLock или ShareUpdateExclusiveLock
Открываем таблицу и берем блокировку.
Не удалось взять блокировку?
● autovacuum: пишем в лог "skipping vacuum of %s --- lock not available";
● не удалось открыть (таблица удалена?), завершаем работу.
Проверка таблицы
Проверка привилегий (superuser, владелец таблицы, владелец БД).
Проверка что объект вообще vacuumable (таблицы, мат.вью, TOAST).
Пропуск временных таблиц других бекендов.
Запоминаем ассоциацию с TOAST (исключение автовакуум).
Переключение userid на владельца таблицы.
Do the actual work
/*
* Do the actual work --- either FULL or "lazy" vacuum
*/
VACUUM FULL?
● закрываем таблицу, но продолжаем держать блокировку;
● cluster_rel() – VACUUM FULL является вариантом CLUSTER; см. cluster.c.
В любом другом случае – lazy_vacuum_rel().
Таблица обработана
Вакуум завершен – таблица обработана.
Закрытие таблицы.
При наличии TOAST, переходим к ней (также vacuum_rel()).
lazy_vacuum_rel()
Установка пороговых значений для заморозки:
● freeze_min_age, freeze_table_age;
● multixact_freeze_min_age, multixact_freeze_table_age;
lazy_vacuum_rel()
Установка пороговых значений для заморозки:
● freeze_min_age, freeze_table_age;
● multixact_freeze_min_age, multixact_freeze_table_age;
● oldestXmin – оценка когда строка считается DEAD или RECENTLY_DEAD;
● freezeLimit – старше этого порога все строки замораживаются;
● xidFullScanLimit – полное сканирование таблицы если relfrozenxid старше порога;
lazy_vacuum_rel()
Установка пороговых значений для заморозки:
● freeze_min_age, freeze_table_age;
● multixact_freeze_min_age, multixact_freeze_table_age;
● oldestXmin – оценка когда строка считается DEAD или RECENTLY_DEAD;
● freezeLimit – старше этого порога все строки замораживаются;
● xidFullScanLimit – полное сканирование таблицы если relfrozenxid старше порога;
● multiXactCutoff – порог для удаления всех MultiXactIds из Xmax;
● mxactFullScanLimit – полное сканирование если relminmxid старше порога.
lazy_vacuum_rel()
Установка пороговых значений для заморозки:
● freeze_min_age, freeze_table_age;
● multixact_freeze_min_age, multixact_freeze_table_age;
● oldestXmin – оценка когда строка считается DEAD или RECENTLY_DEAD;
● freezeLimit – старше этого порога все строки замораживаются;
● xidFullScanLimit – полное сканирование таблицы если relfrozenxid старше порога;
● multiXactCutoff – порог для удаления всех MultiXactIds из Xmax;
● mxactFullScanLimit – полное сканирование если relminmxid старше порога.
Сравниваем relfrozenxid/relminmxid с пороговыми значениями.
lazy_vacuum_rel()
Открываем индексы → вакуум с lazy_scan_heap() → Закрываем индексы.
Считаем вся ли таблица была просканирована:
scanned_pages + frozenskipped_pages = rel_pages
Если возможно обрезаем таблицу.
Обновляем Free Space Map, pg_class:
● relpages, reltuples, relallvisible, relhasindex, refrozenxid/relminmxid (full scan only).
Сохраняем статистику в stats коллектор (n_live_tupe, n_dead_tuples).
Пишем сообщение в журнал, при log_min_duration >= 0.
Конец.
Таблица обработана (напоминание)
Вакуум завершен – таблица обработана.
Закрытие таблицы.
При наличии TOAST, переходим к ней (также vacuum_rel()).
/* lazy_scan_heap() – scan an open heap relation */
Выделяем память для хранения dead строк (autovacuum_work_mem);
Проверяем страницы которые можно пропустить:
● ALL_FROZEN и ALL_VISIBLE флаги (в соотв. с visibility map);
● в случае full scan, нельзя пропускать ALL_VISIBLE страницы;
● всегда пропускаем ALL_FROZEN страницы;
● всегда сканируем последний блок – вдруг таблицу можно обрезать.
После каждого блока выполняем vacuum_delay_point().
lazy_scan_heap()
Начинаем цикл проверки с первого непропускаемого блока:
● и снова ищем следующий блок который нельзя пропускать;
● проверяем хранилище dead строк на предмет переполнения;
● читаем содержимое страницы, считаем costs;
● пытаемся взять блокировку для чистки буффера (для HOT).
Блок будет пропущен если блокировка провалится (искл. full-scan).
lazy_scan_heap()
Проверка страницы на наличие строк — кандидатов в заморозку:
● всегда чистим неинициализированные страницы;
● пропускаем пустые страницы;
● проверяем нормальные страницы;
● dead и redirect никогда не нужно морозить;
● проверяем что любое из XID полей (xmin,xmax,xvac) старше порога.
lazy_scan_heap()
Продолжаем основной цикл проверки страниц…
Новые страницы инициализируем
● помечаем как грязные, отмечаем в Free Space Map.
Пустые страницы:
● ставим отметку ALL_VISIBLE и ALL_FROZEN;
● помечаем как грязные, делаем запись в WAL, обновляем VM и FSM.
Heap Only Tuples
Heap Only Tuples
Heap Only Tuples
Heap Only Tuples
Heap Only Tuples
Heap Only Tuples
Чистка всех HOT цепочек в странице:
● проверяем указатели на предмет HOT цепочек.
● пропускаем redirects, unused и dead указатели.
● Чистим указатели и HOT цепочки (но не вносим никаких изменений в страницу):
● чистим dead и битые HOT цепочки;
● перестраиваем редиректы.
Heap Only Tuples
Применяем изменения в критической секции:
● обновляем указатели;
● делаем дефрагментацию.
Убираем отметку "page is full", помечаем страницу как грязную, пишем WAL.
Завершаем критическую секцию.
(Если доступных для чистки цепочек нет, то ничего не делаем)
lazy_scan_heap()
Проверка страницы, сбор vacuumable строк, проверка на возможность заморозки.
Проверка указателей:
● пропускаем unused, dead, redirects; проверяем только нормальные.
HeapTupleSatisfiesVacuum():
● HEAPTUPLE_DEAD: vacuumable (пропускаем если, это HOT цепочка).
● HEAPTUPLE_LIVE: хорошая строка, вакуум не нужен.
● HEAPTUPLE_RECENTLY_DEAD: нельзя удалять строку.
● HEAPTUPLE_INSERT_IN_PROGRESS и HEAPTUPLE_DELETE_IN_PROGRESS:
пропускаем, страница не является ALL_VISIBLE.
Запоминаем vacuumable строки в хранилище (vacrelstats).
lazy_scan_heap()
Проверяем неудаляемые строки на возможность заморозки.
● подготавливаем строку если можно морозить (составляем локальный infomask).
Если есть строки для заморозки:
● открываем критическую секцию;
● отмечаем страницу как грязную;
● устанавливаем биты в infomask строки;
● пишем изменения в WAL;
● завершаем критическую секцию.
lazy_scan_heap()
Если нет индексов сразу вакуумим страницу.
Обновляем Visibility Map и Free Space Map.
Переходим к следующему блоку
или завершаем цикл, если все блоки просканированы.
lazy_scan_heap()
Сохраняем статистику, считаем новое pg_class.reltuples.
Если еще есть строки к удалению, выполняем завершающий цикл вакуума.
● удаляем указатели в индексах;
● удаляем строки из таблицы с lazy_vacuum_heap().
lazy_vacuum_heap()
lazy_vacuum_heap() – второй проход по таблице.
Цикл через собранные строки (vacrelstats) – идем только в те страницы где есть
мертвые строки:
● перед началом делаем vacuum_delay_point();
● читаем блок и считаем costs;
● пытаемся взять блокировку для очистки – пропускаем блок если не удалось;
● чистим страницу с lazy_vacuum_page();
● обновляем Free Space Map.
lazy_vacuum_page()
lazy_vacuum_page() – чистим dead строки в странице, убираем фрагментацию.
Все изменения в критической секции.
● цикл по dead строкам (внутри страницы);
● отмечаем указатель ItemID как неиспользуемый (LP_UNUSED);
● убираем фрагментацию страницы;
● отмечаем страницу как грязную, пишем в WAL.
Закрываем критическую секцию.
Обновляем Visibility Map.
lazy_scan_heap()
Таблица обработана, VM обновлена.
Обновляем FreeSpaceMap.
Обновление статистики индексов (pg_class).
Пишем в журнал сообщение о проделанной работе.
Конец ?
Что в итоге?
Вакуум всегда должен быть включен.
Дефолтные настройки не оптимальны.
Нагрузка регулируется через cost-based опции.
Вакуум не всегда может вычистить таблицу.
Избегайте длинных транзакций.
Ссылки
Alexey Lesovsky – lesovsky@pgco.me
See slides on SlideShare: http://www.slideshare.net/alexeylesovsky/
PostgreSQL official documentation:
● Vacuum: https://www.postgresql.org/docs/current/static/routine-vacuuming.html
● Autovacuum:
● https://www.postgresql.org/docs/current/static/routine-vacuuming.html#AUTOVACUUM
● https://www.postgresql.org/docs/current/static/runtime-config-autovacuum.html
● Progress Reporting: https://www.postgresql.org/docs/devel/static/progress-reporting.html
● PageInspect contrib module: https://www.postgresql.org/docs/current/static/pageinspect.html
Девять кругов ада или PostgreSQL Vacuum / Алексей Лесовский (PostgreSQL-Consulting LLC)
lazy_scan_heap()
Теперь таблица уже обработана, VM обновлена.
Обновляем FreeSpaceMap.
Пишем в журнал: "%s: removed %d row versions in %d pages ".
Обновление статистики индексов (pg_class).
Пишем в журнал сообщение о проделанной работа.

More Related Content

What's hot (20)

PDF
RootConf 2015
Evgeny Uskov
 
PDF
Мониторинг ожиданий в PostgreSQL / Курбангалиев Ильдус (Postgres Professional)
Ontico
 
PDF
Streaming replication in practice
Alexey Lesovsky
 
PDF
Новые технологии репликации данных в PostgreSQL / Александр Алексеев (Postgre...
Ontico
 
PDF
Современная операционная система: что надо знать разработчику / Александр Кри...
Ontico
 
PDF
Оптимизация high-contention write в PostgreSQL / Александр Коротков, Олег Бар...
Ontico
 
PDF
Call of Postgres: Advanced Operations (part 1)
Alexey Lesovsky
 
PPTX
Автоматизация тестирования клиентской производительности / Николай Лавлинский...
Ontico
 
PPTX
Жизнь проекта на production советы по эксплуатации / Николай Сивко (okmeter.io)
Ontico
 
PDF
nginx.CHANGES.2015 / Игорь Сысоев, Валентин Бартенев (Nginx)
Ontico
 
PDF
DPDK в виртуальном коммутаторе Open vSwitch / Александр Джуринский (Selectel)
Ontico
 
PPTX
Тюним память и сетевой стек в Linux: история перевода высоконагруженных серве...
Ontico
 
PDF
PostgreSQL worst practices / Илья Космодемьянский (Data Egret)
Ontico
 
PDF
Что особенного в СУБД для данных в оперативной памяти / Константин Осипов (Ta...
Ontico
 
PPTX
Flashcache в mamba.ru / Яковлев Александр Юрьевич (ЗАО Мамба)
Ontico
 
PDF
PostgreSQL Streaming Replication
Alexey Lesovsky
 
PDF
libfpta — обгоняя SQLite и Tarantool / Леонид Юрьев (Positive Technologies)
Ontico
 
PDF
Call of Postgres: Advanced Operations (part 3)
Alexey Lesovsky
 
PDF
Очереди и блокировки. Теория и практика / Александр Календарев (ad1.ru)
Ontico
 
PPTX
Защита данных и датацентров от катастроф. Подход Nutanix / Максим Шапошников ...
Ontico
 
RootConf 2015
Evgeny Uskov
 
Мониторинг ожиданий в PostgreSQL / Курбангалиев Ильдус (Postgres Professional)
Ontico
 
Streaming replication in practice
Alexey Lesovsky
 
Новые технологии репликации данных в PostgreSQL / Александр Алексеев (Postgre...
Ontico
 
Современная операционная система: что надо знать разработчику / Александр Кри...
Ontico
 
Оптимизация high-contention write в PostgreSQL / Александр Коротков, Олег Бар...
Ontico
 
Call of Postgres: Advanced Operations (part 1)
Alexey Lesovsky
 
Автоматизация тестирования клиентской производительности / Николай Лавлинский...
Ontico
 
Жизнь проекта на production советы по эксплуатации / Николай Сивко (okmeter.io)
Ontico
 
nginx.CHANGES.2015 / Игорь Сысоев, Валентин Бартенев (Nginx)
Ontico
 
DPDK в виртуальном коммутаторе Open vSwitch / Александр Джуринский (Selectel)
Ontico
 
Тюним память и сетевой стек в Linux: история перевода высоконагруженных серве...
Ontico
 
PostgreSQL worst practices / Илья Космодемьянский (Data Egret)
Ontico
 
Что особенного в СУБД для данных в оперативной памяти / Константин Осипов (Ta...
Ontico
 
Flashcache в mamba.ru / Яковлев Александр Юрьевич (ЗАО Мамба)
Ontico
 
PostgreSQL Streaming Replication
Alexey Lesovsky
 
libfpta — обгоняя SQLite и Tarantool / Леонид Юрьев (Positive Technologies)
Ontico
 
Call of Postgres: Advanced Operations (part 3)
Alexey Lesovsky
 
Очереди и блокировки. Теория и практика / Александр Календарев (ad1.ru)
Ontico
 
Защита данных и датацентров от катастроф. Подход Nutanix / Максим Шапошников ...
Ontico
 

Viewers also liked (20)

PDF
PostgreSQL: практические примеры оптимизации SQL-запросов / Иван Фролков (Po...
Ontico
 
PDF
Новые возможности полнотекстового поиска в PostgreSQL / Олег Бартунов (Postgr...
Ontico
 
PDF
Non-Relational Postgres / Bruce Momjian (EnterpriseDB)
Ontico
 
PDF
Долгожданный релиз pg_pathman 1.0 / Александр Коротков, Дмитрий Иванов (Post...
Ontico
 
PDF
NoSQL внутри SQL: приземленные вопросы практического применения / Дмитрий До...
Ontico
 
PPTX
Выбираем СУБД для хранения временных рядов / Павел Филонов (Лаборатория Каспе...
Ontico
 
PPTX
Как мы готовим MySQL / Николай Королёв (Badoo)
Ontico
 
PDF
Хочу знать, сколько уникальных посетителей было на моём сайте за произвольный...
Ontico
 
PDF
PostgreSQL - Ups, DevOps..., Алексей Лесовский (PostgreSQL-Consulting)
Ontico
 
PDF
Tuning Linux for Databases.
Alexey Lesovsky
 
PDF
Nine Circles of Inferno or Explaining the PostgreSQL Vacuum
Alexey Lesovsky
 
PDF
Open Source SQL-базы данных вступили в эру миллионов запросов в секунду / Фед...
Ontico
 
PDF
Managing PostgreSQL with PgCenter
Alexey Lesovsky
 
PDF
Отладка производительности приложения на Erlang / Максим Лапшин (Erlyvideo)
Ontico
 
PDF
Полнотекстовый поиск в PostgreSQL за миллисекунды (Олег Бартунов, Александр К...
Ontico
 
PDF
Deep dive into PostgreSQL statistics.
Alexey Lesovsky
 
PDF
Хранение данных на виниле / Константин Осипов (tarantool.org)
Ontico
 
PDF
Профилирование кода на C/C++ в *nix-системах / Александр Алексеев (Postgres P...
Ontico
 
PDF
Peeking into the Black Hole Called PL/PGSQL - the New PL Profiler / Jan Wieck...
Ontico
 
PDF
Archival Disc на смену Blu-ray: построение архивного хранилища на оптических ...
Ontico
 
PostgreSQL: практические примеры оптимизации SQL-запросов / Иван Фролков (Po...
Ontico
 
Новые возможности полнотекстового поиска в PostgreSQL / Олег Бартунов (Postgr...
Ontico
 
Non-Relational Postgres / Bruce Momjian (EnterpriseDB)
Ontico
 
Долгожданный релиз pg_pathman 1.0 / Александр Коротков, Дмитрий Иванов (Post...
Ontico
 
NoSQL внутри SQL: приземленные вопросы практического применения / Дмитрий До...
Ontico
 
Выбираем СУБД для хранения временных рядов / Павел Филонов (Лаборатория Каспе...
Ontico
 
Как мы готовим MySQL / Николай Королёв (Badoo)
Ontico
 
Хочу знать, сколько уникальных посетителей было на моём сайте за произвольный...
Ontico
 
PostgreSQL - Ups, DevOps..., Алексей Лесовский (PostgreSQL-Consulting)
Ontico
 
Tuning Linux for Databases.
Alexey Lesovsky
 
Nine Circles of Inferno or Explaining the PostgreSQL Vacuum
Alexey Lesovsky
 
Open Source SQL-базы данных вступили в эру миллионов запросов в секунду / Фед...
Ontico
 
Managing PostgreSQL with PgCenter
Alexey Lesovsky
 
Отладка производительности приложения на Erlang / Максим Лапшин (Erlyvideo)
Ontico
 
Полнотекстовый поиск в PostgreSQL за миллисекунды (Олег Бартунов, Александр К...
Ontico
 
Deep dive into PostgreSQL statistics.
Alexey Lesovsky
 
Хранение данных на виниле / Константин Осипов (tarantool.org)
Ontico
 
Профилирование кода на C/C++ в *nix-системах / Александр Алексеев (Postgres P...
Ontico
 
Peeking into the Black Hole Called PL/PGSQL - the New PL Profiler / Jan Wieck...
Ontico
 
Archival Disc на смену Blu-ray: построение архивного хранилища на оптических ...
Ontico
 
Ad

Similar to Девять кругов ада или PostgreSQL Vacuum / Алексей Лесовский (PostgreSQL-Consulting LLC) (20)

PDF
Беспроблемная эксплуатация PostgreSQL
Дмитрий Васильев
 
PDF
Optimization of a big PostgreSQL database
Alex Chistyakov
 
PDF
Where is the space, Postgres?
Alexey Ermakov
 
PDF
PG Day'14 Russia, PostgreSQL в avito.ru, Михаил Тюрин
pgdayrussia
 
PDF
Народные средства оптимизации PostgreSQL
Nikolay Pisarev
 
PDF
PostgreSQL performance recipes
Alexey Ermakov
 
PDF
Промышленный подход к тюнингу PostgreSQL: эксперименты над базами данных
Nikolay Samokhvalov
 
PDF
Hacking PostgreSQL. Обзор архитектуры.
Anastasia Lubennikova
 
PPTX
Диагностика postgresql для системного администратора
Nikolay Sivko
 
PDF
"Мы два месяца долбались, а потом построили индекс" (c) Аксенов
Alex Chistyakov
 
PDF
Последние новости постгреса с PGCon / О.Бартунов, А.Коротков, Ф.Сигаев (Postg...
Ontico
 
ODP
Scaling PostgreSQL
Дмитрий Васильев
 
PDF
Ivan Kotlyar. PostgreSQL in web applications
DrupalSib
 
PPTX
Длинная транзакция или когда размер имеет значение / Михаил Балаян (Odin — In...
Ontico
 
PDF
Top-10 популярных вопросов администраторам баз данных или почему я против св...
Ilya Kosmodemiansky
 
PDF
Database First! О распространённых ошибках использования РСУБД
Nikolay Samokhvalov
 
PDF
Database First! О распространённых ошибках использования РСУБД / Николай Само...
Ontico
 
PDF
Павел Лузанов, Postgres Professional. «PostgreSQL для пользователей Oracle»
Mail.ru Group
 
PDF
2015.02.06 PostgreSQL в Яндексе: история успеха №2
dev1ant
 
PDF
Hacking PostgreSQL. Разделяемая память и блокировки.
Anastasia Lubennikova
 
Беспроблемная эксплуатация PostgreSQL
Дмитрий Васильев
 
Optimization of a big PostgreSQL database
Alex Chistyakov
 
Where is the space, Postgres?
Alexey Ermakov
 
PG Day'14 Russia, PostgreSQL в avito.ru, Михаил Тюрин
pgdayrussia
 
Народные средства оптимизации PostgreSQL
Nikolay Pisarev
 
PostgreSQL performance recipes
Alexey Ermakov
 
Промышленный подход к тюнингу PostgreSQL: эксперименты над базами данных
Nikolay Samokhvalov
 
Hacking PostgreSQL. Обзор архитектуры.
Anastasia Lubennikova
 
Диагностика postgresql для системного администратора
Nikolay Sivko
 
"Мы два месяца долбались, а потом построили индекс" (c) Аксенов
Alex Chistyakov
 
Последние новости постгреса с PGCon / О.Бартунов, А.Коротков, Ф.Сигаев (Postg...
Ontico
 
Ivan Kotlyar. PostgreSQL in web applications
DrupalSib
 
Длинная транзакция или когда размер имеет значение / Михаил Балаян (Odin — In...
Ontico
 
Top-10 популярных вопросов администраторам баз данных или почему я против св...
Ilya Kosmodemiansky
 
Database First! О распространённых ошибках использования РСУБД
Nikolay Samokhvalov
 
Database First! О распространённых ошибках использования РСУБД / Николай Само...
Ontico
 
Павел Лузанов, Postgres Professional. «PostgreSQL для пользователей Oracle»
Mail.ru Group
 
2015.02.06 PostgreSQL в Яндексе: история успеха №2
dev1ant
 
Hacking PostgreSQL. Разделяемая память и блокировки.
Anastasia Lubennikova
 
Ad

More from Ontico (20)

PDF
One-cloud — система управления дата-центром в Одноклассниках / Олег Анастасье...
Ontico
 
PDF
Масштабируя DNS / Артем Гавриченков (Qrator Labs)
Ontico
 
PPTX
Создание BigData-платформы для ФГУП Почта России / Андрей Бащенко (Luxoft)
Ontico
 
PDF
Готовим тестовое окружение, или сколько тестовых инстансов вам нужно / Алекса...
Ontico
 
PDF
PostgreSQL Configuration for Humans / Alvaro Hernandez (OnGres)
Ontico
 
PDF
Inexpensive Datamasking for MySQL with ProxySQL — Data Anonymization for Deve...
Ontico
 
PDF
Опыт разработки модуля межсетевого экранирования для MySQL / Олег Брославский...
Ontico
 
PPTX
ProxySQL Use Case Scenarios / Alkin Tezuysal (Percona)
Ontico
 
PPTX
MySQL Replication — Advanced Features / Петр Зайцев (Percona)
Ontico
 
PDF
Внутренний open-source. Как разрабатывать мобильное приложение большим количе...
Ontico
 
PPTX
Подробно о том, как Causal Consistency реализовано в MongoDB / Михаил Тюленев...
Ontico
 
PPTX
Балансировка на скорости проводов. Без ASIC, без ограничений. Решения NFWare ...
Ontico
 
PDF
Перехват трафика — мифы и реальность / Евгений Усков (Qrator Labs)
Ontico
 
PPT
И тогда наверняка вдруг запляшут облака! / Алексей Сушков (ПЕТЕР-СЕРВИС)
Ontico
 
PPTX
Как мы заставили Druid работать в Одноклассниках / Юрий Невиницин (OK.RU)
Ontico
 
PPTX
Разгоняем ASP.NET Core / Илья Вербицкий (WebStoating s.r.o.)
Ontico
 
PPTX
100500 способов кэширования в Oracle Database или как достичь максимальной ск...
Ontico
 
PPTX
Apache Ignite Persistence: зачем Persistence для In-Memory, и как он работает...
Ontico
 
PDF
Механизмы мониторинга баз данных: взгляд изнутри / Дмитрий Еманов (Firebird P...
Ontico
 
PDF
Как мы учились чинить самолеты в воздухе / Евгений Коломеец (Virtuozzo)
Ontico
 
One-cloud — система управления дата-центром в Одноклассниках / Олег Анастасье...
Ontico
 
Масштабируя DNS / Артем Гавриченков (Qrator Labs)
Ontico
 
Создание BigData-платформы для ФГУП Почта России / Андрей Бащенко (Luxoft)
Ontico
 
Готовим тестовое окружение, или сколько тестовых инстансов вам нужно / Алекса...
Ontico
 
PostgreSQL Configuration for Humans / Alvaro Hernandez (OnGres)
Ontico
 
Inexpensive Datamasking for MySQL with ProxySQL — Data Anonymization for Deve...
Ontico
 
Опыт разработки модуля межсетевого экранирования для MySQL / Олег Брославский...
Ontico
 
ProxySQL Use Case Scenarios / Alkin Tezuysal (Percona)
Ontico
 
MySQL Replication — Advanced Features / Петр Зайцев (Percona)
Ontico
 
Внутренний open-source. Как разрабатывать мобильное приложение большим количе...
Ontico
 
Подробно о том, как Causal Consistency реализовано в MongoDB / Михаил Тюленев...
Ontico
 
Балансировка на скорости проводов. Без ASIC, без ограничений. Решения NFWare ...
Ontico
 
Перехват трафика — мифы и реальность / Евгений Усков (Qrator Labs)
Ontico
 
И тогда наверняка вдруг запляшут облака! / Алексей Сушков (ПЕТЕР-СЕРВИС)
Ontico
 
Как мы заставили Druid работать в Одноклассниках / Юрий Невиницин (OK.RU)
Ontico
 
Разгоняем ASP.NET Core / Илья Вербицкий (WebStoating s.r.o.)
Ontico
 
100500 способов кэширования в Oracle Database или как достичь максимальной ск...
Ontico
 
Apache Ignite Persistence: зачем Persistence для In-Memory, и как он работает...
Ontico
 
Механизмы мониторинга баз данных: взгляд изнутри / Дмитрий Еманов (Firebird P...
Ontico
 
Как мы учились чинить самолеты в воздухе / Евгений Коломеец (Virtuozzo)
Ontico
 

Девять кругов ада или PostgreSQL Vacuum / Алексей Лесовский (PostgreSQL-Consulting LLC)

  • 1. Девять кругов ада или PostgreSQL Vacuum Лесовский Алексей, 2016.11 PostgreSQL-Consulting
  • 2. Как быстро сломать Postgres Часто и много обновлять таблицу. Отключить вакуум. До: 3565.5 tps, 0.839 ms. После: 172.8 tps, 17.373 ms. Как воспроизвести: https://goo.gl/Tql87l
  • 3. Take home messages Вакуум это важно, его не стоит игнорировать. Если вакуум ненастроен производительность деградирует. Вакуум не страшен, настраивать его не сложно.
  • 4. Вакуум и как это работает MVCC, Postmaster, Autovacuum Launcher & Workers. Что там внутри Worker'а. Подготовка к вакууму, costs, wraparound. Вакуум индексов, таблиц и их страниц. Слайды: ХХ-ХХ-ХХ
  • 5. MVCC MVCC – Multiversion Concurrency Control: ● предлагает хорошую конкурентность; ● в условиях значительной read/write активности; ● читатели не блокируют писателей и наоборот.
  • 6. MVCC MVCC – Multiversion Concurrency Control: ● предлагает хорошую конкурентность; ● в условиях значительной read/write активности; ● читатели не блокируют писателей и наоборот. ● Почти ;)
  • 10. MVCC
  • 11. MVCC
  • 12. MVCC
  • 13. Postmaster Postmaster работает в бесконечном цикле. ● запуск фоновых процесов (checkpointer, bgwriter, walwriter, ...); ● и в т.ч. autovacuum launcher; ● вообще там много всего… AV Launcher будет перезапущен если что-то пойдет не так.
  • 14. Autovacuum Launcher Инициализация Запуск воркера в случае emergency. Создание списка БД. Запуск бесконечного цикла (SIGTERM ?):
  • 15. Autovacuum Launcher Инициализация Запуск воркера в случае emergency. Создание списка БД. Запуск бесконечного цикла (SIGTERM ?): ● обработка SIGTERM, SIGHUP, SIGUSR2; ● запуск воркера для баз в списке (autovacuum_naptime).
  • 16. Как выбирается база для обработки? Определяем xidForceLimit = recentXid – autovacuum_freeze_max_age. Риск wraparound с самым старым datfrozenxid/datminmxid. Базы которые давно не посещал вакуум. Пропускаем базы обработанные недавно.
  • 17. Кандидат выбран Отметка в shared памяти (имя БД, время запуска). Отправка сигнала Postmaster“у (флажок + SIGUSR1). Postmaster принимает сигнал и делает fork (connection limit?). Воркер запущен.
  • 19. Worker Инициализация (signals, file descriptors, filemgr, bufmgr, smgr, shm, local struct). Установка параметров: ● zero_damaged_pages=false ● statement_timeout=0, lock_timeout=0 ● default_transaction_isolation="read commited" ● synchronous_commit=local
  • 20. Worker Получение имени БД из av_startingWorker. Регистрация в runningWorkers и сброс av_startingWorker. Отправка SIGUSR2 процессу AV Launcher. Инициализация в качестве postgres backend.
  • 21. pg_class Составляем список таблиц для обработки ● таблицы и мат. представления; ● TOAST таблицы.
  • 22. pg_class Выбираются только таблицы и мат. представления (pg_class.relkind): ● чтение статы и параметров таблиц (pg_class.reloptions); ● запуск relation_needs_vacanalyze() – vaccum, analyze или wraparound? ● таблица является временной (pg_class.relpersistence)? Для TOAST запоминаем ассоциацию с родительской таблицей.
  • 24. Wraparound recentXid – текущая транзакция. vacuum_freeze_min_age – строки с возрастом старше должны быть заморожены. vacuum_freeze_table_age – полное сканирование если достигнут возраст. autovacuum_freeze_max_age – возраст принудительного запуска wraparound вакуума.
  • 25. А нужен ли вакуум? Проверка необходимости вакуума или сбора статистики (или все вместе). Определение пороговых параметров: ● параметры reloptions (от основной или TOAST таблицы); ● параметры конфигурации (postgresql.conf); ● для freeze_max_age выбираем минимум (reloptions vs. postgresql.conf);
  • 26. А нужен ли вакуум? Принудительный вакуум если есть риск wraparound: ● xidForceLimit = recentXid – freeze_max_age; ● multiForceLimit = recentMulti – multixact_freeze_max_age; ● вакуум обязателен если pgclass.relfrozenxid или relminmxid старше порогов; ● если нет риска wraparound и AV отключен – пропускаем таблицу.
  • 27. А нужен ли вакуум? pg_stat_all_tables.n_dead_tup, pg_stat_all_tables.n_mod_since_analyze reltuples = classForm->reltuples; vactuples = tabentry->n_dead_tuples; anltuples = tabentry->changes_since_analyze; vacthresh = (float4) vac_base_thresh + vac_scale_factor * reltuples; anlthresh = (float4) anl_base_thresh + anl_scale_factor * reltuples; *dovacuum = force_vacuum || (vactuples > vacthresh); *doanalyze = (anltuples > anlthresh);
  • 28. А нужен ли вакуум? autovacuum_vacuum_threshold = 50 # min number of row updates # before vacuum autovacuum_analyze_threshold = 50 # min number of row updates # before analyze autovacuum_vacuum_scale_factor = 0.2 # fraction of table size # before vacuum autovacuum_analyze_scale_factor = 0.1 # fraction of table size # before analyze
  • 29. Подготовка к вакууму Все таблицы проверены – список составлен – закрываем pg_class. Выбор стратегии работы с shared памятью: ● BAS_BULKREAD: ring_size = 256 * 1024 / BLCKSZ; ● BAS_BULKWRITE: ring_size = 16 * 1024 * 1024 / BLCKSZ; ● BAS_VACUUM: ring_size = 256 * 1024 / BLCKSZ; (32kB). Выбор первой таблицы из списка.
  • 30. Расчет cost параметров vacuum_cost_delay = 0 # 0-100 milliseconds vacuum_cost_page_hit = 1 # 0-10000 credits vacuum_cost_page_miss = 10 # 0-10000 credits vacuum_cost_page_dirty = 20 # 0-10000 credits vacuum_cost_limit = 200 # 1-10000 credits autovacuum_vacuum_cost_delay = 20ms # default vacuum cost delay for # autovacuum, in milliseconds; # -1 means use vacuum_cost_delay autovacuum_vacuum_cost_limit = -1 # default vacuum cost limit for # autovacuum, -1 means use # vacuum_cost_limit
  • 31. Расчет cost параметров Разделение I/O поровну между всеми воркерами. Объем I/O определяется с помощью cost_limit, cost_delay. ● autovacuum_vacuum_cost_limit или vacuum_cost_limit; ● autovacuum_vacuum_cost_delay или vacuum_cost_delay; Ничего не делать если параметры не установлены (<= 0).
  • 33. Вакуум, вакуум autovacuum_do_vac_analyze() – автовакуум и/или autoanalyze. ExecVacuum() – точка входа ручных VACUUM и ANALYZE команд. vacuum() – точка входа для вакуума и сбора статистики.
  • 34. Вакуум или Аналайз Cost-based вакуум в случае VacuumCostDelay > 0. Обработка таблицы в зависимости от потребности: ● vacuum_rel() и analyze_rel(); Завершение обработки: ● обновление pg_database.datfrozenxid и чистка pg_clog; ● завершение работы.
  • 35. Блокировки Проверка отмены со стороны пользователя. Выбор блокировки: ExclusiveLock или ShareUpdateExclusiveLock Открываем таблицу и берем блокировку. Не удалось взять блокировку? ● autovacuum: пишем в лог "skipping vacuum of %s --- lock not available"; ● не удалось открыть (таблица удалена?), завершаем работу.
  • 36. Проверка таблицы Проверка привилегий (superuser, владелец таблицы, владелец БД). Проверка что объект вообще vacuumable (таблицы, мат.вью, TOAST). Пропуск временных таблиц других бекендов. Запоминаем ассоциацию с TOAST (исключение автовакуум). Переключение userid на владельца таблицы.
  • 37. Do the actual work /* * Do the actual work --- either FULL or "lazy" vacuum */ VACUUM FULL? ● закрываем таблицу, но продолжаем держать блокировку; ● cluster_rel() – VACUUM FULL является вариантом CLUSTER; см. cluster.c. В любом другом случае – lazy_vacuum_rel().
  • 38. Таблица обработана Вакуум завершен – таблица обработана. Закрытие таблицы. При наличии TOAST, переходим к ней (также vacuum_rel()).
  • 39. lazy_vacuum_rel() Установка пороговых значений для заморозки: ● freeze_min_age, freeze_table_age; ● multixact_freeze_min_age, multixact_freeze_table_age;
  • 40. lazy_vacuum_rel() Установка пороговых значений для заморозки: ● freeze_min_age, freeze_table_age; ● multixact_freeze_min_age, multixact_freeze_table_age; ● oldestXmin – оценка когда строка считается DEAD или RECENTLY_DEAD; ● freezeLimit – старше этого порога все строки замораживаются; ● xidFullScanLimit – полное сканирование таблицы если relfrozenxid старше порога;
  • 41. lazy_vacuum_rel() Установка пороговых значений для заморозки: ● freeze_min_age, freeze_table_age; ● multixact_freeze_min_age, multixact_freeze_table_age; ● oldestXmin – оценка когда строка считается DEAD или RECENTLY_DEAD; ● freezeLimit – старше этого порога все строки замораживаются; ● xidFullScanLimit – полное сканирование таблицы если relfrozenxid старше порога; ● multiXactCutoff – порог для удаления всех MultiXactIds из Xmax; ● mxactFullScanLimit – полное сканирование если relminmxid старше порога.
  • 42. lazy_vacuum_rel() Установка пороговых значений для заморозки: ● freeze_min_age, freeze_table_age; ● multixact_freeze_min_age, multixact_freeze_table_age; ● oldestXmin – оценка когда строка считается DEAD или RECENTLY_DEAD; ● freezeLimit – старше этого порога все строки замораживаются; ● xidFullScanLimit – полное сканирование таблицы если relfrozenxid старше порога; ● multiXactCutoff – порог для удаления всех MultiXactIds из Xmax; ● mxactFullScanLimit – полное сканирование если relminmxid старше порога. Сравниваем relfrozenxid/relminmxid с пороговыми значениями.
  • 43. lazy_vacuum_rel() Открываем индексы → вакуум с lazy_scan_heap() → Закрываем индексы. Считаем вся ли таблица была просканирована: scanned_pages + frozenskipped_pages = rel_pages Если возможно обрезаем таблицу. Обновляем Free Space Map, pg_class: ● relpages, reltuples, relallvisible, relhasindex, refrozenxid/relminmxid (full scan only). Сохраняем статистику в stats коллектор (n_live_tupe, n_dead_tuples). Пишем сообщение в журнал, при log_min_duration >= 0. Конец.
  • 44. Таблица обработана (напоминание) Вакуум завершен – таблица обработана. Закрытие таблицы. При наличии TOAST, переходим к ней (также vacuum_rel()).
  • 45. /* lazy_scan_heap() – scan an open heap relation */ Выделяем память для хранения dead строк (autovacuum_work_mem); Проверяем страницы которые можно пропустить: ● ALL_FROZEN и ALL_VISIBLE флаги (в соотв. с visibility map); ● в случае full scan, нельзя пропускать ALL_VISIBLE страницы; ● всегда пропускаем ALL_FROZEN страницы; ● всегда сканируем последний блок – вдруг таблицу можно обрезать. После каждого блока выполняем vacuum_delay_point().
  • 46. lazy_scan_heap() Начинаем цикл проверки с первого непропускаемого блока: ● и снова ищем следующий блок который нельзя пропускать; ● проверяем хранилище dead строк на предмет переполнения; ● читаем содержимое страницы, считаем costs; ● пытаемся взять блокировку для чистки буффера (для HOT). Блок будет пропущен если блокировка провалится (искл. full-scan).
  • 47. lazy_scan_heap() Проверка страницы на наличие строк — кандидатов в заморозку: ● всегда чистим неинициализированные страницы; ● пропускаем пустые страницы; ● проверяем нормальные страницы; ● dead и redirect никогда не нужно морозить; ● проверяем что любое из XID полей (xmin,xmax,xvac) старше порога.
  • 48. lazy_scan_heap() Продолжаем основной цикл проверки страниц… Новые страницы инициализируем ● помечаем как грязные, отмечаем в Free Space Map. Пустые страницы: ● ставим отметку ALL_VISIBLE и ALL_FROZEN; ● помечаем как грязные, делаем запись в WAL, обновляем VM и FSM.
  • 54. Heap Only Tuples Чистка всех HOT цепочек в странице: ● проверяем указатели на предмет HOT цепочек. ● пропускаем redirects, unused и dead указатели. ● Чистим указатели и HOT цепочки (но не вносим никаких изменений в страницу): ● чистим dead и битые HOT цепочки; ● перестраиваем редиректы.
  • 55. Heap Only Tuples Применяем изменения в критической секции: ● обновляем указатели; ● делаем дефрагментацию. Убираем отметку "page is full", помечаем страницу как грязную, пишем WAL. Завершаем критическую секцию. (Если доступных для чистки цепочек нет, то ничего не делаем)
  • 56. lazy_scan_heap() Проверка страницы, сбор vacuumable строк, проверка на возможность заморозки. Проверка указателей: ● пропускаем unused, dead, redirects; проверяем только нормальные. HeapTupleSatisfiesVacuum(): ● HEAPTUPLE_DEAD: vacuumable (пропускаем если, это HOT цепочка). ● HEAPTUPLE_LIVE: хорошая строка, вакуум не нужен. ● HEAPTUPLE_RECENTLY_DEAD: нельзя удалять строку. ● HEAPTUPLE_INSERT_IN_PROGRESS и HEAPTUPLE_DELETE_IN_PROGRESS: пропускаем, страница не является ALL_VISIBLE. Запоминаем vacuumable строки в хранилище (vacrelstats).
  • 57. lazy_scan_heap() Проверяем неудаляемые строки на возможность заморозки. ● подготавливаем строку если можно морозить (составляем локальный infomask). Если есть строки для заморозки: ● открываем критическую секцию; ● отмечаем страницу как грязную; ● устанавливаем биты в infomask строки; ● пишем изменения в WAL; ● завершаем критическую секцию.
  • 58. lazy_scan_heap() Если нет индексов сразу вакуумим страницу. Обновляем Visibility Map и Free Space Map. Переходим к следующему блоку или завершаем цикл, если все блоки просканированы.
  • 59. lazy_scan_heap() Сохраняем статистику, считаем новое pg_class.reltuples. Если еще есть строки к удалению, выполняем завершающий цикл вакуума. ● удаляем указатели в индексах; ● удаляем строки из таблицы с lazy_vacuum_heap().
  • 60. lazy_vacuum_heap() lazy_vacuum_heap() – второй проход по таблице. Цикл через собранные строки (vacrelstats) – идем только в те страницы где есть мертвые строки: ● перед началом делаем vacuum_delay_point(); ● читаем блок и считаем costs; ● пытаемся взять блокировку для очистки – пропускаем блок если не удалось; ● чистим страницу с lazy_vacuum_page(); ● обновляем Free Space Map.
  • 61. lazy_vacuum_page() lazy_vacuum_page() – чистим dead строки в странице, убираем фрагментацию. Все изменения в критической секции. ● цикл по dead строкам (внутри страницы); ● отмечаем указатель ItemID как неиспользуемый (LP_UNUSED); ● убираем фрагментацию страницы; ● отмечаем страницу как грязную, пишем в WAL. Закрываем критическую секцию. Обновляем Visibility Map.
  • 62. lazy_scan_heap() Таблица обработана, VM обновлена. Обновляем FreeSpaceMap. Обновление статистики индексов (pg_class). Пишем в журнал сообщение о проделанной работе.
  • 64. Что в итоге? Вакуум всегда должен быть включен. Дефолтные настройки не оптимальны. Нагрузка регулируется через cost-based опции. Вакуум не всегда может вычистить таблицу. Избегайте длинных транзакций.
  • 65. Ссылки Alexey Lesovsky – [email protected] See slides on SlideShare: http://www.slideshare.net/alexeylesovsky/ PostgreSQL official documentation: ● Vacuum: https://www.postgresql.org/docs/current/static/routine-vacuuming.html ● Autovacuum: ● https://www.postgresql.org/docs/current/static/routine-vacuuming.html#AUTOVACUUM ● https://www.postgresql.org/docs/current/static/runtime-config-autovacuum.html ● Progress Reporting: https://www.postgresql.org/docs/devel/static/progress-reporting.html ● PageInspect contrib module: https://www.postgresql.org/docs/current/static/pageinspect.html
  • 67. lazy_scan_heap() Теперь таблица уже обработана, VM обновлена. Обновляем FreeSpaceMap. Пишем в журнал: "%s: removed %d row versions in %d pages ". Обновление статистики индексов (pg_class). Пишем в журнал сообщение о проделанной работа.