Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 532d94f

Browse files
committed
amcheck: Refactoring the storage of the last visible entry
This commit introduces a new data structure BtreeLastVisibleEntry comprising information about the last visible heap entry with the current value of key. Usage of this data structure allows us to avoid passing all this information as individual function arguments. Reported-by: Alexander Korotkov Discussion: https://www.postgresql.org/message-id/CAPpHfdsVbB9ToriaB1UHuOKwjKxiZmTFQcEF%3DjuzzC_nby31uA%40mail.gmail.com Author: Pavel Borisov, Alexander Korotkov
1 parent bac44bc commit 532d94f

File tree

2 files changed

+60
-58
lines changed

2 files changed

+60
-58
lines changed

contrib/amcheck/verify_nbtree.c

+59-58
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,19 @@ typedef struct BtreeLevel
145145
bool istruerootlevel;
146146
} BtreeLevel;
147147

148+
/*
149+
* Information about the last visible entry with current B-tree key. Used
150+
* for validation of the unique constraint.
151+
*/
152+
typedef struct BtreeLastVisibleEntry
153+
{
154+
BlockNumber blkno; /* Index block */
155+
OffsetNumber offset; /* Offset on index block */
156+
int postingIndex; /* Number in the posting list (-1 for
157+
* non-deduplicated tuples) */
158+
ItemPointer tid; /* Heap tid */
159+
} BtreeLastVisibleEntry;
160+
148161
PG_FUNCTION_INFO_V1(bt_index_check);
149162
PG_FUNCTION_INFO_V1(bt_index_parent_check);
150163

