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

Commit8776faa

Browse files
committed
Adjust SP-GiST WAL record formats to reduce alignment padding.
The way the code was written, the padding was copied from uninitializedmemory areas.. Because the structs are local variables in the code wherethe WAL records are constructed, making them larger and zeroing the paddingbytes would not make the code very pretty, so rather than fixing thisdirectly by zeroing out the padding bytes, it seems more clear to not try toalign the tuples in the WAL records. The redo functions are taught to copythe tuple header to a local variable to avoid unaligned access.Stable-branches have the same problem, but we can't change the WAL formatthere, so fix in master only. Reading a few random extra bytes at the stackis harmless in practice, so it's not worth crafting a differentback-patchable fix.Per reports from Kevin Grittner and Andres Freund, using clang staticanalyzer and Valgrind, respectively.
1 parentd4d48a5 commit8776faa

File tree

5 files changed

+105
-80
lines changed

5 files changed

+105
-80
lines changed

‎src/backend/access/spgist/spgdoinsert.c

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,6 @@ addLeafTuple(Relation index, SpGistState *state, SpGistLeafTuple leafTuple,
217217
xlrec.nodeI=0;
218218

219219
ACCEPT_RDATA_DATA(&xlrec,sizeof(xlrec),0);
220-
/* we assume sizeof(xlrec) is at least int-aligned */
221220
ACCEPT_RDATA_DATA(leafTuple,leafTuple->size,1);
222221
ACCEPT_RDATA_BUFFER(current->buffer,2);
223222

@@ -533,9 +532,9 @@ moveLeafs(Relation index, SpGistState *state,
533532
{
534533
XLogRecPtrrecptr;
535534

536-
ACCEPT_RDATA_DATA(&xlrec,MAXALIGN(sizeof(xlrec)),0);
537-
ACCEPT_RDATA_DATA(toDelete,MAXALIGN(sizeof(OffsetNumber)*nDelete),1);
538-
ACCEPT_RDATA_DATA(toInsert,MAXALIGN(sizeof(OffsetNumber)*nInsert),2);
535+
ACCEPT_RDATA_DATA(&xlrec,SizeOfSpgxlogMoveLeafs,0);
536+
ACCEPT_RDATA_DATA(toDelete,sizeof(OffsetNumber)*nDelete,1);
537+
ACCEPT_RDATA_DATA(toInsert,sizeof(OffsetNumber)*nInsert,2);
539538
ACCEPT_RDATA_DATA(leafdata,leafptr-leafdata,3);
540539
ACCEPT_RDATA_BUFFER(current->buffer,4);
541540
ACCEPT_RDATA_BUFFER(nbuf,5);
@@ -1116,9 +1115,8 @@ doPickSplit(Relation index, SpGistState *state,
11161115

11171116
leafdata=leafptr= (char*)palloc(totalLeafSizes);
11181117

1119-
ACCEPT_RDATA_DATA(&xlrec,MAXALIGN(sizeof(xlrec)),0);
1120-
ACCEPT_RDATA_DATA(innerTuple,innerTuple->size,1);
1121-
nRdata=2;
1118+
ACCEPT_RDATA_DATA(&xlrec,SizeOfSpgxlogPickSplit,0);
1119+
nRdata=1;
11221120

11231121
/* Here we begin making the changes to the target pages */
11241122
START_CRIT_SECTION();
@@ -1152,7 +1150,7 @@ doPickSplit(Relation index, SpGistState *state,
11521150
{
11531151
xlrec.nDelete=nToDelete;
11541152
ACCEPT_RDATA_DATA(toDelete,
1155-
MAXALIGN(sizeof(OffsetNumber)*nToDelete),
1153+
sizeof(OffsetNumber)*nToDelete,
11561154
nRdata);
11571155
nRdata++;
11581156
ACCEPT_RDATA_BUFFER(current->buffer,nRdata);
@@ -1251,13 +1249,11 @@ doPickSplit(Relation index, SpGistState *state,
12511249
}
12521250

12531251
xlrec.nInsert=nToInsert;
1254-
ACCEPT_RDATA_DATA(toInsert,
1255-
MAXALIGN(sizeof(OffsetNumber)*nToInsert),
1256-
nRdata);
1252+
ACCEPT_RDATA_DATA(toInsert,sizeof(OffsetNumber)*nToInsert,nRdata);
12571253
nRdata++;
1258-
ACCEPT_RDATA_DATA(leafPageSelect,
1259-
MAXALIGN(sizeof(uint8)*nToInsert),
1260-
nRdata);
1254+
ACCEPT_RDATA_DATA(leafPageSelect,sizeof(uint8)*nToInsert,nRdata);
1255+
nRdata++;
1256+
ACCEPT_RDATA_DATA(innerTuple,innerTuple->size,nRdata);
12611257
nRdata++;
12621258
ACCEPT_RDATA_DATA(leafdata,leafptr-leafdata,nRdata);
12631259
nRdata++;
@@ -1518,7 +1514,6 @@ spgAddNodeAction(Relation index, SpGistState *state,
15181514
xlrec.newPage= false;
15191515

15201516
ACCEPT_RDATA_DATA(&xlrec,sizeof(xlrec),0);
1521-
/* we assume sizeof(xlrec) is at least int-aligned */
15221517
ACCEPT_RDATA_DATA(newInnerTuple,newInnerTuple->size,1);
15231518
ACCEPT_RDATA_BUFFER(current->buffer,2);
15241519

@@ -1733,7 +1728,6 @@ spgSplitNodeAction(Relation index, SpGistState *state,
17331728
xlrec.newPage= false;
17341729

17351730
ACCEPT_RDATA_DATA(&xlrec,sizeof(xlrec),0);
1736-
/* we assume sizeof(xlrec) is at least int-aligned */
17371731
ACCEPT_RDATA_DATA(prefixTuple,prefixTuple->size,1);
17381732
ACCEPT_RDATA_DATA(postfixTuple,postfixTuple->size,2);
17391733
ACCEPT_RDATA_BUFFER(current->buffer,3);

‎src/backend/access/spgist/spgvacuum.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -327,8 +327,7 @@ vacuumLeafPage(spgBulkDeleteState *bds, Relation index, Buffer buffer,
327327
xlrec.blkno=BufferGetBlockNumber(buffer);
328328
STORE_STATE(&bds->spgstate,xlrec.stateSrc);
329329

330-
ACCEPT_RDATA_DATA(&xlrec,sizeof(xlrec),0);
331-
/* sizeof(xlrec) should be a multiple of sizeof(OffsetNumber) */
330+
ACCEPT_RDATA_DATA(&xlrec,SizeOfSpgxlogVacuumLeaf,0);
332331
ACCEPT_RDATA_DATA(toDead,sizeof(OffsetNumber)*xlrec.nDead,1);
333332
ACCEPT_RDATA_DATA(toPlaceholder,sizeof(OffsetNumber)*xlrec.nPlaceholder,2);
334333
ACCEPT_RDATA_DATA(moveSrc,sizeof(OffsetNumber)*xlrec.nMove,3);

‎src/backend/access/spgist/spgxlog.c

Lines changed: 71 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -109,13 +109,15 @@ spgRedoAddLeaf(XLogRecPtr lsn, XLogRecord *record)
109109
{
110110
char*ptr=XLogRecGetData(record);
111111
spgxlogAddLeaf*xldata= (spgxlogAddLeaf*)ptr;
112-
SpGistLeafTupleleafTuple;
112+
char*leafTuple;
113+
SpGistLeafTupleDataleafTupleHdr;
113114
Bufferbuffer;
114115
Pagepage;
115116

116-
/* we assume this is adequately aligned */
117117
ptr+=sizeof(spgxlogAddLeaf);
118-
leafTuple= (SpGistLeafTuple)ptr;
118+
leafTuple=ptr;
119+
/* the leaf tuple is unaligned, so make a copy to access its header */
120+
memcpy(&leafTupleHdr,leafTuple,sizeof(SpGistLeafTupleData));
119121

120122
/*
121123
* In normal operation we would have both current and parent pages locked
@@ -142,7 +144,7 @@ spgRedoAddLeaf(XLogRecPtr lsn, XLogRecord *record)
142144
if (xldata->offnumLeaf!=xldata->offnumHeadLeaf)
143145
{
144146
/* normal cases, tuple was added by SpGistPageAddNewItem */
145-
addOrReplaceTuple(page, (Item)leafTuple,leafTuple->size,
147+
addOrReplaceTuple(page, (Item)leafTuple,leafTupleHdr.size,
146148
xldata->offnumLeaf);
147149

148150
/* update head tuple's chain link if needed */
@@ -152,7 +154,7 @@ spgRedoAddLeaf(XLogRecPtr lsn, XLogRecord *record)
152154

153155
head= (SpGistLeafTuple)PageGetItem(page,
154156
PageGetItemId(page,xldata->offnumHeadLeaf));
155-
Assert(head->nextOffset==leafTuple->nextOffset);
157+
Assert(head->nextOffset==leafTupleHdr.nextOffset);
156158
head->nextOffset=xldata->offnumLeaf;
157159
}
158160
}
@@ -161,10 +163,10 @@ spgRedoAddLeaf(XLogRecPtr lsn, XLogRecord *record)
161163
/* replacing a DEAD tuple */
162164
PageIndexTupleDelete(page,xldata->offnumLeaf);
163165
if (PageAddItem(page,
164-
(Item)leafTuple,leafTuple->size,
166+
(Item)leafTuple,leafTupleHdr.size,
165167
xldata->offnumLeaf, false, false)!=xldata->offnumLeaf)
166168
elog(ERROR,"failed to add item of size %u to SPGiST index page",
167-
leafTuple->size);
169+
leafTupleHdr.size);
168170
}
169171

170172
PageSetLSN(page,lsn);
@@ -217,11 +219,11 @@ spgRedoMoveLeafs(XLogRecPtr lsn, XLogRecord *record)
217219

218220
nInsert=xldata->replaceDead ?1 :xldata->nMoves+1;
219221

220-
ptr+=MAXALIGN(sizeof(spgxlogMoveLeafs));
222+
ptr+=SizeOfSpgxlogMoveLeafs;
221223
toDelete= (OffsetNumber*)ptr;
222-
ptr+=MAXALIGN(sizeof(OffsetNumber)*xldata->nMoves);
224+
ptr+=sizeof(OffsetNumber)*xldata->nMoves;
223225
toInsert= (OffsetNumber*)ptr;
224-
ptr+=MAXALIGN(sizeof(OffsetNumber)*nInsert);
226+
ptr+=sizeof(OffsetNumber)*nInsert;
225227

226228
/* now ptr points to the list of leaf tuples */
227229

@@ -252,10 +254,20 @@ spgRedoMoveLeafs(XLogRecPtr lsn, XLogRecord *record)
252254

253255
for (i=0;i<nInsert;i++)
254256
{
255-
SpGistLeafTuplelt= (SpGistLeafTuple)ptr;
257+
char*leafTuple;
258+
SpGistLeafTupleDataleafTupleHdr;
256259

257-
addOrReplaceTuple(page, (Item)lt,lt->size,toInsert[i]);
258-
ptr+=lt->size;
260+
/*
261+
* the tuples are not aligned, so must copy to access
262+
* the size field.
263+
*/
264+
leafTuple=ptr;
265+
memcpy(&leafTupleHdr,leafTuple,
266+
sizeof(SpGistLeafTupleData));
267+
268+
addOrReplaceTuple(page, (Item)leafTuple,
269+
leafTupleHdr.size,toInsert[i]);
270+
ptr+=leafTupleHdr.size;
259271
}
260272

261273
PageSetLSN(page,lsn);
@@ -321,15 +333,17 @@ spgRedoAddNode(XLogRecPtr lsn, XLogRecord *record)
321333
{
322334
char*ptr=XLogRecGetData(record);
323335
spgxlogAddNode*xldata= (spgxlogAddNode*)ptr;
324-
SpGistInnerTupleinnerTuple;
336+
char*innerTuple;
337+
SpGistInnerTupleDatainnerTupleHdr;
325338
SpGistStatestate;
326339
Bufferbuffer;
327340
Pagepage;
328341
intbbi;
329342

330-
/* we assume this is adequately aligned */
331343
ptr+=sizeof(spgxlogAddNode);
332-
innerTuple= (SpGistInnerTuple)ptr;
344+
innerTuple=ptr;
345+
/* the tuple is unaligned, so make a copy to access its header */
346+
memcpy(&innerTupleHdr,innerTuple,sizeof(SpGistInnerTupleData));
333347

334348
fillFakeState(&state,xldata->stateSrc);
335349

@@ -348,11 +362,11 @@ spgRedoAddNode(XLogRecPtr lsn, XLogRecord *record)
348362
if (lsn>PageGetLSN(page))
349363
{
350364
PageIndexTupleDelete(page,xldata->offnum);
351-
if (PageAddItem(page, (Item)innerTuple,innerTuple->size,
365+
if (PageAddItem(page, (Item)innerTuple,innerTupleHdr.size,
352366
xldata->offnum,
353367
false, false)!=xldata->offnum)
354368
elog(ERROR,"failed to add item of size %u to SPGiST index page",
355-
innerTuple->size);
369+
innerTupleHdr.size);
356370

357371
PageSetLSN(page,lsn);
358372
MarkBufferDirty(buffer);
@@ -393,7 +407,7 @@ spgRedoAddNode(XLogRecPtr lsn, XLogRecord *record)
393407
if (lsn>PageGetLSN(page))
394408
{
395409
addOrReplaceTuple(page, (Item)innerTuple,
396-
innerTuple->size,xldata->offnumNew);
410+
innerTupleHdr.size,xldata->offnumNew);
397411

398412
/*
399413
* If parent is in this same page, don't advance LSN;
@@ -508,16 +522,21 @@ spgRedoSplitTuple(XLogRecPtr lsn, XLogRecord *record)
508522
{
509523
char*ptr=XLogRecGetData(record);
510524
spgxlogSplitTuple*xldata= (spgxlogSplitTuple*)ptr;
511-
SpGistInnerTupleprefixTuple;
512-
SpGistInnerTuplepostfixTuple;
525+
char*prefixTuple;
526+
SpGistInnerTupleDataprefixTupleHdr;
527+
char*postfixTuple;
528+
SpGistInnerTupleDatapostfixTupleHdr;
513529
Bufferbuffer;
514530
Pagepage;
515531

516-
/* we assume this is adequately aligned */
517532
ptr+=sizeof(spgxlogSplitTuple);
518-
prefixTuple= (SpGistInnerTuple)ptr;
519-
ptr+=prefixTuple->size;
520-
postfixTuple= (SpGistInnerTuple)ptr;
533+
prefixTuple=ptr;
534+
/* the prefix tuple is unaligned, so make a copy to access its header */
535+
memcpy(&prefixTupleHdr,prefixTuple,sizeof(SpGistInnerTupleData));
536+
ptr+=prefixTupleHdr.size;
537+
postfixTuple=ptr;
538+
/* postfix tuple is also unaligned */
539+
memcpy(&postfixTupleHdr,postfixTuple,sizeof(SpGistInnerTupleData));
521540

522541
/*
523542
* In normal operation we would have both pages locked simultaneously; but
@@ -543,7 +562,7 @@ spgRedoSplitTuple(XLogRecPtr lsn, XLogRecord *record)
543562
if (lsn>PageGetLSN(page))
544563
{
545564
addOrReplaceTuple(page, (Item)postfixTuple,
546-
postfixTuple->size,xldata->offnumPostfix);
565+
postfixTupleHdr.size,xldata->offnumPostfix);
547566

548567
PageSetLSN(page,lsn);
549568
MarkBufferDirty(buffer);
@@ -564,14 +583,14 @@ spgRedoSplitTuple(XLogRecPtr lsn, XLogRecord *record)
564583
if (lsn>PageGetLSN(page))
565584
{
566585
PageIndexTupleDelete(page,xldata->offnumPrefix);
567-
if (PageAddItem(page, (Item)prefixTuple,prefixTuple->size,
586+
if (PageAddItem(page, (Item)prefixTuple,prefixTupleHdr.size,
568587
xldata->offnumPrefix, false, false)!=xldata->offnumPrefix)
569588
elog(ERROR,"failed to add item of size %u to SPGiST index page",
570-
prefixTuple->size);
589+
prefixTupleHdr.size);
571590

572591
if (xldata->blknoPostfix==xldata->blknoPrefix)
573592
addOrReplaceTuple(page, (Item)postfixTuple,
574-
postfixTuple->size,
593+
postfixTupleHdr.size,
575594
xldata->offnumPostfix);
576595

577596
PageSetLSN(page,lsn);
@@ -587,7 +606,8 @@ spgRedoPickSplit(XLogRecPtr lsn, XLogRecord *record)
587606
{
588607
char*ptr=XLogRecGetData(record);
589608
spgxlogPickSplit*xldata= (spgxlogPickSplit*)ptr;
590-
SpGistInnerTupleinnerTuple;
609+
char*innerTuple;
610+
SpGistInnerTupleDatainnerTupleHdr;
591611
SpGistStatestate;
592612
OffsetNumber*toDelete;
593613
OffsetNumber*toInsert;
@@ -602,15 +622,18 @@ spgRedoPickSplit(XLogRecPtr lsn, XLogRecord *record)
602622

603623
fillFakeState(&state,xldata->stateSrc);
604624

605-
ptr+=MAXALIGN(sizeof(spgxlogPickSplit));
606-
innerTuple= (SpGistInnerTuple)ptr;
607-
ptr+=innerTuple->size;
625+
ptr+=SizeOfSpgxlogPickSplit;
608626
toDelete= (OffsetNumber*)ptr;
609-
ptr+=MAXALIGN(sizeof(OffsetNumber)*xldata->nDelete);
627+
ptr+=sizeof(OffsetNumber)*xldata->nDelete;
610628
toInsert= (OffsetNumber*)ptr;
611-
ptr+=MAXALIGN(sizeof(OffsetNumber)*xldata->nInsert);
629+
ptr+=sizeof(OffsetNumber)*xldata->nInsert;
612630
leafPageSelect= (uint8*)ptr;
613-
ptr+=MAXALIGN(sizeof(uint8)*xldata->nInsert);
631+
ptr+=sizeof(uint8)*xldata->nInsert;
632+
633+
innerTuple=ptr;
634+
/* the inner tuple is unaligned, so make a copy to access its header */
635+
memcpy(&innerTupleHdr,innerTuple,sizeof(SpGistInnerTupleData));
636+
ptr+=innerTupleHdr.size;
614637

615638
/* now ptr points to the list of leaf tuples */
616639

@@ -735,15 +758,20 @@ spgRedoPickSplit(XLogRecPtr lsn, XLogRecord *record)
735758
/* restore leaf tuples to src and/or dest page */
736759
for (i=0;i<xldata->nInsert;i++)
737760
{
738-
SpGistLeafTuplelt= (SpGistLeafTuple)ptr;
761+
char*leafTuple;
762+
SpGistLeafTupleDataleafTupleHdr;
739763

740-
ptr+=lt->size;
764+
/* the tuples are not aligned, so must copy to access the size field. */
765+
leafTuple=ptr;
766+
memcpy(&leafTupleHdr,leafTuple,sizeof(SpGistLeafTupleData));
767+
ptr+=leafTupleHdr.size;
741768

742769
page=leafPageSelect[i] ?destPage :srcPage;
743770
if (page==NULL)
744771
continue;/* no need to touch this page */
745772

746-
addOrReplaceTuple(page, (Item)lt,lt->size,toInsert[i]);
773+
addOrReplaceTuple(page, (Item)leafTuple,leafTupleHdr.size,
774+
toInsert[i]);
747775
}
748776

749777
/* Now update src and dest page LSNs if needed */
@@ -776,7 +804,7 @@ spgRedoPickSplit(XLogRecPtr lsn, XLogRecord *record)
776804

777805
if (lsn>PageGetLSN(page))
778806
{
779-
addOrReplaceTuple(page, (Item)innerTuple,innerTuple->size,
807+
addOrReplaceTuple(page, (Item)innerTuple,innerTupleHdr.size,
780808
xldata->offnumInner);
781809

782810
/* if inner is also parent, update link while we're here */
@@ -861,7 +889,7 @@ spgRedoVacuumLeaf(XLogRecPtr lsn, XLogRecord *record)
861889

862890
fillFakeState(&state,xldata->stateSrc);
863891

864-
ptr+=sizeof(spgxlogVacuumLeaf);
892+
ptr+=SizeOfSpgxlogVacuumLeaf;
865893
toDead= (OffsetNumber*)ptr;
866894
ptr+=sizeof(OffsetNumber)*xldata->nDead;
867895
toPlaceholder= (OffsetNumber*)ptr;
@@ -941,8 +969,7 @@ spgRedoVacuumRoot(XLogRecPtr lsn, XLogRecord *record)
941969
Bufferbuffer;
942970
Pagepage;
943971

944-
ptr+=sizeof(spgxlogVacuumRoot);
945-
toDelete= (OffsetNumber*)ptr;
972+
toDelete=xldata->offsets;
946973

947974
if (record->xl_info&XLR_BKP_BLOCK(0))
948975
(void)RestoreBackupBlock(lsn,record,0, false, false);
@@ -974,8 +1001,7 @@ spgRedoVacuumRedirect(XLogRecPtr lsn, XLogRecord *record)
9741001
Bufferbuffer;
9751002
Pagepage;
9761003

977-
ptr+=sizeof(spgxlogVacuumRedirect);
978-
itemToPlaceholder= (OffsetNumber*)ptr;
1004+
itemToPlaceholder=xldata->offsets;
9791005

9801006
/*
9811007
* If any redirection tuples are being removed, make sure there are no

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp