Стоит ли запускать VACUUM на столе, который получает только INSERT?

19

В выступлении 2015 года re: Invent AWS упомянул, что вакуум должен запускаться не только после обновлений или удалений, но и после вставок. Вот соответствующая часть разговора:

http://www.youtube.com/watch?v=tZXp19q8RFo&t=16m2s

Предположительно, существует некоторая очистка, которая должна быть выполнена для блоков, даже если они только получили вставки, и эта очистка может быть выполнена либо при первом выборе блока (замедление чтения), либо во время вакуума. Это правда, и если да, то какая именно очистка должна быть сделана?

foobar0100
источник

Ответы:

15

tl; dr: первый процесс, который считывает данные после его фиксации, устанавливает биты подсказок. Это испачкает страницу, создавая активность записи. Другая вещь VACUUM(но не другие команды) помечает страницу как полностью видимую, если это необходимо. VACUUMв конечном итоге придется ударить по столу, чтобы заморозить кортежи.

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

Из-за MVCC каждый раз, когда Postgres оценивает, должен ли кортеж быть видимым для запроса, он должен учитывать, была ли зафиксирована транзакция, создавшая кортеж (записанный в скрытом поле xmin), а также некоторые другие критерии. Эта проверка является дорогой, поэтому, как только станет известно, что транзакция видима для всех открытых в настоящее время транзакций, в заголовке кортежа указывается «бит подсказки», указывающий на это. Установка этого бита загрязняет страницу, что означает, что она должна быть записана на диск. Это может быть очень запутанным, если следующая команда для чтения данных - это SELECTвнезапно создавшая большой трафик записи. Запуск VACUUMпосле вставки фиксирует это. Другое важное отличие состоит в том, чтоVACUUMВСЕГДА будет подсказывать кортежи на странице (если она получила блокировку очистки на странице), но большинство других команд будут только подсказывать, если транзакция вставки зафиксирована до ее запуска.

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

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

Из-за того, как работает MVCC, кортежи, которые были вставлены более ~ 2 миллиардов транзакций назад, должны быть помечены как « замороженные ». По умолчанию включается автовакуум, чтобы делать это каждые 200 миллионов транзакций. Запуск ручного вакуума с вакуумом_свободной_мин_установки, установленным в 0 после массовой вставки, может помочь уменьшить влияние этого. Более агрессивно, вы можете бегать VACUUM FREEZEпо столу после вставки. Это «сбросит часы» при следующем сканировании.

Если вы хотите узнать конкретные детали, посмотрите на HEAPTUPLE_LIVEслучай после звонка HeapTupleSatisfiesVacuum()внутрь lazy_scan_heap(). Посмотри и HeapTupleSatisfiesVacuum()сам, и сравни с ним HeapTupleSatisfiesMVCC().

Есть еще две мои презентации, которые могут быть интересными. Первое видео доступно с http://www.pgcon.org/2015/schedule/events/829.en.html , а второе (которое, я думаю, было немного лучше) на https://www.youtube. ком / часы? v = L8nErzxPJjQ

Джим Насби
источник
Это очень интересно, а также объясняет некоторые грязные страницы в некоторых EXPLAIN (ANALYZE, BUFFERS) outputs. But, if I understand things correctly, some of the hint bits (at least * COMMITTED` и *INVALID) может (может) уже быть установлен COMMITили ROLLBACK, верно?
Дезсо
3
COMMIT и ROLLBACK на самом деле не касаются страниц данных, поэтому нет, эти команды, в частности, никогда не намекают. Команда DML может по-прежнему устанавливать состояния подсказок xmin и xmax либо для кортежей, отмеченных другими транзакциями, либо потенциально даже для кортежей, отмеченных текущей транзакцией.
Джим Насби