mirror of
https://github.com/postgres/postgres.git
synced 2026-10-23 13:29:09 +03:00
Add VM corruption check to verify_heapam()
Detect heap pages whose PD_ALL_VISIBLE flag is clear while either visibility map bit is set. This inconsistent state can cause incorrect index-only scan results and is not currently reported by verify_heapam(). This also helps users who have access to amcheck but not pg_visibility to diagnose corruption. Author: Melanie Plageman <melanieplageman@gmail.com> Reviewed-by: Andres Freund <andres@anarazel.de> Discussion: https://postgr.es/m/66mqpfyti3qhfttcsv6r2lbvqqd32rrmpn6i47ovrsnvguts46@gou54xc5jld3
This commit is contained in:
@@ -482,6 +482,7 @@ verify_heapam(PG_FUNCTION_ARGS)
|
||||
|
||||
while ((ctx.buffer = read_stream_next_buffer(stream, NULL)) != InvalidBuffer)
|
||||
{
|
||||
uint8 vmbits;
|
||||
OffsetNumber maxoff;
|
||||
OffsetNumber predecessor[MaxOffsetNumber];
|
||||
OffsetNumber successor[MaxOffsetNumber];
|
||||
@@ -500,6 +501,23 @@ verify_heapam(PG_FUNCTION_ARGS)
|
||||
ctx.blkno = BufferGetBlockNumber(ctx.buffer);
|
||||
ctx.page = BufferGetPage(ctx.buffer);
|
||||
|
||||
/*
|
||||
* It is corruption if PD_ALL_VISIBLE is clear while either VM bit is
|
||||
* set. Missing VM pages are treated as having no bits set. VM pages
|
||||
* that fail page verification are read with RBM_ZERO_ON_ERROR, so
|
||||
* those failures are not reported as corruption rows here.
|
||||
*/
|
||||
vmbits = visibilitymap_get_status(ctx.rel, ctx.blkno, &vmbuffer);
|
||||
|
||||
if (!PageIsAllVisible(ctx.page) &&
|
||||
(vmbits & VISIBILITYMAP_VALID_BITS) != 0)
|
||||
{
|
||||
ctx.offnum = InvalidOffsetNumber;
|
||||
ctx.attnum = -1;
|
||||
report_corruption(&ctx,
|
||||
psprintf("page is not marked all-visible in page header but visibility map bit is set"));
|
||||
}
|
||||
|
||||
/* Perform tuple checks */
|
||||
maxoff = PageGetMaxOffsetNumber(ctx.page);
|
||||
for (ctx.offnum = FirstOffsetNumber; ctx.offnum <= maxoff;
|
||||
|
||||
Reference in New Issue
Block a user