@@ -165,17 +178,14 @@ static void bt_recheck_sibling_links(BtreeCheckState *state,
165178
BlockNumber btpo_prev_from_target,
166179
BlockNumber leftcurrent);
167180
static bool heap_entry_is_visible(BtreeCheckState *state, ItemPointer tid);
168-
static void bt_report_duplicate(BtreeCheckState *state, ItemPointer tid,
169-
BlockNumber block, OffsetNumber offset,
170-
int posting, ItemPointer nexttid,
181+
static void bt_report_duplicate(BtreeCheckState *state,
182+
BtreeLastVisibleEntry *lVis,
183+
ItemPointer nexttid,
171184
BlockNumber nblock, OffsetNumber noffset,
172185
int nposting);
173186
static void bt_entry_unique_check(BtreeCheckState *state, IndexTuple itup,
174-
BlockNumber targetblock,
175-
OffsetNumber offset, int *lVis_i,
176-
ItemPointer *lVis_tid,
177-
OffsetNumber *lVis_offset,
178-
BlockNumber *lVis_block);
187+
BlockNumber targetblock, OffsetNumber offset,
188+
BtreeLastVisibleEntry *lVis);
179189
static void bt_target_page_check(BtreeCheckState *state);
180190
static BTScanInsert bt_right_page_check_scankey(BtreeCheckState *state,
181191
OffsetNumber *rightfirstoffset);
@@ -997,8 +1007,7 @@ heap_entry_is_visible(BtreeCheckState *state, ItemPointer tid)
9971007
*/
9981008
static void
9991009
bt_report_duplicate(BtreeCheckState *state,
1000-
ItemPointer tid, BlockNumber block, OffsetNumber offset,
1001-
int posting,
1010+
BtreeLastVisibleEntry *lVis,
10021011
ItemPointer nexttid, BlockNumber nblock, OffsetNumber noffset,
10031012
int nposting)
10041013
{
@@ -1010,18 +1019,18 @@ bt_report_duplicate(BtreeCheckState *state,
10101019
*pnposting = "";
10111020

10121021
htid = psprintf("tid=(%u,%u)",
1013-
ItemPointerGetBlockNumberNoCheck(tid),
1014-
ItemPointerGetOffsetNumberNoCheck(tid));
1022+
ItemPointerGetBlockNumberNoCheck(lVis->tid),
1023+
ItemPointerGetOffsetNumberNoCheck(lVis->tid));
10151024
nhtid = psprintf("tid=(%u,%u)",
10161025
ItemPointerGetBlockNumberNoCheck(nexttid),
10171026
ItemPointerGetOffsetNumberNoCheck(nexttid));
1018-
itid = psprintf("tid=(%u,%u)", block, offset);
1027+
itid = psprintf("tid=(%u,%u)", lVis->blkno, lVis->offset);
10191028

1020-
if (nblock != block || noffset != offset)
1029+
if (nblock != lVis->blkno || noffset != lVis->offset)
10211030
nitid = psprintf(" tid=(%u,%u)", nblock, noffset);
10221031

1023-
if (posting >= 0)
1024-
pposting = psprintf(" posting %u", posting);
1032+
if (lVis->postingIndex >= 0)
1033+
pposting = psprintf(" posting %u", lVis->postingIndex);
10251034

10261035
if (nposting >= 0)
10271036
pnposting = psprintf(" posting %u", nposting);
@@ -1038,9 +1047,8 @@ bt_report_duplicate(BtreeCheckState *state,
10381047
/* Check if current nbtree leaf entry complies with UNIQUE constraint */
10391048
static void
10401049
bt_entry_unique_check(BtreeCheckState *state, IndexTuple itup,
1041-
BlockNumber targetblock, OffsetNumber offset, int *lVis_i,
1042-
ItemPointer *lVis_tid, OffsetNumber *lVis_offset,
1043-
BlockNumber *lVis_block)
1050+
BlockNumber targetblock, OffsetNumber offset,
1051+
BtreeLastVisibleEntry *lVis)
10441052
{
10451053
ItemPointer tid;
10461054
bool has_visible_entry = false;
@@ -1049,7 +1057,7 @@ bt_entry_unique_check(BtreeCheckState *state, IndexTuple itup,
10491057

10501058
/*
10511059
* Current tuple has posting list. Report duplicate if TID of any posting
1052-
* list entry is visible and lVis_tid is valid.
1060+
* list entry is visible and lVis->tid is valid.
10531061
*/
10541062
if (BTreeTupleIsPosting(itup))
10551063
{
@@ -1059,11 +1067,10 @@ bt_entry_unique_check(BtreeCheckState *state, IndexTuple itup,
10591067
if (heap_entry_is_visible(state, tid))
10601068
{
10611069
has_visible_entry = true;
1062-
if (ItemPointerIsValid(*lVis_tid))
1070+
if (ItemPointerIsValid(lVis->tid))
10631071
{
10641072
bt_report_duplicate(state,
1065-
*lVis_tid, *lVis_block,
1066-
*lVis_offset, *lVis_i,
1073+
lVis,
10671074
tid, targetblock,
10681075
offset, i);
10691076
}
@@ -1073,59 +1080,60 @@ bt_entry_unique_check(BtreeCheckState *state, IndexTuple itup,
10731080
* between the posting list entries of the first tuple on the
10741081
* page after cross-page check.
10751082
*/
1076-
if (*lVis_block != targetblock && ItemPointerIsValid(*lVis_tid))
1083+
if (lVis->blkno != targetblock && ItemPointerIsValid(lVis->tid))
10771084
return;
10781085

1079-
*lVis_i = i;
1080-
*lVis_tid = tid;
1081-
*lVis_offset = offset;
1082-
*lVis_block = targetblock;
1086+
lVis->blkno = targetblock;
1087+
lVis->offset = offset;
1088+
lVis->postingIndex = i;
1089+
lVis->tid = tid;
10831090
}
10841091
}
10851092
}
10861093

10871094
/*
10881095
* Current tuple has no posting list. If TID is visible save info about it
10891096
* for the next comparisons in the loop in bt_target_page_check(). Report
1090-
* duplicate if lVis_tid is already valid.
1097+
* duplicate if lVis->tid is already valid.
10911098
*/
10921099
else
10931100
{
10941101
tid = BTreeTupleGetHeapTID(itup);
10951102
if (heap_entry_is_visible(state, tid))
10961103
{
10971104
has_visible_entry = true;
1098-
if (ItemPointerIsValid(*lVis_tid))
1105+
if (ItemPointerIsValid(lVis->tid))
10991106
{
11001107
bt_report_duplicate(state,
1101-
*lVis_tid, *lVis_block,
1102-
*lVis_offset, *lVis_i,
1108+
lVis,
11031109
tid, targetblock,
11041110
offset, -1);
11051111
}
1106-
*lVis_i = -1;
1107-
*lVis_tid = tid;
1108-
*lVis_offset = offset;
1109-
*lVis_block = targetblock;
1112+
1113+
lVis->blkno = targetblock;
1114+
lVis->offset = offset;
1115+
lVis->tid = tid;
1116+
lVis->postingIndex = -1;
11101117
}
11111118
}
11121119

1113-
if (!has_visible_entry && *lVis_block != InvalidBlockNumber &&
1114-
*lVis_block != targetblock)
1120+
if (!has_visible_entry &&
1121+
lVis->blkno != InvalidBlockNumber &&
1122+
lVis->blkno != targetblock)
11151123
{
11161124
char *posting = "";
11171125

1118-
if (*lVis_i >= 0)
1119-
posting = psprintf(" posting %u", *lVis_i);
1126+
if (lVis->postingIndex >= 0)
1127+
posting = psprintf(" posting %u", lVis->postingIndex);
11201128
ereport(DEBUG1,
11211129
(errcode(ERRCODE_NO_DATA),
11221130
errmsg("index uniqueness can not be checked for index tid=(%u,%u) in index \"%s\"",
11231131
targetblock, offset,
11241132
RelationGetRelationName(state->rel)),
11251133
errdetail("It doesn't have visible heap tids and key is equal to the tid=(%u,%u)%s (points to heap tid=(%u,%u)).",
1126-
*lVis_block, *lVis_offset, posting,
1127-
ItemPointerGetBlockNumberNoCheck(*lVis_tid),
1128-
ItemPointerGetOffsetNumberNoCheck(*lVis_tid)),
1134+
lVis->blkno, lVis->offset, posting,
1135+
ItemPointerGetBlockNumberNoCheck(lVis->tid),
1136+
ItemPointerGetOffsetNumberNoCheck(lVis->tid)),
11291137
errhint("VACUUM the table and repeat the check.")));
11301138
}
11311139
}
@@ -1372,12 +1380,8 @@ bt_target_page_check(BtreeCheckState *state)
13721380
OffsetNumber max;
13731381
BTPageOpaque topaque;
13741382

1375-
/* last visible entry info for checking indexes with unique constraint */
1376-
int lVis_i = -1; /* the position of last visible item for
1377-
* posting tuple. for non-posting tuple (-1) */
1378-
ItemPointer lVis_tid = NULL;
1379-
BlockNumber lVis_block = InvalidBlockNumber;
1380-
OffsetNumber lVis_offset = InvalidOffsetNumber;
1383+
/* Last visible entry info for checking indexes with unique constraint */
1384+
BtreeLastVisibleEntry lVis = {InvalidBlockNumber, InvalidOffsetNumber, -1, NULL};
13811385

13821386
topaque = BTPageGetOpaque(state->target);
13831387
max = PageGetMaxOffsetNumber(state->target);
@@ -1776,8 +1780,7 @@ bt_target_page_check(BtreeCheckState *state)
17761780
if (state->checkunique && state->indexinfo->ii_Unique &&
17771781
P_ISLEAF(topaque) && !skey->anynullkeys)
17781782
bt_entry_unique_check(state, itup, state->targetblock, offset,
1779-
&lVis_i, &lVis_tid, &lVis_offset,
1780-
&lVis_block);
1783+
&lVis);
17811784

17821785
if (state->checkunique && state->indexinfo->ii_Unique &&
17831786
P_ISLEAF(topaque) && OffsetNumberNext(offset) <= max)
@@ -1800,10 +1803,10 @@ bt_target_page_check(BtreeCheckState *state)
18001803
if (_bt_compare(state->rel, skey, state->target,
18011804
OffsetNumberNext(offset)) != 0 || skey->anynullkeys)
18021805
{
1803-
lVis_i = -1;
1804-
lVis_tid = NULL;
1805-
lVis_block = InvalidBlockNumber;
1806-
lVis_offset = InvalidOffsetNumber;
1806+
lVis.blkno = InvalidBlockNumber;
1807+
lVis.offset = InvalidOffsetNumber;
1808+
lVis.postingIndex = -1;
1809+
lVis.tid = NULL;
18071810
}
18081811
skey->scantid = scantid; /* Restore saved scan key state */
18091812
}
@@ -1902,9 +1905,7 @@ bt_target_page_check(BtreeCheckState *state)
19021905
rightfirstoffset);
19031906
itup = (IndexTuple) PageGetItem(state->target, itemid);
19041907

1905-
bt_entry_unique_check(state, itup, rightblock_number, rightfirstoffset,
1906-
&lVis_i, &lVis_tid, &lVis_offset,
1907-
&lVis_block);
1908+
bt_entry_unique_check(state, itup, rightblock_number, rightfirstoffset, &lVis);
19081909
}
19091910
}
19101911
}

src/tools/pgindent/typedefs.list

+1
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,7 @@ BrinStatsData
322322
BrinTuple
323323
BrinValues
324324
BtreeCheckState
325+
BtreeLastVisibleEntry
325326
BtreeLevel
326327
Bucket
327328
BufFile

0 commit comments

Comments
 (0)