PostgreSQL. Почему самая старая активная транзакция может удерживать строки от очистки vacuum?
Есть ли здесь те кто хорошо разбирается в том как работает postgresql? Сейчас читаю книгу "PostgreSQL изнутри" + статьи на хабре. Пытаюсь осмыслить то как работает vacuum и как он связан с горизонтом событий (xmin horizon).
Допустим, есть таблица my_table с одной колонкой val. Вставляем в нее строку:
insert into my_table values ('A');
Обновляем значение:
update my_table set val='B';
Открываем транзакцию в другом терминале и не закрываем. Предположим что она не является виртуальной и ее номер 806.
Возвращаемся к предыдущему терминалу и снова обновляем значение в таблице:
update my_table set val='C';
В итоге получаем одну актуальную строку и две мертвых:
xmin xmax val
804 805 A
805 807 B
807 0 C
Делаем vacuum:
vacuum verbose my_table;
Казалось бы, что вакуум должен очистить строки со значениями A и B. Но он прошелся только по строке A.
xmin xmax val
пусто пусто пусто
805 807 B
807 0 C
Не понимаю почему нельзя очистить и строку B, если транзакция 807 уже завершена?
Ответы (1 шт):
Потому что vacuum вычисляет и учитывает в очищении dead tuples только данные старше самой старой известной транзакции - данные, которые точно никто не может больше прочитать. А вот сколько и где транзакций запущено, которые новее этого вычисленного горизонта? Горизонт дополнительно ограничивают потенциально существующие места, где ещё могут быть чтения старых данных: реплики, слоты логической репликации, prepared transactions.
Это у вас в примере, проанализировав все возможные транзакции, человеку понятно, что нет ни одной активной транзакции, которая может прочитать тапл B. vacuum не располагает такими сведениями. И не может знать, например, какие транзакции запущены на репликах: hot_standby_feedback если включен, то присылает аналогично возраст самой старой свой транзакции. А если выключен? Тогда репликами в принципе невозможно пользоваться для выполнения запросов. Оп, запрос на реплике вдруг не нашёл данных платежей (если бы vacuum пытался вычислить все активные транзакции и, ничего не зная про эту реплику, успешно вычистил таплы, а тут они как раз и были нужны), отчёт с фактическими ошибками, боль, штрафы от налоговой и прочее прикладное счастье.
Если погружаться фундаментально - то Transactional Information Systems, by Gerhard Weikum and Gottfried Vossen, Morgan Kaufmann.