summaryrefslogtreecommitdiff
path: root/contrib/pageinspect/hashfuncs.c
diff options
context:
space:
mode:
authorRobert Haas2017-04-05 18:17:23 +0000
committerRobert Haas2017-04-05 18:18:15 +0000
commit633e15ea0f1bf2e1d70441fe9da8781befebd6e9 (patch)
tree0dd846cb2e2418e82b2e90bcd8fa88e2c64be55d /contrib/pageinspect/hashfuncs.c
parent6785fbd60ffd82ef825baf6db34bd944f3c7b121 (diff)
Fix pageinspect failures on hash indexes.
Make every page in a hash index which isn't all-zeroes have a valid special space, so that tools like pageinspect don't error out. Also, make pageinspect cope with all-zeroes pages, because _hash_alloc_buckets can leave behind large numbers of those until they're consumed by splits. Ashutosh Sharma and Robert Haas, reviewed by Amit Kapila. Original trouble report from Jeff Janes. Discussion: http://postgr.es/m/CAMkU=1y6NjKmqbJ8wLMhr=F74WzcMALYWcVFhEpm7i=mV=XsOg@mail.gmail.com
Diffstat (limited to 'contrib/pageinspect/hashfuncs.c')
-rw-r--r--contrib/pageinspect/hashfuncs.c70
1 files changed, 39 insertions, 31 deletions
diff --git a/contrib/pageinspect/hashfuncs.c b/contrib/pageinspect/hashfuncs.c
index 812a03f1214..dd00aaa81a6 100644
--- a/contrib/pageinspect/hashfuncs.c
+++ b/contrib/pageinspect/hashfuncs.c
@@ -56,31 +56,33 @@ static Page
verify_hash_page(bytea *raw_page, int flags)
{
Page page = get_page_from_raw(raw_page);
- int pagetype;
- HashPageOpaque pageopaque;
+ int pagetype = LH_UNUSED_PAGE;
- if (PageIsNew(page))
- ereport(ERROR,
- (errcode(ERRCODE_INDEX_CORRUPTED),
- errmsg("index table contains zero page")));
+ /* Treat new pages as unused. */
+ if (!PageIsNew(page))
+ {
+ HashPageOpaque pageopaque;
- if (PageGetSpecialSize(page) != MAXALIGN(sizeof(HashPageOpaqueData)))
- ereport(ERROR,
- (errcode(ERRCODE_INDEX_CORRUPTED),
- errmsg("index table contains corrupted page")));
+ if (PageGetSpecialSize(page) != MAXALIGN(sizeof(HashPageOpaqueData)))
+ ereport(ERROR,
+ (errcode(ERRCODE_INDEX_CORRUPTED),
+ errmsg("index table contains corrupted page")));
- pageopaque = (HashPageOpaque) PageGetSpecialPointer(page);
- if (pageopaque->hasho_page_id != HASHO_PAGE_ID)
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("page is not a hash page"),
- errdetail("Expected %08x, got %08x.",
- HASHO_PAGE_ID, pageopaque->hasho_page_id)));
+ pageopaque = (HashPageOpaque) PageGetSpecialPointer(page);
+ if (pageopaque->hasho_page_id != HASHO_PAGE_ID)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("page is not a hash page"),
+ errdetail("Expected %08x, got %08x.",
+ HASHO_PAGE_ID, pageopaque->hasho_page_id)));
+
+ pagetype = pageopaque->hasho_flag & LH_PAGE_TYPE;
+ }
/* Check that page type is sane. */
- pagetype = pageopaque->hasho_flag & LH_PAGE_TYPE;
if (pagetype != LH_OVERFLOW_PAGE && pagetype != LH_BUCKET_PAGE &&
- pagetype != LH_BITMAP_PAGE && pagetype != LH_META_PAGE)
+ pagetype != LH_BITMAP_PAGE && pagetype != LH_META_PAGE &&
+ pagetype != LH_UNUSED_PAGE)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("invalid hash page type %08x", pagetype)));
@@ -190,19 +192,25 @@ hash_page_type(PG_FUNCTION_ARGS)
(errmsg("must be superuser to use raw page functions"))));
page = verify_hash_page(raw_page, 0);
- opaque = (HashPageOpaque) PageGetSpecialPointer(page);
-
- /* page type (flags) */
- if (opaque->hasho_flag & LH_META_PAGE)
- type = "metapage";
- else if (opaque->hasho_flag & LH_OVERFLOW_PAGE)
- type = "overflow";
- else if (opaque->hasho_flag & LH_BUCKET_PAGE)
- type = "bucket";
- else if (opaque->hasho_flag & LH_BITMAP_PAGE)
- type = "bitmap";
- else
+
+ if (PageIsNew(page))
type = "unused";
+ else
+ {
+ opaque = (HashPageOpaque) PageGetSpecialPointer(page);
+
+ /* page type (flags) */
+ if (opaque->hasho_flag & LH_META_PAGE)
+ type = "metapage";
+ else if (opaque->hasho_flag & LH_OVERFLOW_PAGE)
+ type = "overflow";
+ else if (opaque->hasho_flag & LH_BUCKET_PAGE)
+ type = "bucket";
+ else if (opaque->hasho_flag & LH_BITMAP_PAGE)
+ type = "bitmap";
+ else
+ type = "unused";
+ }
PG_RETURN_TEXT_P(cstring_to_text(type));
}