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

Commit24992c6

Browse files
committed
Rewrite PageIndexDeleteNoCompact into a form that only deletes 1 tuple.
The full generality of deleting an arbitrary number of tuples is no longerneeded, so let's save some code and cycles by replacing the original codingwith an implementation based on PageIndexTupleDelete.We can always get back the old code from git if we need it again for newcallers (though I don't care for its willingness to mess with line pointersit wasn't told to mess with).Discussion: <552.1473445163@sss.pgh.pa.us>
1 parent1a4be10 commit24992c6

File tree

4 files changed

+74
-129
lines changed

4 files changed

+74
-129
lines changed

‎src/backend/access/brin/brin_pageops.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ brin_doupdate(Relation idxrel, BlockNumber pagesPerRange,
245245
if (extended)
246246
brin_page_init(BufferGetPage(newbuf),BRIN_PAGETYPE_REGULAR);
247247

248-
PageIndexDeleteNoCompact(oldpage,&oldoff,1);
248+
PageIndexTupleDeleteNoCompact(oldpage,oldoff);
249249
newoff=PageAddItem(newpage, (Item)newtup,newsz,
250250
InvalidOffsetNumber, false, false);
251251
if (newoff==InvalidOffsetNumber)

‎src/backend/access/brin/brin_xlog.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -148,10 +148,8 @@ brin_xlog_update(XLogReaderState *record)
148148
page= (Page)BufferGetPage(buffer);
149149

150150
offnum=xlrec->oldOffnum;
151-
if (PageGetMaxOffsetNumber(page)+1<offnum)
152-
elog(PANIC,"brin_xlog_update: invalid max offset number");
153151

154-
PageIndexDeleteNoCompact(page,&offnum,1);
152+
PageIndexTupleDeleteNoCompact(page,offnum);
155153

156154
PageSetLSN(page,lsn);
157155
MarkBufferDirty(buffer);

‎src/backend/storage/page/bufpage.c

Lines changed: 71 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -415,8 +415,7 @@ PageRestoreTempPage(Page tempPage, Page oldPage)
415415
}
416416

417417
/*
418-
* sorting support for PageRepairFragmentation, PageIndexMultiDelete,
419-
* PageIndexDeleteNoCompact
418+
* sorting support for PageRepairFragmentation and PageIndexMultiDelete
420419
*/
421420
typedefstructitemIdSortData
422421
{
@@ -762,15 +761,14 @@ PageIndexTupleDelete(Page page, OffsetNumber offnum)
762761
* Now move everything between the old upper bound (beginning of tuple
763762
* space) and the beginning of the deleted tuple forward, so that space in
764763
* the middle of the page is left free. If we've just deleted the tuple
765-
* at the beginning of tuple space, then there's no need to do the copy
766-
* (and bcopy on some architectures SEGV's if asked to move zero bytes).
764+
* at the beginning of tuple space, then there's no need to do the copy.
767765
*/
768766

769767
/* beginning of tuple space */
770768
addr= (char*)page+phdr->pd_upper;
771769

772770
if (offset>phdr->pd_upper)
773-
memmove(addr+size,addr,(int) (offset-phdr->pd_upper));
771+
memmove(addr+size,addr,offset-phdr->pd_upper);
774772

775773
/* adjust free space boundary pointers */
776774
phdr->pd_upper+=size;
@@ -918,155 +916,105 @@ PageIndexMultiDelete(Page page, OffsetNumber *itemnos, int nitems)
918916
compactify_tuples(itemidbase,nused,page);
919917
}
920918

919+
921920
/*
922-
* PageIndexDeleteNoCompact
923-
*Delete the given items for an index page, and defragment the resulting
924-
*free space, but do not compact the item pointers array.
925-
*
926-
* itemnos is the array of tuples to delete; nitems is its size. maxIdxTuples
927-
* is the maximum number of tuples that can exist in a page.
921+
* PageIndexTupleDeleteNoCompact
928922
*
929-
* Unused items at the end of the array are removed.
923+
* Remove the specified tuple from an index page, but set its line pointer
924+
* to "unused" instead of compacting it out, except that it can be removed
925+
* if it's the last line pointer on the page.
930926
*
931927
* This is used for index AMs that require that existing TIDs of live tuples
932-
* remain unchanged.
928+
* remain unchanged, and are willing to allow unused line pointers instead.
933929
*/
934930
void
935-
PageIndexDeleteNoCompact(Pagepage,OffsetNumber*itemnos,intnitems)
931+
PageIndexTupleDeleteNoCompact(Pagepage,OffsetNumberoffnum)
936932
{
937933
PageHeaderphdr= (PageHeader)page;
938-
LocationIndexpd_lower=phdr->pd_lower;
939-
LocationIndexpd_upper=phdr->pd_upper;
940-
LocationIndexpd_special=phdr->pd_special;
934+
char*addr;
935+
ItemIdtup;
936+
Sizesize;
937+
unsignedoffset;
941938
intnline;
942-
boolempty;
943-
OffsetNumberoffnum;
944-
intnextitm;
945939

946940
/*
947941
* As with PageRepairFragmentation, paranoia seems justified.
948942
*/
949-
if (pd_lower<SizeOfPageHeaderData||
950-
pd_lower>pd_upper||
951-
pd_upper>pd_special||
952-
pd_special>BLCKSZ||
953-
pd_special!=MAXALIGN(pd_special))
943+
if (phdr->pd_lower<SizeOfPageHeaderData||
944+
phdr->pd_lower>phdr->pd_upper||
945+
phdr->pd_upper>phdr->pd_special||
946+
phdr->pd_special>BLCKSZ||
947+
phdr->pd_special!=MAXALIGN(phdr->pd_special))
954948
ereport(ERROR,
955949
(errcode(ERRCODE_DATA_CORRUPTED),
956950
errmsg("corrupted page pointers: lower = %u, upper = %u, special = %u",
957-
pd_lower,pd_upper,pd_special)));
951+
phdr->pd_lower,phdr->pd_upper,phdr->pd_special)));
952+
953+
nline=PageGetMaxOffsetNumber(page);
954+
if ((int)offnum <=0|| (int)offnum>nline)
955+
elog(ERROR,"invalid index offnum: %u",offnum);
956+
957+
tup=PageGetItemId(page,offnum);
958+
Assert(ItemIdHasStorage(tup));
959+
size=ItemIdGetLength(tup);
960+
offset=ItemIdGetOffset(tup);
961+
962+
if (offset<phdr->pd_upper|| (offset+size)>phdr->pd_special||
963+
offset!=MAXALIGN(offset))
964+
ereport(ERROR,
965+
(errcode(ERRCODE_DATA_CORRUPTED),
966+
errmsg("corrupted item pointer: offset = %u, size = %u",
967+
offset, (unsignedint)size)));
968+
969+
/* Amount of space to actually be deleted */
970+
size=MAXALIGN(size);
958971

