F.2. amcheck#
F.2. amcheck
Модуль amcheck
предоставляет функции, которые позволяют
проверить логическую согласованность структуры отношений.
Функции проверки B-дерева проверяют различные инварианты в структуре представления конкретных отношений. Правильность функций метода доступа, лежащих в основе индексных сканирований и других важных операций, зависит от того, что эти инварианты всегда выполняются. Например, некоторые функции проверяют, среди прочего, что все страницы B-дерева имеют элементы в “логическом” порядке (например, для индексов B-дерева на типе text
, кортежи индекса должны быть в лексикографическом порядке). Если этот конкретный инвариант по какой-то причине не выполняется, можно ожидать, что бинарные поиски на затронутой странице неправильно направят индексные сканирования, что приведет к неправильным ответам на SQL-запросы. Если структура кажется действительной, ошибки не возникает.
Проверка выполняется с использованием тех же процедур, что и при сканировании индекса, которые могут быть определены пользователем в виде кода класса операторов. Например, проверка индекса B-Tree основана на сравнениях, выполняемых с помощью одной или нескольких функций поддержки B-Tree. См. Раздел 36.15.3 для получения подробной информации о функциях поддержки класса операторов.
В отличие от функций проверки B-дерева, которые сообщают о повреждении, вызывая ошибки, функция проверки кучи verify_heapam
проверяет таблицу и пытается вернуть набор строк, одну строку на каждое обнаруженное повреждение. Несмотря на это, если средства, от которых зависит verify_heapam
, также повреждены, функция может быть неспособна продолжить работу и вместо этого вызовет ошибку.
Разрешение на выполнение функций amcheck
может быть предоставлено не суперпользователям, но перед предоставлением таких разрешений следует тщательно продумать вопросы безопасности данных и конфиденциальности. Хотя отчеты о повреждениях, создаваемые этими функциями, не ставят своей целью содержание поврежденных данных, а скорее структуру этих данных и характер обнаруженных повреждений, злоумышленник, получивший разрешение на выполнение этих функций, особенно если он также может вызвать повреждение, может сделать выводы о самих данных на основе таких сообщений.
F.2.1. Функции
-
bt_index_check(index regclass, heapallindexed boolean) returns void
bt_index_check
проверяет, что его цель, индекс B-Tree, соблюдает различные инварианты. Пример использования: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)
Этот пример показывает сессию, который выполняет проверку 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-Tree, соблюдает различные инварианты. При необходимости, когда аргумент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
следует общему соглашению о вызове ошибки, если он обнаруживает логическое несоответствие или другую проблему.Для целевого индекса требуется
ShareLock
, который проверяется функциейbt_index_parent_check
(также получаетсяShareLock
на связанное отношение кучи). Эти блокировки предотвращают одновременное изменение данных командамиINSERT
,UPDATE
иDELETE
. Блокировки также предотвращают одновременную обработку базового отношения командойVACUUM
, а также всеми другими утилитами. Обратите внимание, что функция удерживает блокировки только во время выполнения, а не на всю транзакцию.Дополнительная проверка
bt_index_parent_check
скорее всего обнаружит различные патологические случаи. Эти случаи могут включать неправильно реализованный класс операторов B-Tree, используемый проверяемым индексом, или, гипотетически, необнаруженные ошибки в коде метода доступа к базовому индексу B-Tree. Обратите внимание, чтоbt_index_parent_check
не может использоваться, когда включен режим горячего резервирования (т.е. на только для чтения физических репликах), в отличие отbt_index_check
.
Подсказка
bt_index_check
и
bt_index_parent_check
оба выводят сообщения журнала
о процессе проверки на уровнях серьезности DEBUG1
и
DEBUG2
. Эти сообщения предоставляют подробную информацию
о процессе проверки, которая может быть интересна разработчикам
Tantor SE. Опытные пользователи также могут
найти эту информацию полезной, поскольку она предоставляет дополнительный
контекст в случае обнаружения несоответствия при проверке. Запуск:
SET client_min_messages = DEBUG1;
в интерактивной сессии psql перед выполнением запроса на проверку будут отображаться сообщения о ходе проверки с уровнем детализации, который можно управлять.
-
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 может потенциально вызвать сбой сервера, хотя во многих случаях это просто приведет к ошибке.
По умолчанию установлено значение false.
skip
Если не указано
none
, проверка на повреждения пропускает блоки, которые помечены как полностью видимые или полностью замороженные, как указано. Допустимыми вариантами являютсяall-visible
,all-frozen
иnone
.По умолчанию
none
.startblock
Если указан, проверка целостности начинается с указанного блока, пропуская все предыдущие блоки. Ошибка указать
startblock
за пределами диапазона блоков в целевой таблице.По умолчанию проверка начинается с первого блока.
endblock
Если указан, проверка целостности заканчивается на указанном блоке, пропуская все оставшиеся блоки. Ошибка указать
endblock
за пределами диапазона блоков в целевой таблице.По умолчанию все блоки отмечены.
Для каждой обнаруженной коррупции
verify_heapam
возвращает строку со следующими столбцами:blkno
Номер блока, содержащего поврежденную страницу.
offnum
The OffsetNumber of the corrupt tuple.
attnum
Атрибут номера поврежденного столбца в кортеже, если повреждение относится к конкретному столбцу, а не к кортежу в целом.
msg
Сообщение, описывающее обнаруженную проблему.
F.2.2. Опциональная проверка heapallindexed
Когда аргумент heapallindexed
функций проверки B-дерева установлен в true
, выполняется дополнительная фаза проверки для таблицы, связанной с целевым индексом. Она состоит из операции “dummy” CREATE INDEX
, которая проверяет наличие всех гипотетических новых кортежей индекса во временной структуре, хранящейся в памяти (она создается при необходимости во время основной первой фазы проверки). Суммирующая структура “отпечатывает” каждый кортеж, найденный в целевом индексе. Основной принцип проверки heapallindexed
заключается в том, что новый индекс, эквивалентный существующему целевому индексу, должен содержать только записи, которые можно найти в существующей структуре.
Дополнительная фаза heapallindexed
добавляет значительные издержки: проверка обычно занимает несколько раз больше времени. Однако, при выполнении проверки heapallindexed
не происходит изменения блокировок на уровне отношений.
Структура сводки ограничена размером maintenance_work_mem
. Чтобы гарантировать, что вероятность необнаружения несоответствия для каждой кортежа кучи, которая должна быть представлена в индексе, не превышает 2%, требуется примерно 2 байта памяти на каждый кортеж. По мере уменьшения доступной памяти на каждый кортеж, вероятность пропуска несоответствия медленно увеличивается. Такой подход значительно ограничивает издержки на проверку, при этом незначительно снижая вероятность обнаружения проблемы, особенно для установок, где проверка рассматривается как регулярная задача по обслуживанию. Каждая отсутствующая или неправильно сформированная кортежа имеет новую возможность быть обнаруженной при каждой новой попытке проверки.
F.2.3. Использование amcheck
эффективно
amcheck
может быть эффективным в обнаружении различных типов
сбоев, которые контрольные суммы данных не смогут обнаружить. Это включает в себя:
Структурные несоответствия, вызванные неправильной реализацией класса операторов.
Это включает проблемы, вызванные изменением правил сортировки операционной системы. Сравнения данных типа
text
должны быть неизменяемыми (как и все сравнения, используемые для сканирования индекса B-Tree), что подразумевает, что правила сортировки операционной системы никогда не должны изменяться. Хотя это редко, обновления правил сортировки операционной системы могут вызывать эти проблемы. Более часто возникает несоответствие в порядке сортировки между основным сервером и резервным сервером, возможно, из-за несогласованности используемой основной версии операционной системы. Такие несоответствия, как правило, возникают только на резервных серверах и, следовательно, могут быть обнаружены только на резервных серверах.Если возникает такая проблема, это может и не повлиять на каждый отдельный индекс, упорядоченный с использованием затронутого правила сортировки, просто потому что значения, на которых основан индекс, могут иметь одинаковый абсолютный порядок, независимо от поведенческой несогласованности. См. Раздел 23.1 и Раздел 23.2 для получения дополнительной информации о том, как Tantor SE использует локали и правила сортировки операционной системы.
Структурные несоответствия между индексами и отношениями кучи, которые индексируются (при выполнении проверки
heapallindexed
).Во время нормальной работы не выполняется перекрестная проверка индексов по отношению к их куче. Симптомы повреждения кучи могут быть незаметными.
Повреждение, вызванное гипотетическими необнаруженными ошибками в основном коде метода доступа к Tantor SE, коде сортировки или коде управления транзакциями.
Automatic verification of the structural integrity of indexes plays a role in the general testing of new or proposed Tantor SE 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
amcheck
functions continuously when running the standard regression testsСбои файловой системы или подсистемы хранения, где контрольные суммы случайно не включены.
Обратите внимание, что
amcheck
анализирует страницу, представленную в некотором общем буфере памяти во время проверки, если при доступе к блоку произошло только попадание в общий буфер. Следовательно,amcheck
не обязательно анализирует данные, считанные из файловой системы во время проверки. Обратите внимание, что при включенных контрольных суммахamcheck
может вызвать ошибку из-за несоответствия контрольной суммы, когда поврежденный блок считывается в буфер.Повреждение, вызванное неисправной оперативной памятью или более широкой подсистемой памяти.
Tantor SE не защищает от исправимых ошибок памяти, и предполагается, что вы будете работать с ОЗУ, использующей стандартные коды исправления ошибок (ECC) или более надежную защиту. Однако ECC-память обычно устойчива только к однобитовым ошибкам и не следует полагать, что она обеспечивает абсолютную защиту от сбоев, приводящих к повреждению памяти.
Когда выполняется проверка
heapallindexed
, обычно существует значительно больший шанс обнаружения однобитных ошибок, поскольку выполняется строгое бинарное сравнение и проверяются индексированные атрибуты внутри кучи.
Структурная поврежденность может произойти из-за неисправного аппаратного обеспечения хранения или перезаписи или изменения файлов связей несвязанным программным обеспечением. Такого рода повреждение также может быть обнаружено с помощью контрольных сумм страниц данных.
Страницы отношений, которые правильно отформатированы, внутренне согласованы и корректны относительно своих собственных контрольных сумм, могут все равно содержать логическую поврежденность. Такие повреждения невозможно обнаружить с помощью контрольных сумм. Примеры включают тостовые значения в основной таблице, которым не соответствует запись в тостовой таблице, и кортежи в основной таблице с идентификатором транзакции, который старше самого старого допустимого идентификатора транзакции в базе данных или кластере.
В производственных системах было замечено множество причин логической поврежденности, включая ошибки в серверном программном обеспечении Tantor SE, неисправные и неудачные инструменты резервного копирования и восстановления, а также ошибки пользователей.
Поврежденные отношения являются наиболее критичными проблемами в реальных производственных средах, именно там, где рискованные действия не желательны. По этой причине была разработана функция verify_heapam
для диагностики повреждений без излишних рисков. Она не может защитить от всех причин сбоев бэкенда, так как даже выполнение вызывающего запроса может быть небезопасным в случае серьезного повреждения системы. Доступ к каталожным таблицам выполняется и может вызывать проблемы, если сами каталоги повреждены.
В общем случае, amcheck
может только доказать наличие повреждений; он не может доказать их отсутствие.
F.2.4. Восстановление повреждений
Не должно возникать ошибок, связанных с повреждением, вызванных amcheck
, которые могут быть ложными срабатываниями. amcheck
вызывает ошибки в случае условий, которые, по определению, не должны происходить, поэтому часто требуется тщательный анализ ошибок amcheck
.
Нет общего метода для устранения проблем, которые обнаруживает amcheck
. Следует искать объяснение корневой причины нарушения инварианта. pageinspect может сыграть полезную роль в диагностировании повреждений, которые обнаруживает amcheck
. REINDEX
может быть неэффективным при восстановлении повреждений.