Skip to content

Rework amcheck: 3 reports (c1/c2/c3), include system indexes, add GIN#90

Merged
NikolayS merged 1 commit intomasterfrom
rework-amcheck-reports
Feb 10, 2026
Merged

Rework amcheck: 3 reports (c1/c2/c3), include system indexes, add GIN#90
NikolayS merged 1 commit intomasterfrom
rework-amcheck-reports

Conversation

@NikolayS
Copy link
Owner

Follow-up to #89. Reworks the corruption checks based on feedback.

Changes

3 reports instead of 2 — clearer separation by use case:

Report Lock What it checks When to use
c1 AccessShareLock btree pages, GIN (PG18+), heap+TOAST (PG14+) Production primary — safe, fast
c2 ShareLock ⚠️ btree parent-child ordering, sibling pointers, rootdescend, checkunique (PG14+) Standby — detects glibc/collation corruption
c3 ShareLock ⚠️⚠️ Everything in c2 + heapallindexed + verify_heapam with full TOAST Standby only — proves every heap tuple is indexed, slowest

System indexes included

All three reports now check pg_catalog and pg_toast indexes too. System catalog corruption is arguably more critical than user table corruption.

GIN support (PG18+)

c1 checks GIN indexes via gin_index_check() on PostgreSQL 18+.

Big fat warnings

c2 and c3 emit prominent warnings about ShareLock blocking writes.

Testing

  • PG13: 158 btree indexes checked (no verify_heapam, no GIN)
  • PG17: 168 btree indexes + 73 tables checked
  • Superuser and non-superuser scenarios verified

… support

- c1 (quick): bt_index_check + gin_index_check (PG18+) + verify_heapam (PG14+)
  All AccessShareLock — safe for production primaries.
- c2 (parent): bt_index_parent_check with rootdescend + checkunique (PG14+)
  ShareLock — detects glibc/collation corruption. Best on standbys.
- c3 (full): bt_index_parent_check with heapallindexed + verify_heapam
  ShareLock + full heap scan — proves every tuple is indexed. Slow.
- All three now check system catalog indexes (pg_catalog, pg_toast)
- Big fat warnings on c2 and c3 about ShareLock blocking writes
- Tested on PG13 (158 btree indexes) and PG17 (168 btree indexes, 73 tables)
@NikolayS NikolayS merged commit 2bd4318 into master Feb 10, 2026
6 checks passed
@@ -27,10 +29,15 @@ begin

select current_setting('server_version_num')::int into pg_version;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On PG10 and earlier this hits bt_index_parent_check(..., heapallindexed := true) (and may fail due to signature/availability). Might be better to explicitly skip c3 on < PG11 with a clear message.

Suggested change
select current_setting('server_version_num')::int into pg_version;
select current_setting('server_version_num')::int into pg_version;
if pg_version < 110000 then
raise notice '';
raise notice 'ℹ️ heapallindexed checks require PostgreSQL 11+. Skipped.';
return;
end if;

|----|--------|
| c1 | B-tree index integrity check (amcheck, non-blocking) |
| c2 | Full B-tree + heap integrity check (amcheck, takes locks — use on standby!) |
| c1 | Quick: btree + GIN (PG18) + heap (PG14) check — safe for production (AccessShareLock) |
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor doc nit: this reads like it’s PG18/PG14 only, but the scripts say PG18+ / PG14+.

Suggested change
| c1 | Quick: btree + GIN (PG18) + heap (PG14) check — safe for production (AccessShareLock) |
| c1 | Quick: btree + GIN (PG18+) + heap (PG14+) check — safe for production (AccessShareLock) |

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

Comments