Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit633e15e

Browse files
committed
Fix pageinspect failures on hash indexes.
Make every page in a hash index which isn't all-zeroes have a validspecial 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 untilthey'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
1 parent6785fbd commit633e15e

File tree

4 files changed

+73
-35
lines changed

4 files changed

+73
-35
lines changed

‎contrib/pageinspect/hashfuncs.c

Lines changed: 39 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -56,31 +56,33 @@ static Page
5656
verify_hash_page(bytea*raw_page,intflags)
5757
{
5858
Pagepage=get_page_from_raw(raw_page);
59-
intpagetype;
60-
HashPageOpaquepageopaque;
59+
intpagetype=LH_UNUSED_PAGE;
6160

62-
if (PageIsNew(page))
63-
ereport(ERROR,
64-
(errcode(ERRCODE_INDEX_CORRUPTED),
65-
errmsg("index table contains zero page")));
61+
/* Treat new pages as unused. */
62+
if (!PageIsNew(page))
63+
{
64+
HashPageOpaquepageopaque;
6665

67-
if (PageGetSpecialSize(page)!=MAXALIGN(sizeof(HashPageOpaqueData)))
68-
ereport(ERROR,
69-
(errcode(ERRCODE_INDEX_CORRUPTED),
70-
errmsg("index table contains corrupted page")));
66+
if (PageGetSpecialSize(page)!=MAXALIGN(sizeof(HashPageOpaqueData)))
67+
ereport(ERROR,
68+
(errcode(ERRCODE_INDEX_CORRUPTED),
69+
errmsg("index table contains corrupted page")));
7170

72-
pageopaque= (HashPageOpaque)PageGetSpecialPointer(page);
73-
if (pageopaque->hasho_page_id!=HASHO_PAGE_ID)
74-
ereport(ERROR,
75-
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
76-
errmsg("page is not a hash page"),
77-
errdetail("Expected %08x, got %08x.",
78-
HASHO_PAGE_ID,pageopaque->hasho_page_id)));
71+
pageopaque= (HashPageOpaque)PageGetSpecialPointer(page);
72+
if (pageopaque->hasho_page_id!=HASHO_PAGE_ID)
73+
ereport(ERROR,
74+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
75+
errmsg("page is not a hash page"),
76+
errdetail("Expected %08x, got %08x.",
77+
HASHO_PAGE_ID,pageopaque->hasho_page_id)));
78+
79+
pagetype=pageopaque->hasho_flag&LH_PAGE_TYPE;
80+
}
7981

8082
/* Check that page type is sane. */
81-
pagetype=pageopaque->hasho_flag&LH_PAGE_TYPE;
8283
if (pagetype!=LH_OVERFLOW_PAGE&&pagetype!=LH_BUCKET_PAGE&&
83-
pagetype!=LH_BITMAP_PAGE&&pagetype!=LH_META_PAGE)
84+
pagetype!=LH_BITMAP_PAGE&&pagetype!=LH_META_PAGE&&
85+
pagetype!=LH_UNUSED_PAGE)
8486
ereport(ERROR,
8587
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
8688
errmsg("invalid hash page type %08x",pagetype)));
@@ -190,19 +192,25 @@ hash_page_type(PG_FUNCTION_ARGS)
190192
(errmsg("must be superuser to use raw page functions"))));
191193

192194
page=verify_hash_page(raw_page,0);
193-
opaque= (HashPageOpaque)PageGetSpecialPointer(page);
194-
195-
/* page type (flags) */
196-
if (opaque->hasho_flag&LH_META_PAGE)
197-
type="metapage";
198-
elseif (opaque->hasho_flag&LH_OVERFLOW_PAGE)
199-
type="overflow";
200-
elseif (opaque->hasho_flag&LH_BUCKET_PAGE)
201-
type="bucket";
202-
elseif (opaque->hasho_flag&LH_BITMAP_PAGE)
203-
type="bitmap";
204-
else
195+
196+
if (PageIsNew(page))
205197
type="unused";
198+
else
199+
{
200+
opaque= (HashPageOpaque)PageGetSpecialPointer(page);
201+
202+
/* page type (flags) */
203+
if (opaque->hasho_flag&LH_META_PAGE)
204+
type="metapage";
205+
elseif (opaque->hasho_flag&LH_OVERFLOW_PAGE)
206+
type="overflow";
207+
elseif (opaque->hasho_flag&LH_BUCKET_PAGE)
208+
type="bucket";
209+
elseif (opaque->hasho_flag&LH_BITMAP_PAGE)
210+
type="bitmap";
211+
else
212+
type="unused";
213+
}
206214