959972
/*
960-
*Scantheexistingitem pointerarray and mark as unused those that are
961-
*in our kill-list; make sure any non-interesting ones aremarked unused
962-
*as well.
973+
*Either setthe item pointerto "unused", or zap it if it's the last
974+
*one. (Note: it's possible that the next-to-last one(s) arealready
975+
*unused, but we do not trouble to try to compact them out if so.)
963976
*/
964-
nline=PageGetMaxOffsetNumber(page);
965-
empty= true;
966-
nextitm=0;
967-
for (offnum=FirstOffsetNumber;offnum <=nline;offnum=OffsetNumberNext(offnum))
977+
if ((int)offnum<nline)
978+
ItemIdSetUnused(tup);
979+
else
968980
{
969-
ItemIdlp;
970-
ItemLengthitemlen;
971-
ItemOffsetoffset;
981+
phdr->pd_lower-=sizeof(ItemIdData);
982+
nline--;/* there's one less than when we started */
983+
}
972984

973-
lp=PageGetItemId(page,offnum);
985+
/*
986+
* Now move everything between the old upper bound (beginning of tuple
987+
* space) and the beginning of the deleted tuple forward, so that space in
988+
* the middle of the page is left free. If we've just deleted the tuple
989+
* at the beginning of tuple space, then there's no need to do the copy.
990+
*/
974991

975-
itemlen=ItemIdGetLength(lp);
976-
offset=ItemIdGetOffset(lp);
992+
/* beginning of tuple space */
993+
addr=(char*)page+phdr->pd_upper;
977994

978-
if (ItemIdIsUsed(lp))
979-
{
980-
if (offset<pd_upper||
981-
(offset+itemlen)>pd_special||
982-
offset!=MAXALIGN(offset))
983-
ereport(ERROR,
984-
(errcode(ERRCODE_DATA_CORRUPTED),
985-
errmsg("corrupted item pointer: offset = %u, length = %u",
986-
offset, (unsignedint)itemlen)));
987-
988-
if (nextitm<nitems&&offnum==itemnos[nextitm])
989-
{
990-
/* this one is on our list to delete, so mark it unused */
991-
ItemIdSetUnused(lp);
992-
nextitm++;
993-
}
994-
elseif (ItemIdHasStorage(lp))
995-
{
996-
/* This one's live -- must do the compaction dance */
997-
empty= false;
998-
}
999-
else
1000-
{
1001-
/* get rid of this one too */
1002-
ItemIdSetUnused(lp);
1003-
}
1004-
}
1005-
}
995+
if (offset>phdr->pd_upper)
996+
memmove(addr+size,addr,offset-phdr->pd_upper);
1006997

