F.2. amcheck
Модуль amcheck предоставляет функции, позволяющие проверять логическую целостность структуры отношений.
Функции проверки B-дерева контролируют различные инварианты в структуре представления определённых отношений. Правильность работы функций методов доступа, стоящих за сканированием индекса и другими важными операциями, зависит от всегда соблюдаемых инвариантов. Например, определённые функции проверяют, помимо остальных вещей, что все страницы B-дерева содержат элементы в «логическом» порядке (например, индекс-B-дерево, построенный по столбцу text, должен содержать кортежи, упорядоченные в лексическом порядке с учётом правила сортировки). Если этот конкретный инвариант каким-то образом нарушается, следует ожидать, что бинарный поиск на затронутой странице введёт в заблуждение процедуру сканирования индекса, что приведёт к неверным результатам запросов SQL. Если нарушения структуры не обнаруживаются, эти функции отрабатывают без ошибок.
Проверка выполняется теми же процедурами, что используются при сканировании индекса, и это может быть код пользовательского класса операторов. Например, проверка индекса-B-дерева задействует сравнения, выполняемые одной или несколькими опорными функциями B-дерева под номером 1. Подробнее опорные функции класса операторов описываются в Подразделе 37.16.3.
В отличие от функций проверки B-дерева, которые сообщают о повреждениях, выдавая ошибки, функция проверки кучи verify_heapam проверяет таблицу и пытается вернуть набор строк: по одной строке на каждое обнаруженное повреждение. Тем не менее, если будут повреждены средства, которые использует функция verify_heapam, она не сможет продолжить работу и выдаст ошибку.
Права на выполнение функций amcheck можно выдать и не суперпользователю, но перед этим следует тщательно учесть аспекты безопасности и конфиденциальности данных. Хотя эти функции прежде всего выдают информацию о структуре данных и характере найденных повреждений, а не выводят собственно повреждённые данные, если злоумышленник сможет выполнять эти функции, а особенно если ему также удастся вызвать повреждение данных, он сможет узнать что-то о самих данных из полученной информации.
F.2.1. Функции
-
bt_index_check(index regclass, heapallindexed boolean) returns void bt_index_checkпроверяет, соблюдаются ли в целевом индексе-B-дереве различные инварианты. Пример использования:test=# SELECT bt_index_check(index => c.oid, heapallindexed => i.indisunique), c.relname, c.relpages FROM pg_index i JOIN pg_opclass op ON i.indclass[0] = op.oid JOIN pg_am am ON op.opcmethod = am.oid JOIN pg_class c ON i.indexrelid = c.oid JOIN pg_namespace n ON c.relnamespace = n.oid WHERE am.amname = 'btree' AND n.nspname = 'pg_catalog' -- Не проверять временные таблицы (они могут относиться к другим сеансам): AND c.relpersistence != 't' -- Функция может выдать ошибку без этих условий: AND c.relkind = 'i' AND i.indisready AND i.indisvalid ORDER BY c.relpages DESC LIMIT 10; bt_index_check | relname | relpages ----------------+---------------------------------+---------- | pg_depend_reference_index | 43 | pg_depend_depender_index | 40 | pg_proc_proname_args_nsp_index | 31 | pg_description_o_c_o_index | 21 | pg_attribute_relid_attnam_index | 14 | pg_proc_oid_index | 10 | pg_attribute_relid_attnum_index | 9 | pg_amproc_fam_proc_index | 5 | pg_amop_opr_fam_index | 5 | pg_amop_fam_strat_index | 5 (10 rows)Этот пример демонстрирует сеанс проверки 10 самых больших индексов системных каталогов в базе данных «test». Проверка всех кортежей кучи на предмет наличия соответствующих кортежей индекса запрашивается только для тех из этих индексов, которые являются уникальными. Так как ошибки не было, все проверенные индексы представляются логически целостными. Естественно, этот запрос можно легко изменить, чтобы функция
bt_index_checkвызывалась для всех индексов в базе, которые поддерживают эту проверку.Функция
bt_index_checkзапрашивает блокировкуAccessShareLockдля целевого индекса и отношения, которому он принадлежит. Это тот же режим блокировки, что запрашивается для отношений обычными операторамиSELECT.bt_index_checkне проверяет инварианты, существующие в иерархии потомок/родитель, но проверяет представление всех кортежей кучи в индексе в виде индексных кортежей, когда параметрheapallindexedравенtrue. Когда в работающей производственной среде требуется регулярная лёгкая проверка на наличие нарушений, использованиеbt_index_checkчасто будет подходящим компромиссом между полнотой проверки и минимизацией влияния на производительность и доступность приложения.-
bt_index_parent_check(index regclass, heapallindexed boolean, rootdescend boolean) returns void Функция
bt_index_parent_checkпроверяет, соблюдаются ли в целевом объекте, индексе-B-дереве, различные инварианты. Кроме того, если аргументheapallindexedравенtrue, эта функция проверяет наличие в индексе всех кортежей из кучи, которые должны в него попасть. Когда необязательный параметрrootdescendравенtrue, при проверке для каждого кортежа на уровне листьев производится ещё один поиск, начиная с корневой страницы. Проверки, которые может производитьbt_index_parent_check, включают в себя все проверки, выполняемые функциейbt_index_check. Функциюbt_index_parent_checkможно считать более полноценным вариантомbt_index_check: в отличие отbt_index_check,bt_index_parent_checkпроверяет ещё и инварианты, существующие в иерархии родитель/потомок, в том числе отсутствие потерянных связей в структуре индекса.bt_index_parent_checkследует общему соглашению и выдаёт ошибку в случае обнаружения логической несогласованности или другой проблемы.Функция
bt_index_parent_checkзапрашивает в целевом индексе блокировкуShareLock(такжеShareLockзапрашивается и в основном отношении). Эти блокировки предотвращают одновременное изменение данных командамиINSERT,UPDATEиDELETE. Эти блокировки также препятствуют одновременной обработке нижележащего отношения командойVACUUMи другими вспомогательными командами. Заметьте, что эта функция удерживает блокировки только во время выполнения, а не на протяжении всей транзакции.Дополнительные проверки, проводимые функцией
bt_index_parent_check, более ориентированы на выявление различных патологических случаев. В том числе это может быть неправильно реализованный класс операторов B-дерева, используемый проверяемым индексом, или, гипотетически, неизвестные ошибки в нижележащем коде метода доступа индекса-B-дерева. Заметьте, что функциюbt_index_parent_checkнельзя применять, когда включён режим горячего резерва (то есть на физических репликах в режиме «только чтение»), в отличие отbt_index_check.
Подсказка
Функции bt_index_check и bt_index_parent_check выводят отладочные сообщения о процессе проверки на уровнях важности DEBUG1 и DEBUG2. Эти сообщения содержат подробные сведения о проверке, которые могут представлять интерес для разработчиков PostgreSQL. Они могут быть полезны и для опытных пользователей в качестве дополнительного контекста в случае обнаружения несогласованности. Чтобы получать сообщения о процессе проверки с подходящим уровнем детализации, выполните до запуска проверяющего запроса в интерактивном psql:
SET client_min_messages = DEBUG1;
-
verify_heapam(relation regclass, on_error_stop boolean, check_toast boolean, skip text, startblock bigint, endblock bigint, blkno OUT bigint, offnum OUT integer, attnum OUT integer, msg OUT text) returns setof record Проверяет таблицу, последовательность или материализованное представление на наличие структурных повреждений (когда страницы отношения содержат данные в неправильном формате) и логических повреждений (когда структура страниц не повреждена, но и не соответствует остальной части кластера).
В качестве необязательных аргументов принимаются:
on_error_stopЕсли true, проверка на наличие повреждений останавливается в конце первого блока, в котором обнаружены какие-либо повреждения.
По умолчанию false.
check_toastЕсли true, поля TOAST проверяются по TOAST-таблице целевого отношения.
Эта проверка может быть длительной. Кроме того, если TOAST-таблица или её индекс повреждены, проверка TOAST-полей потенциально может привести к сбою в работе сервера, хотя во многих случаях это просто вызовет ошибку.
По умолчанию false.
skipЕсли указано значение, отличное от
none, проверка на наличие повреждений пропускает блоки, которые помечены как полностью видимые или полностью замороженные, в зависимости от указанного значения. Допустимые варианты:all-visible,all-frozenиnone.По умолчанию
none.startblockЕсли этот параметр задан, проверка на наличие повреждений начинается с указанного блока и пропускает все предыдущие блоки. Если в
startblockуказано значение вне диапазона блоков целевой таблицы, выдаётся ошибка.По умолчанию проверка начинается с первого блока.
endblockЕсли этот параметр задан, проверка на наличие повреждений заканчивается на указанном блоке и пропускает все оставшиеся блоки. Если в
endblockуказано значение вне диапазона блоков целевой таблицы, выдаётся ошибка.По умолчанию проверяются все блоки.
Для каждого обнаруженного повреждения
verify_heapamвозвращает строку со следующими столбцами:blknoНомер блока, содержащего повреждённую страницу.
offnumНомер смещения повреждённого кортежа.
attnumНомер атрибута повреждённого столбца в кортеже, если повреждён именно столбец, а не весь кортеж.
msgСообщение с описанием выявленной ошибки.
F.2.2. Дополнительная проверка heapallindexed
Когда аргумент heapallindexed функций проверки B-дерева равен true, для таблицы, связанной с отношением целевого индекса, добавляется дополнительная фаза проверки. Она включает «фиктивную» операцию CREATE INDEX CONCURRENTLY, которая проверяет присутствие всех гипотетических новых индексных кортежей по временной сводной структуре в памяти (она создаётся при необходимости на первом этапе проверки). Сводная структура «помечает» каждый кортеж, который находится в целевом индексе. На высоком уровне идея проверки heapallindexed состоит в том, чтобы убедиться, что новый индекс, равнозначный целевому, содержит только те записи, которые можно найти в существующей структуре.
С дополнительным этапом heapallindexed связаны значительные издержки: проверка обычно будет выполняться в несколько раз дольше. Однако никакие новые блокировки уровня отношения при проверке heapallindexed не запрашиваются.
Сводная структура ограничивается по объёму значением maintenance_work_mem. Для выявления несогласованности в представленных в индексе кортежах с вероятностью упущений в пределах 2% требуется приблизительно 2 байта памяти на кортеж. По мере уменьшения объёма памяти в пересчёте на кортеж этот процент медленно растёт. Этот подход значительно ограничивает издержки такой проверки, и при этом лишь немного уменьшается вероятность выявления проблемы, особенно в инсталляциях, где эта проверка включена в процедуру регулярного обслуживания. Даже если единичное отсутствие или повреждение кортежа упущено, есть все шансы выявить его при очередной проверке.
F.2.3. Эффективное использование amcheck
Модуль amcheck может быть полезен для выявления различных типов проблем, которые могут остаться незамеченными при включении контрольных сумм страниц данных. В частности это:
Структурные несоответствия, возникающие при некорректной реализации класса операторов.
В том числе это проблемы, возникающие при изменении правил сравнения в операционной системе. Сравнения данных сортируемого типа, например
text, должны быть постоянными (как и все сравнения, применяемые при сканировании индекса-B-дерева), что подразумевает неизменность правил сортировки в операционной системе. Проблемы могут возникать при обновлениях правил в операционной системе, хотя такие случаи редки. Чаще проявляются несоответствия порядка сортировки между ведущим и ведомым сервером, например, из-за различий основных версий используемых операционных систем. Возникающие расхождения обычно наблюдаются только на ведомых серверах, так что и выявить их обычно можно только на них.Когда возникает подобная проблема, она может затрагивать не абсолютно все индексы, построенные с порочным правилом сортировки, просто потому что индексированные значения могут иметь тот же абсолютный порядок, независящий от различий поведения. За дополнительными сведениями об использовании в Postgres Pro правил сортировки и локалей операционной системы обратитесь к Разделу 22.1 и Разделу 22.2.
Несоответствия структуры между индексами и проиндексированными отношениями в куче (когда выполняется проверка
heapallindexed).Во время обычных операций перекрёстная проверка индексов по отношениям в куче не производится. Симптомы повреждения данных в куче могут быть неочевидными.
Повреждения, вызванные гипотетическими неизвестными ошибками в нижележащем коде методов доступа, коде сортировки и управления транзакциями Postgres Pro.
Автоматическая проверка структурной целостности индексов играет важную роль в общем тестировании новых или предлагаемых возможностей Postgres Pro, с которыми может возникнуть логическая несогласованность. Такую же роль играет проверка структуры таблицы и связанной информации о видимости и состоянии транзакций. И поэтому одна из очевидных стратегий тестирования — регулярно вызывать функции
amcheckпри проведении стандартных регрессионных тестов.Ошибки в файловой системе или подсистеме хранения, когда просто не включены контрольные суммы.
Заметьте, что
amcheckрассматривает страницу в том виде, как она представлена в некотором буфере разделяемой памяти к моменту проверки, если при обращению к нужному блоку он уже находится в разделяемом буфере. Вследствие этого,amcheckне обязательно видит данные, находящиеся в файловой системе в момент проверки. Заметьте, что когда контрольные суммы включены,amcheckможет выдать ошибку из-за несоответствия контрольных сумм, если в буфер будет считываться испорченный блок.Повреждения, вызванные дефектными чипами ОЗУ или вообще подсистемой памяти.
Postgres Pro не защищает от ошибок памяти; предполагается, что в эксплуатируемом вами сервере установлена память с ECC (Error Correcting Codes, Коды исправления ошибок) или лучшая защита. Однако память ECC обычно защищает только от ошибок в одном бите и не следует считать её абсолютной защитой от сбоев, приводящих к повреждению памяти.
Когда выполняется проверка
heapallindexed, в целом значительно увеличивается шанс выявления ошибок в отдельных битах, так как она тестирует точное двоичное равенство и сверяет проиндексированные атрибуты с кучей.
Причиной повреждения структуры данных может стать неисправность оборудования или же перезапись или изменение файлов отношения сторонним ПО. Этот вид повреждения также можно обнаружить с помощью контрольных сумм страниц данных.
Даже если страницы отношений имеют правильный формат, их внутренняя структура не повреждена и данные соответствуют контрольной сумме, это не гарантирует отсутствие логических повреждений. Повреждения такого типа невозможно обнаружить с помощью контрольных сумм. Примеры: значения TOAST в основной таблице, для которых нет соответствующей записи в таблице TOAST; кортежи в основной таблице с идентификатором транзакции, который старше, чем самый старый действительный идентификатор транзакции в базе данных или кластере.
В производственных системах выявляются разнообразные причины логических повреждений: ошибки в серверном ПО PostgreSQL, неисправные и непродуманные инструменты резервного копирования и восстановления, ошибки пользователей.
Повреждение отношений особенно опасно в работающей производственной среде, то есть в той среде, где высокий риск совсем нежелателен. Поэтому для диагностики повреждения данных без излишнего риска была разработана функция verify_heapam. Она не может обеспечить защиту от всех сбоев сервера, так как даже выполнение вызывающего запроса может быть небезопасным на сильно повреждённой системе. Если сами каталоги повреждены, то вероятны проблемы с доступом к таблицам.
Вообще говоря, amcheck может доказать только наличие повреждений, но не доказать их отсутствие.
F.2.4. Исправление повреждений
Когда amcheck сигнализирует о повреждении данных, ложные срабатывания практически исключены. amcheck считает ошибочными ситуации, которые никогда не должны наблюдаться по определению, поэтому ошибки amcheck, как правило, требуют тщательного анализа.
Общего метода устранения проблем, которые может выявить amcheck, не существует. Начать нужно с поиска корня проблемы, приводящей к нарушению инварианта. Полезную роль в диагностике повреждений, которые выявляет amcheck, может сыграть pageinspect. Одна лишь команда REINDEX может быть неэффективна, когда потребуется исправить повреждения.
F.2. amcheck
The amcheck module provides functions that allow you to verify the logical consistency of the structure of relations.
The B-Tree checking functions verify various invariants in the structure of the representation of particular relations. The correctness of the access method functions behind index scans and other important operations relies on these invariants always holding. For example, certain functions verify, among other things, that all B-Tree pages have items in “logical” order (e.g., for B-Tree indexes on text, index tuples should be in collated lexical order). If that particular invariant somehow fails to hold, we can expect binary searches on the affected page to incorrectly guide index scans, resulting in wrong answers to SQL queries. If the structure appears to be valid, no error is raised.
Verification is performed using the same procedures as those used by index scans themselves, which may be user-defined operator class code. For example, B-Tree index verification relies on comparisons made with one or more B-Tree support function 1 routines. See Section 37.16.3 for details of operator class support functions.
Unlike the B-Tree checking functions which report corruption by raising errors, the heap checking function verify_heapam checks a table and attempts to return a set of rows, one row per corruption detected. Despite this, if facilities that verify_heapam relies upon are themselves corrupted, the function may be unable to continue and may instead raise an error.
Permission to execute amcheck functions may be granted to non-superusers, but before granting such permissions careful consideration should be given to data security and privacy concerns. Although the corruption reports generated by these functions do not focus on the contents of the corrupted data so much as on the structure of that data and the nature of the corruptions found, an attacker who gains permission to execute these functions, particularly if the attacker can also induce corruption, might be able to infer something of the data itself from such messages.
F.2.1. Functions
-
bt_index_check(index regclass, heapallindexed boolean) returns void bt_index_checktests that its target, a B-Tree index, respects a variety of invariants. Example usage:test=# SELECT bt_index_check(index => c.oid, heapallindexed => i.indisunique), c.relname, c.relpages FROM pg_index i JOIN pg_opclass op ON i.indclass[0] = op.oid JOIN pg_am am ON op.opcmethod = am.oid JOIN pg_class c ON i.indexrelid = c.oid JOIN pg_namespace n ON c.relnamespace = n.oid WHERE am.amname = 'btree' AND n.nspname = 'pg_catalog' -- Don't check temp tables, which may be from another session: AND c.relpersistence != 't' -- Function may throw an error when this is omitted: AND c.relkind = 'i' AND i.indisready AND i.indisvalid ORDER BY c.relpages DESC LIMIT 10; bt_index_check | relname | relpages ----------------+---------------------------------+---------- | pg_depend_reference_index | 43 | pg_depend_depender_index | 40 | pg_proc_proname_args_nsp_index | 31 | pg_description_o_c_o_index | 21 | pg_attribute_relid_attnam_index | 14 | pg_proc_oid_index | 10 | pg_attribute_relid_attnum_index | 9 | pg_amproc_fam_proc_index | 5 | pg_amop_opr_fam_index | 5 | pg_amop_fam_strat_index | 5 (10 rows)This example shows a session that performs verification of the 10 largest catalog indexes in the database “test”. Verification of the presence of heap tuples as index tuples is requested for the subset that are unique indexes. Since no error is raised, all indexes tested appear to be logically consistent. Naturally, this query could easily be changed to call
bt_index_checkfor every index in the database where verification is supported.bt_index_checkacquires anAccessShareLockon the target index and the heap relation it belongs to. This lock mode is the same lock mode acquired on relations by simpleSELECTstatements.bt_index_checkdoes not verify invariants that span child/parent relationships, but will verify the presence of all heap tuples as index tuples within the index whenheapallindexedistrue. When a routine, lightweight test for corruption is required in a live production environment, usingbt_index_checkoften provides the best trade-off between thoroughness of verification and limiting the impact on application performance and availability.-
bt_index_parent_check(index regclass, heapallindexed boolean, rootdescend boolean) returns void bt_index_parent_checktests that its target, a B-Tree index, respects a variety of invariants. Optionally, when theheapallindexedargument istrue, the function verifies the presence of all heap tuples that should be found within the index. When the optionalrootdescendargument istrue, verification re-finds tuples on the leaf level by performing a new search from the root page for each tuple. The checks that can be performed bybt_index_parent_checkare a superset of the checks that can be performed bybt_index_check.bt_index_parent_checkcan be thought of as a more thorough variant ofbt_index_check: unlikebt_index_check,bt_index_parent_checkalso checks invariants that span parent/child relationships, including checking that there are no missing downlinks in the index structure.bt_index_parent_checkfollows the general convention of raising an error if it finds a logical inconsistency or other problem.A
ShareLockis required on the target index bybt_index_parent_check(aShareLockis also acquired on the heap relation). These locks prevent concurrent data modification fromINSERT,UPDATE, andDELETEcommands. The locks also prevent the underlying relation from being concurrently processed byVACUUM, as well as all other utility commands. Note that the function holds locks only while running, not for the entire transaction.bt_index_parent_check's additional verification is more likely to detect various pathological cases. These cases may involve an incorrectly implemented B-Tree operator class used by the index that is checked, or, hypothetically, undiscovered bugs in the underlying B-Tree index access method code. Note thatbt_index_parent_checkcannot be used when hot standby mode is enabled (i.e., on read-only physical replicas), unlikebt_index_check.
Tip
bt_index_check and bt_index_parent_check both output log messages about the verification process at DEBUG1 and DEBUG2 severity levels. These messages provide detailed information about the verification process that may be of interest to PostgreSQL developers. Advanced users may also find this information helpful, since it provides additional context should verification actually detect an inconsistency. Running:
SET client_min_messages = DEBUG1;
in an interactive psql session before running a verification query will display messages about the progress of verification with a manageable level of detail.
-
verify_heapam(relation regclass, on_error_stop boolean, check_toast boolean, skip text, startblock bigint, endblock bigint, blkno OUT bigint, offnum OUT integer, attnum OUT integer, msg OUT text) returns setof record Checks a table, sequence, or materialized view for structural corruption, where pages in the relation contain data that is invalidly formatted, and for logical corruption, where pages are structurally valid but inconsistent with the rest of the database cluster.
The following optional arguments are recognized:
on_error_stopIf true, corruption checking stops at the end of the first block in which any corruptions are found.
Defaults to false.
check_toastIf true, toasted values are checked against the target relation's TOAST table.
This option is known to be slow. Also, if the toast table or its index is corrupt, checking it against toast values could conceivably crash the server, although in many cases this would just produce an error.
Defaults to false.
skipIf not
none, corruption checking skips blocks that are marked as all-visible or all-frozen, as specified. Valid options areall-visible,all-frozenandnone.Defaults to
none.startblockIf specified, corruption checking begins at the specified block, skipping all previous blocks. It is an error to specify a
startblockoutside the range of blocks in the target table.By default, checking begins at the first block.
endblockIf specified, corruption checking ends at the specified block, skipping all remaining blocks. It is an error to specify an
endblockoutside the range of blocks in the target table.By default, all blocks are checked.
For each corruption detected,
verify_heapamreturns a row with the following columns:blknoThe number of the block containing the corrupt page.
offnumThe OffsetNumber of the corrupt tuple.
attnumThe attribute number of the corrupt column in the tuple, if the corruption is specific to a column and not the tuple as a whole.
msgA message describing the problem detected.
F.2.2. Optional heapallindexed Verification
When the heapallindexed argument to B-Tree verification functions is true, an additional phase of verification is performed against the table associated with the target index relation. This consists of a “dummy” CREATE INDEX CONCURRENTLY operation, which checks for the presence of all hypothetical new index tuples against a temporary, in-memory summarizing structure (this is built when needed during the basic first phase of verification). The summarizing structure “fingerprints” every tuple found within the target index. The high level principle behind heapallindexed verification is that a new index that is equivalent to the existing, target index must only have entries that can be found in the existing structure.
The additional heapallindexed phase adds significant overhead: verification will typically take several times longer. However, there is no change to the relation-level locks acquired when heapallindexed verification is performed.
The summarizing structure is bound in size by maintenance_work_mem. In order to ensure that there is no more than a 2% probability of failure to detect an inconsistency for each heap tuple that should be represented in the index, approximately 2 bytes of memory are needed per tuple. As less memory is made available per tuple, the probability of missing an inconsistency slowly increases. This approach limits the overhead of verification significantly, while only slightly reducing the probability of detecting a problem, especially for installations where verification is treated as a routine maintenance task. Any single absent or malformed tuple has a new opportunity to be detected with each new verification attempt.
F.2.3. Using amcheck Effectively
amcheck can be effective at detecting various types of failure modes that data checksums will fail to catch. These include:
Structural inconsistencies caused by incorrect operator class implementations.
This includes issues caused by the comparison rules of operating system collations changing. Comparisons of datums of a collatable type like
textmust be immutable (just as all comparisons used for B-Tree index scans must be immutable), which implies that operating system collation rules must never change. Though rare, updates to operating system collation rules can cause these issues. More commonly, an inconsistency in the collation order between a primary server and a standby server is implicated, possibly because the major operating system version in use is inconsistent. Such inconsistencies will generally only arise on standby servers, and so can generally only be detected on standby servers.If a problem like this arises, it may not affect each individual index that is ordered using an affected collation, simply because indexed values might happen to have the same absolute ordering regardless of the behavioral inconsistency. See Section 22.1 and Section 22.2 for further details about how Postgres Pro uses operating system locales and collations.
Structural inconsistencies between indexes and the heap relations that are indexed (when
heapallindexedverification is performed).There is no cross-checking of indexes against their heap relation during normal operation. Symptoms of heap corruption can be subtle.
Corruption caused by hypothetical undiscovered bugs in the underlying Postgres Pro access method code, sort code, or transaction management code.
Automatic verification of the structural integrity of indexes plays a role in the general testing of new or proposed Postgres Pro features that could plausibly allow a logical inconsistency to be introduced. Verification of table structure and associated visibility and transaction status information plays a similar role. One obvious testing strategy is to call
amcheckfunctions continuously when running the standard regression tests.File system or storage subsystem faults where checksums happen to simply not be enabled.
Note that
amcheckexamines a page as represented in some shared memory buffer at the time of verification if there is only a shared buffer hit when accessing the block. Consequently,amcheckdoes not necessarily examine data read from the file system at the time of verification. Note that when checksums are enabled,amcheckmay raise an error due to a checksum failure when a corrupt block is read into a buffer.Corruption caused by faulty RAM, or the broader memory subsystem.
Postgres Pro does not protect against correctable memory errors and it is assumed you will operate using RAM that uses industry standard Error Correcting Codes (ECC) or better protection. However, ECC memory is typically only immune to single-bit errors, and should not be assumed to provide absolute protection against failures that result in memory corruption.
When
heapallindexedverification is performed, there is generally a greatly increased chance of detecting single-bit errors, since strict binary equality is tested, and the indexed attributes within the heap are tested.
Structural corruption can happen due to faulty storage hardware, or relation files being overwritten or modified by unrelated software. This kind of corruption can also be detected with data page checksums.
Relation pages which are correctly formatted, internally consistent, and correct relative to their own internal checksums may still contain logical corruption. As such, this kind of corruption cannot be detected with checksums. Examples include toasted values in the main table which lack a corresponding entry in the toast table, and tuples in the main table with a Transaction ID that is older than the oldest valid Transaction ID in the database or cluster.
Multiple causes of logical corruption have been observed in production systems, including bugs in the PostgreSQL server software, faulty and ill-conceived backup and restore tools, and user error.
Corrupt relations are most concerning in live production environments, precisely the same environments where high risk activities are least welcome. For this reason, verify_heapam has been designed to diagnose corruption without undue risk. It cannot guard against all causes of backend crashes, as even executing the calling query could be unsafe on a badly corrupted system. Access to catalog tables is performed and could be problematic if the catalogs themselves are corrupted.
In general, amcheck can only prove the presence of corruption; it cannot prove its absence.
F.2.4. Repairing Corruption
No error concerning corruption raised by amcheck should ever be a false positive. amcheck raises errors in the event of conditions that, by definition, should never happen, and so careful analysis of amcheck errors is often required.
There is no general method of repairing problems that amcheck detects. An explanation for the root cause of an invariant violation should be sought. pageinspect may play a useful role in diagnosing corruption that amcheck detects. A REINDEX may not be effective in repairing corruption.