207215
PG_RETURN_TEXT_P(cstring_to_text(type));
208216
}

‎src/backend/access/hash/hash_xlog.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -697,11 +697,20 @@ hash_xlog_squeeze_page(XLogReaderState *record)
697697
if (XLogReadBufferForRedo(record,2,&ovflbuf)==BLK_NEEDS_REDO)
698698
{
699699
Pageovflpage;
700+
HashPageOpaqueovflopaque;
700701

701702
ovflpage=BufferGetPage(ovflbuf);
702703

703704
_hash_pageinit(ovflpage,BufferGetPageSize(ovflbuf));
704705

706+
ovflopaque= (HashPageOpaque)PageGetSpecialPointer(ovflpage);
707+
708+
ovflopaque->hasho_prevblkno=InvalidBlockNumber;
709+
ovflopaque->hasho_nextblkno=InvalidBlockNumber;
710+
ovflopaque->hasho_bucket=-1;
711+
ovflopaque->hasho_flag=LH_UNUSED_PAGE;
712+
ovflopaque->hasho_page_id=HASHO_PAGE_ID;
713+
705714
PageSetLSN(ovflpage,lsn);
706715
MarkBufferDirty(ovflbuf);
707716
}

‎src/backend/access/hash/hashovfl.c

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -590,11 +590,22 @@ _hash_freeovflpage(Relation rel, Buffer bucketbuf, Buffer ovflbuf,
590590
}
591591

592592
/*
593-
* Initialize the freed overflow page. Just zeroing the page won't work,
594-
* because WAL replay routines expect pages to be initialized. See
595-
* explanation of RBM_NORMAL mode atop XLogReadBufferExtended.
593+
* Reinitialize the freed overflow page. Just zeroing the page won't
594+
* work, because WAL replay routines expect pages to be initialized. See
595+
* explanation of RBM_NORMAL mode atop XLogReadBufferExtended. We are
596+
* careful to make the special space valid here so that tools like
597+
* pageinspect won't get confused.
596598
*/
597599
_hash_pageinit(ovflpage,BufferGetPageSize(ovflbuf));
600+
601+
ovflopaque= (HashPageOpaque)PageGetSpecialPointer(ovflpage);
602+
603+
ovflopaque->hasho_prevblkno=InvalidBlockNumber;
604+
ovflopaque->hasho_nextblkno=InvalidBlockNumber;
605+
ovflopaque->hasho_bucket=-1;
606+
ovflopaque->hasho_flag=LH_UNUSED_PAGE;
607+
ovflopaque->hasho_page_id=HASHO_PAGE_ID;
608+
598609
MarkBufferDirty(ovflbuf);
599610

600611
if (BufferIsValid(prevbuf))

‎src/backend/access/hash/hashpage.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -993,6 +993,7 @@ _hash_alloc_buckets(Relation rel, BlockNumber firstblock, uint32 nblocks)
993993
BlockNumberlastblock;
994994
charzerobuf[BLCKSZ];
995995
Pagepage;
996+
HashPageOpaqueovflopaque;
996997

997998
lastblock=firstblock+nblocks-1;
998999

@@ -1007,10 +1008,19 @@ _hash_alloc_buckets(Relation rel, BlockNumber firstblock, uint32 nblocks)
10071008

10081009
/*
10091010
* Initialize the page. Just zeroing the page won't work; see
1010-
* _hash_freeovflpage for similar usage.
1011+
* _hash_freeovflpage for similar usage. We take care to make the
1012+
* special space valid for the benefit of tools such as pageinspect.
10111013
*/
10121014
_hash_pageinit(page,BLCKSZ);
10131015

1016+
ovflopaque= (HashPageOpaque)PageGetSpecialPointer(page);
1017+
1018+
ovflopaque->hasho_prevblkno=InvalidBlockNumber;
1019+
ovflopaque->hasho_nextblkno=InvalidBlockNumber;
1020+
ovflopaque->hasho_bucket=-1;
1021+
ovflopaque->hasho_flag=LH_UNUSED_PAGE;
1022+
ovflopaque->hasho_page_id=HASHO_PAGE_ID;
1023+
10141024
if (RelationNeedsWAL(rel))
10151025
log_newpage(&rel->rd_node,
10161026
MAIN_FORKNUM,

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp