Skip to content

Commit 684a745

Browse files
committed
pgstattuple: Improve reports generated for indexes (hash, gist, btree)
pgstattuple checks the state of the pages retrieved for gist and hash using some check functions from each index AM, respectively gistcheckpage() and _hash_checkpage(). When these are called, they would fail when bumping on data that is found as incorrect (like opaque area size not matching, or empty pages), contrary to btree that simply discards these cases and continues to aggregate data. Zero pages can happen after a crash, with these AMs being able to do an internal cleanup when these are seen. Also, sporadic failures are annoying when doing for example a large-scale diagnostic query based on pgstattuple with a join of pg_class, as it forces one to use tricks like quals to discard hash or gist indexes, or use a PL wrapper able to catch errors. This commit changes the reports generated for btree, gist and hash to be more user-friendly; - When seeing an empty page, report it as free space. This new rule applies to gist and hash, and already applied to btree. - For btree, a check based on the size of BTPageOpaqueData is added. - For gist indexes, gistcheckpage() is not called anymore, replaced by a check based on the size of GISTPageOpaqueData. - For hash indexes, instead of _hash_getbuf_with_strategy(), use a direct call to ReadBufferExtended(), coupled with a check based on HashPageOpaqueData. The opaque area size check was already used. - Pages that do not match these criterias are discarded from the stats reports generated. There have been a couple of bug reports over the years that complained about the current behavior for hash and gist, as being not that useful, with nothing being done about it. Hence this change is backpatched down to v13. Reported-by: Noah Misch <[email protected]> Author: Nitin Motiani <[email protected]> Reviewed-by: Dilip Kumar <[email protected]> Discussion: https://postgr.es/m/CAH5HC95gT1J3dRYK4qEnaywG8RqjbwDdt04wuj8p39R=HukayA@mail.gmail.com Backpatch-through: 13
1 parent fd726b8 commit 684a745

File tree

1 file changed

+22
-10
lines changed

1 file changed

+22
-10
lines changed

contrib/pgstattuple/pgstattuple.c

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,7 @@ pgstat_btree_page(pgstattuple_type *stat, Relation rel, BlockNumber blkno,
424424
/* fully empty page */
425425
stat->free_space += BLCKSZ;
426426
}
427-
else
427+
else if (PageGetSpecialSize(page) == MAXALIGN(sizeof(BTPageOpaqueData)))
428428
{
429429
BTPageOpaque opaque;
430430

@@ -458,10 +458,16 @@ pgstat_hash_page(pgstattuple_type *stat, Relation rel, BlockNumber blkno,
458458
Buffer buf;
459459
Page page;
460460

461-
buf = _hash_getbuf_with_strategy(rel, blkno, HASH_READ, 0, bstrategy);
461+
buf = ReadBufferExtended(rel, MAIN_FORKNUM, blkno, RBM_NORMAL, bstrategy);
462+
LockBuffer(buf, HASH_READ);
462463
page = BufferGetPage(buf);
463464

464-
if (PageGetSpecialSize(page) == MAXALIGN(sizeof(HashPageOpaqueData)))
465+
if (PageIsNew(page))
466+
{
467+
/* fully empty page */
468+
stat->free_space += BLCKSZ;
469+
}
470+
else if (PageGetSpecialSize(page) == MAXALIGN(sizeof(HashPageOpaqueData)))
465471
{
466472
HashPageOpaque opaque;
467473

@@ -502,17 +508,23 @@ pgstat_gist_page(pgstattuple_type *stat, Relation rel, BlockNumber blkno,
502508

503509
buf = ReadBufferExtended(rel, MAIN_FORKNUM, blkno, RBM_NORMAL, bstrategy);
504510
LockBuffer(buf, GIST_SHARE);
505-
gistcheckpage(rel, buf);
506511
page = BufferGetPage(buf);
507-
508-
if (GistPageIsLeaf(page))
512+
if (PageIsNew(page))
509513
{
510-
pgstat_index_page(stat, page, FirstOffsetNumber,
511-
PageGetMaxOffsetNumber(page));
514+
/* fully empty page */
515+
stat->free_space += BLCKSZ;
512516
}
513-
else
517+
else if (PageGetSpecialSize(page) == MAXALIGN(sizeof(GISTPageOpaqueData)))
514518
{
515-
/* root or node */
519+
if (GistPageIsLeaf(page))
520+
{
521+
pgstat_index_page(stat, page, FirstOffsetNumber,
522+
PageGetMaxOffsetNumber(page));
523+
}
524+
else
525+
{
526+
/* root or node */
527+
}
516528
}
517529

518530
UnlockReleaseBuffer(buf);

0 commit comments

Comments
 (0)