pg_freeze_recovery. Ручная коррекция работы VACUUM
В исходном дистрибутиве установлено по умолчанию: нет.
Связанные компоненты: отсутствуют.
Схема размещения:
ext
.Расширение считается устаревшим, рекомендуется использовать
pg_surgery
.
Модуль pg_freeze_recovery
предоставляет функцию для ручной коррекции работы VACUUM. Расширение предназначено для исправления ситуации вида:
vacuumdb: error: processing of database "stmnt3_sh1" failed: ERROR: found xmin 1287773215 from before relfrozenxid 1296057024
CONTEXT: while scanning block 313483885
В расширении предусмотрена функция freeze_page(regclass, tid)
. Для использования в скрипте вызов производится следующим образом:
SELECT freeze_page('table1','(5405,188)');
На вход подается имя таблицы, идентификатор записи (tid
): номер страницы и смещение на странице записи. Для использования расширения pg_freeze_recovery
необходимо наличие в БД предварительно установленного расширения pageinspect
. Предполагается, что pg_freeze_recovery
корректно работает с wal
- выполняется запись и смещение LSN
вперед.
Крайне рекомендуется во время использования pg_freeze_recovery
отключать автоочистку:
ALTER SYSTEM SET autovacuum = off;
Доработка
Доработка не проводилась.
Ограничения
Эти freeze_page
спроектирована как небезопасная и ее использование может привести к повреждению (или дальнейшему повреждению) базы данных, например: к несогласованности таблицы с ее собственными индексами, к нарушению уникальности или внешнего ключа, к видимымости строк, чтение которых приведет к сбою сервера базы данных. Ее следует использовать с большой осторожностью и только в качестве крайней меры.
Установка
При наличии прав администратора СУБД включение модуля выполняется запросом:
CREATE EXTENSION pg_freeze_recovery SCHEMA ext;
Настройка
Настройка не требуется.
Использование модуля
VACUUM -a -F
Пример вывода результата запроса:
vacuumdb: vacuuming database "db0"
vacuumdb: error: processing of database "db0" failed ERROR: found xmin 727 from before relfrozenxid 743
CONTEXT: while scanning block 0 offset 2 of relation "pg_catalog.pg_shdescription"
Вывод показывает наличие незамороженных строк до горизонта заморозки (743). Горизонт заморозки также можно получить запросом:
SELECT relfrozenxid FROM pg_class WHERE oid = 'pg_catalog.pg_shdescription'::regclass;
Пример вывода результата запроса:
relfrozenxid
--------------
512
(1 row)
Список tid
незамороженных записей до горизонта заморозки («сломанных») можно получить запросом:
SELECT t_ctid
FROM generate_series(0, pg_relation_size('pg_catalog.pg_shdescription')/8192 - 1) s(i)
LEFT JOIN
LATERAL heap_page_items(get_raw_page('pg_catalog.pg_shdescription', s.i::int)) ON true
WHERE t_xmin::text::bigint < 512 AND
t_infomask & X'0300'::int <> X'0300'::int;
Пример вывода результата запроса:
t_cid
-------------
(123456,65)
(123456,66)
(123456,67)
(123456,68)
(123456,69)
(123456,70)
(5 rows)
Скрипт для починки отношения можно подготовить с помощью запроса:
SELECT 'SELECT freeze_page(''pg_catalog.pg_shdescription'', '''||t_ctid||''');'
FROM generate_series(0, pg_relation_size('pg_catalog.pg_shdescription')/8192 - 1) s(i)
LEFT JOIN
LATERAL heap_page_items(get_raw_page('pg_catalog.pg_shdescription', s.i::int)) ON true
WHERE t_xmin::text::bigint < 512 AND
t_infomask & X'0300'::int <> X'0300'::int;
Пример вывода результата запроса:
?column?
--------------------------------------------------------------------
SELECT freeze_page('pg_catalog.pg_shdescription', '(123456,65)');
SELECT freeze_page('pg_catalog.pg_shdescription', '((123456,66)');
SELECT freeze_page('pg_catalog.pg_shdescription', '((123456,67)');
SELECT freeze_page('pg_catalog.pg_shdescription', '((123456,68)');
SELECT freeze_page('pg_catalog.pg_shdescription', '((123456,69)');
SELECT freeze_page('pg_catalog.pg_shdescription', '((123456,70)');
(5 rows)
Выполните фриз полученным скриптом.
Пример вывода результата запроса:
freeze_page
-------------
t
(1 rows)