Имея уровень изоляции READ COMMITTED, незанятые транзакции, выполнившие операцию записи, не позволят вакуумировать мертвые строки для таблиц, в которые была записана транзакция.
Это очевидно для таблиц, которые были написаны транзакциями, которые все еще выполняются. Здесь вы можете найти хорошее объяснение.
Но мне непонятно, почему это ограничение влияет и на любые другие таблицы.
Например: транзакция T запускается и обновляет таблицу B, вакуум выполняется для таблицы A, пока T находится в состоянии «простаивает в транзакции». Почему в этом случае мертвые строки в A нельзя удалить?
Вот что я сделал:
# show default_transaction_isolation;
default_transaction_isolation
-------------------------------
read committed
(1 row)
# create table a (v int);
CREATE TABLE
# create table b (v int);
CREATE TABLE
# insert into a values (generate_series(1,1000));
INSERT 0 1000
На этом этапе я делаю обновление, чтобы сгенерировать новые 1000 мертвых строк.
# update a set v = v + 1;
UPDATE 1000
Чистка пылесосом удалит их, как и ожидалось:
# vacuum verbose a;
INFO: vacuuming "public.a"
INFO: "a": removed 1000 row versions in 5 pages
INFO: "a": found 1000 removable, 1000 nonremovable row versions in 9 out of 9 pages
DETAIL: 0 dead row versions cannot be removed yet.
There were 0 unused item pointers.
0 pages are entirely empty.
CPU 0.00s/0.00u sec elapsed 0.00 sec.
VACUUM
Теперь я начинаю запись транзакции T в таблице b:
# begin;
BEGIN
# insert into b values (generate_series(1,1000));
INSERT 0 1000
Я снова генерирую больше мертвых строк в другой транзакции T1, которая началась после T:
# begin;
# update a set v = v + 1;
# commit;
В другой транзакции:
# vacuum verbose a;
INFO: vacuuming "public.a"
INFO: "a": found 0 removable, 2000 nonremovable row versions in 9 out of 9 pages
DETAIL: 1000 dead row versions cannot be removed yet.
There were 34 unused item pointers.
0 pages are entirely empty.
CPU 0.00s/0.00u sec elapsed 0.00 sec.
VACUUM
Это релевантная часть: ПОДРОБНЕЕ: 1000 мертвых версий еще нельзя удалить.
Если я фиксирую транзакцию T и снова выполняю вакуум, я удаляю мертвые строки, как и ожидалось:
# vacuum verbose a;
INFO: vacuuming "public.a"
INFO: "a": removed 1000 row versions in 5 pages
INFO: "a": found 1000 removable, 1000 nonremovable row versions in 9 out of 9 pages
DETAIL: 0 dead row versions cannot be removed yet.
There were 34 unused item pointers.
0 pages are entirely empty.
CPU 0.00s/0.00u sec elapsed 0.00 sec.
VACUUM
INFO: "a": found 0 removable, 0 nonremovable row versions in 0 out of 9 pages
поделитесь своей версией и создайте сценарий в скрипте rexter или sql (извините - не уверен насчет имен сайтов - где угодно в общем env) - person Vao Tsun   schedule 08.09.2017PostgreSQL 9.4.8 on x86_64-unknown-linux-gnu, compiled by gcc (Ubuntu 5.2.1-22ubuntu2) 5.2.1 20151010, 64-bit
- person alostale   schedule 08.09.2017