1007-
/* this will catch invalid or out-of-order itemnos[] */
1008-
if (nextitm!=nitems)
1009-
elog(ERROR,"incorrect index offsets supplied");
998+
/* adjust free space boundary pointer */
999+
phdr->pd_upper+=size;
10101000

1011-
if (empty)
1012-
{
1013-
/* Page is completely empty, so just reset it quickly */
1014-
phdr->pd_lower=SizeOfPageHeaderData;
1015-
phdr->pd_upper=pd_special;
1016-
}
1017-
else
1001+
/*
1002+
* Finally, we need to adjust the linp entries that remain.
1003+
*
1004+
* Anything that used to be before the deleted tuple's data was moved
1005+
* forward by the size of the deleted tuple.
1006+
*/
1007+
if (!PageIsEmpty(page))
10181008
{
1019-
/* There are live items: need to compact the page the hard way */
1020-
itemIdSortDataitemidbase[MaxOffsetNumber];
1021-
itemIdSortitemidptr;
10221009
inti;
1023-
Sizetotallen;
10241010

1025-
/*
1026-
* Scan the page taking note of each item that we need to preserve.
1027-
* This includes both live items (those that contain data) and
1028-
* interspersed unused ones. It's critical to preserve these unused
1029-
* items, because otherwise the offset numbers for later live items
1030-
* would change, which is not acceptable. Unused items might get used
1031-
* again later; that is fine.
1032-
*/
1033-
itemidptr=itemidbase;
1034-
totallen=0;
1035-
PageClearHasFreeLinePointers(page);
1036-
for (i=0;i<nline;i++)
1011+
for (i=1;i <=nline;i++)
10371012
{
1038-
ItemIdlp;
1039-
1040-
itemidptr->offsetindex=i;
1013+
ItemIdii=PageGetItemId(phdr,i);
10411014

1042-
lp=PageGetItemId(page,i+1);
1043-
if (ItemIdHasStorage(lp))
1044-
{
1045-
itemidptr->itemoff=ItemIdGetOffset(lp);
1046-
itemidptr->alignedlen=MAXALIGN(ItemIdGetLength(lp));
1047-
totallen+=itemidptr->alignedlen;
1048-
itemidptr++;
1049-
}
1050-
else
1051-
{
1052-
PageSetHasFreeLinePointers(page);
1053-
ItemIdSetUnused(lp);
1054-
}
1015+
if (ItemIdHasStorage(ii)&&ItemIdGetOffset(ii) <=offset)
1016+
ii->lp_off+=size;
10551017
}
1056-
nline=itemidptr-itemidbase;
1057-
/* By here, there are exactly nline elements in itemidbase array */
1058-
1059-
if (totallen> (Size) (pd_special-pd_lower))
1060-
ereport(ERROR,
1061-
(errcode(ERRCODE_DATA_CORRUPTED),
1062-
errmsg("corrupted item lengths: total %u, available space %u",
1063-
(unsignedint)totallen,pd_special-pd_lower)));
1064-
1065-
/*
1066-
* Defragment the data areas of each tuple, being careful to preserve
1067-
* each item's position in the linp array.
1068-
*/
1069-
compactify_tuples(itemidbase,nline,page);
10701018
}
10711019
}
10721020

‎src/include/storage/bufpage.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -429,8 +429,7 @@ extern Size PageGetExactFreeSpace(Page page);
429429
externSizePageGetHeapFreeSpace(Pagepage);
430430
externvoidPageIndexTupleDelete(Pagepage,OffsetNumberoffset);
431431
externvoidPageIndexMultiDelete(Pagepage,OffsetNumber*itemnos,intnitems);
432-
externvoidPageIndexDeleteNoCompact(Pagepage,OffsetNumber*itemnos,
433-
intnitems);
432+
externvoidPageIndexTupleDeleteNoCompact(Pagepage,OffsetNumberoffset);
434433
externboolPageIndexTupleOverwrite(Pagepage,OffsetNumberoffnum,
435434
Itemnewtup,Sizenewsize);
436435
externchar*PageSetChecksumCopy(Pagepage,BlockNumberblkno);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp