Аппаратура пока несовершенна и данные могут быть повреждены на носителе, при передаче данных по интерфейсным кабелям и т.п.
Часть таких ошибок обрабатывается на аппаратном уровне, но часть — увы нет.
Чтобы вовремя обнаружить возникшую проблему, в PostgreSQL журнальные записи всегда снабжаются контрольными суммами.
Страницы данных также можно защитить контрольными суммами.
Как это сделать? Читаем ниже.
Исходные данные: Кластер PostgreSQL 12
Задача: Включить защиту страниц данных контрольными суммами.
Включить защиту страниц данных контрольными суммами можно сделать только при инициализации кластера, но в версии PostgreSQL 12 ее можно включать и выключать с помощью утилиты pg_checksums (правда, пока не «на лету», а только при остановленном кластер).
В производственной среде контрольные суммы обязательно должны быть включены, несмотря на накладные расходы на их вычисление и контроль. Это уменьшает вероятность того, что сбой не будет вовремя обнаружен.
ВАЖНО! Включение контрольных сумм на большом кластере может занять до нескольких часов, помните про это и планируйте простой в связи с этим.
Вначале убедимся, что ведение контрольных сумм выключено:
su - postgres -c 'psql -c "SHOW data_checksums;"'
Если выведет off, то ведение контрольных сумм выключено:
data_checksums ---------------- off (1 row)
Теперь останавливаем кластер для включения контрольных сумм:
pg_ctlcluster 12 main stop
Проверяем:
su - postgres -c '/usr/lib/postgresql/12/bin/pg_controldata -D "/var/lib/postgresql/12/main"' | grep state
Если выведет:
Database cluster state: shut down
, то можно включать контрольные суммы:
su - postgres -c '/usr/lib/postgresql/12/bin/pg_checksums --enable -D "/var/lib/postgresql/12/main"'
Утилиты pg_checksums выведет такое сообщение:
Checksum operation completed Files scanned: 961 Blocks scanned: 2996 pg_checksums: syncing data directory pg_checksums: updating control file Checksums enabled in cluster
Это означает, что защита страниц данных контрольными суммами включена.
Запускаем кластер:
pg_ctlcluster 12 main start
Проверяем включение контрольных сумм:
su - postgres -c 'psql -c "SHOW data_checksums;"'
Должно вывести:
data_checksums ---------------- on (1 row)
Так же можно проверить включение контрольных сумм с помощью утилиты pg_controldata:
su - postgres -c '/usr/lib/postgresql/12/bin/pg_controldata -D "/var/lib/postgresql/12/main" | grep checksum'
Должно вывести:
Data page checksum version: 1
В дальнейшем очень важно контролировать количество ошибок контрольных сумм в страницах данных с помощью какой-то системы мониторинга, иначе Вы не сможете во время узнать о появлении ошибок и произвести исправление данных. Для контроля нужно использовать представление pg_stat_database и проверять значение столбцов datname (Имя базы данных), checksum_failures (Количество ошибок контрольных сумм в страницах данных этой базы (или общего объекта) либо NULL, если контрольные суммы не проверяются) и checksum_last_failure (Время выявления последней ошибки контрольной суммы в страницах данных этой базы (или общего объекта) либо NULL, если контрольные суммы не проверяются)
Пример запроса для проверки наличия ошибок:
SELECT datname, checksum_failures, checksum_last_failure FROM pg_stat_database WHERE datname IS NOT NULL;
На этом все, до скорых встреч. Если у Вас возникли вопросы или Вы хотите чтобы я помог Вам, то Вы всегда можете связаться со мной разными доступными способами.
Профессионально занимаюсь системным администрированием Linux -серверов и баз данных (MySQL, POstgreSQL) на протяжении последних 24 лет.
а если checksum включены, но не пишутся? В pg_stat_database не появилась колонка checksum_failures.
как такое лечится?
Добрый день, она там должны быть, если ее нет, то значит ваша версия Pg в принципе не поддерживает контрольные суммы для страниц данных.
Выполните:
checksum_failures — Количество ошибок контрольных сумм в страницах данных конкретной базы, должно быть 0, если там NULL — то контрольные суммы не проверяются, то есть Вы их не включили или кластер был инициализирован без контрольных сумм в страницах данных.
checksum_last_failure — Время выявления последней ошибки контрольной суммы в страницах данных конкретной базы (или общего объекта) или NULL, если контрольные суммы не проверяются.
SQL Error [42703]: ERROR: column «checksum_failures» does not exist
покажите вывод команды
SELECT version();
Спасибо за интересную статью.
Подскажите, пожалуйста, при старте кластера проверка отличается от проверки утилитой pg_checksums -c ?
Я руками изменил один файл при выключенном кластере.
pg_checksums -с выдаёт ошибку, а кластер стартует без ошибок.
При старте кластера контрольные суммы не проверяются. Проверка контрольной суммы на странице данных происходит при обращении к ней (чтение) и если контр. сумма в странице не сойдется, то будет выдана ошибка и произведено увеличение счетчика ошибок контрольных сумм который можно посмотреть через представление pg_stat_database (checksum_failures и checksum_last_failure).
Большое спасибо!