Траблшутинг повреждений страниц PostgreSQL: pg_checksums и amcheck
- Ошибка
ERROR: invalid page in block X of relation "table_name"при чтении строк. - Ошибка
PANIC: right sibling's left-link doesn't match: block Xв индексах B-Tree. - Сбои контрольных сумм страниц
page verification failed, calculated checksum ... expected ....
1. Включение и проверка контрольных сумм (Data Checksums)
Контрольные суммы позволяют выявлять битые биты на диске в момент чтения страницы.
# Остановка инстанса БД
systemctl stop postgresql
# Проверка контрольных сумм всех страниц кластера
sudo -u postgres pg_checksums -c -D /var/lib/postgresql/15/main
# Включение контрольных сумм в оффлайн-режиме (если были выключены)
sudo -u postgres pg_checksums -e -D /var/lib/postgresql/15/main
# Запуск кластера
systemctl start postgresql2. Онлайн-проверка целостности B-Tree индексов с помощью amcheck
-- Подключение расширения
CREATE EXTENSION IF NOT EXISTS amcheck;
-- Глубокая проверка всех индексов схемы public
SELECT c.relname,
bt_index_check(c.oid, true)
FROM pg_index i
JOIN pg_class c ON c.oid = i.indexrelid
JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE c.relam = 403 -- btree
AND n.nspname = 'public'
AND c.relpersistence != 't';3. Восстановление поврежденного индекса
REINDEX TABLE CONCURRENTLY corrupted_table;4. Аварийный пропуск поврежденных страниц таблицы
Если резервной копии нет, а нужно выгрузить уцелевшие данные:
SET zero_damaged_pages = on;
VACUUM corrupted_table;
pg_dump -t corrupted_table mydb > /tmp/salvaged_data.sql;
SET zero_damaged_pages = off; Частые вопросы (FAQ)
Что делает параметр zero_damaged_pages = on?
Он заставляет PostgreSQL при обнаружении поврежденного заголовка страницы заполнять весь 8KB блок нулями вместо падения с ошибкой. Это приводит к потере строк в данном блоке, но позволяет прочитать остальную таблицу.
Влияет ли pg_checksums на производительность базы?
Накладные расходы на расчет CRC32 контрольных сумм при чтении и записи страниц в современных CPU с инструкциями SSE4.2 составляют менее 1–2%.