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

Commit877b088

Browse files
committed
Avoid allocations in critical sections.
If a palloc in a critical section fails, it becomes a PANIC.
1 parentc7b3539 commit877b088

File tree

4 files changed

+49
-57
lines changed

4 files changed

+49
-57
lines changed

‎src/backend/access/nbtree/nbtinsert.c

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1995,8 +1995,10 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf)
19951995
BTPageOpaquelopaque;
19961996
ItemIditemid;
19971997
IndexTupleitem;
1998-
Sizeitemsz;
1999-
IndexTuplenew_item;
1998+
IndexTupleleft_item;
1999+
Sizeleft_item_sz;
2000+
IndexTupleright_item;
2001+
Sizeright_item_sz;
20002002
Buffermetabuf;
20012003
Pagemetapg;
20022004
BTMetaPageData*metad;
@@ -2016,6 +2018,26 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf)
20162018
metapg=BufferGetPage(metabuf);
20172019
metad=BTPageGetMeta(metapg);
20182020

2021+
/*
2022+
* Create downlink item for left page (old root). Since this will be the
2023+
* first item in a non-leaf page, it implicitly has minus-infinity key
2024+
* value, so we need not store any actual key in it.
2025+
*/
2026+
left_item_sz=sizeof(IndexTupleData);
2027+
left_item= (IndexTuple)palloc(left_item_sz);
2028+
left_item->t_info=left_item_sz;
2029+
ItemPointerSet(&(left_item->t_tid),lbkno,P_HIKEY);
2030+
2031+
/*
2032+
* Create downlink item for right page. The key for it is obtained from
2033+
* the "high key" position in the left page.
2034+
*/
2035+
itemid=PageGetItemId(lpage,P_HIKEY);
2036+
right_item_sz=ItemIdGetLength(itemid);
2037+
item= (IndexTuple)PageGetItem(lpage,itemid);
2038+
right_item=CopyIndexTuple(item);
2039+
ItemPointerSet(&(right_item->t_tid),rbkno,P_HIKEY);
2040+
20192041
/* NO EREPORT(ERROR) from here till newroot op is logged */
20202042
START_CRIT_SECTION();
20212043

@@ -2033,16 +2055,6 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf)
20332055
metad->btm_fastroot=rootblknum;
20342056
metad->btm_fastlevel=rootopaque->btpo.level;
20352057

2036-
/*
2037-
* Create downlink item for left page (old root). Since this will be the
2038-
* first item in a non-leaf page, it implicitly has minus-infinity key
2039-
* value, so we need not store any actual key in it.
2040-
*/
2041-
itemsz=sizeof(IndexTupleData);
2042-
new_item= (IndexTuple)palloc(itemsz);
2043-
new_item->t_info=itemsz;
2044-
ItemPointerSet(&(new_item->t_tid),lbkno,P_HIKEY);
2045-
20462058
/*
20472059
* Insert the left page pointer into the new root page. The root page is
20482060
* the rightmost page on its level so there is no "high key" in it; the
@@ -2051,32 +2063,20 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf)
20512063
* Note: we *must* insert the two items in item-number order, for the
20522064
* benefit of _bt_restore_page().
20532065
*/
2054-
if (PageAddItem(rootpage, (Item)new_item,itemsz,P_HIKEY,
2066+
if (PageAddItem(rootpage, (Item)left_item,left_item_sz,P_HIKEY,
20552067
false, false)==InvalidOffsetNumber)
20562068
elog(PANIC,"failed to add leftkey to new root page"
20572069
" while splitting block %u of index \"%s\"",
20582070
BufferGetBlockNumber(lbuf),RelationGetRelationName(rel));
2059-
pfree(new_item);
2060-
2061-
/*
2062-
* Create downlink item for right page. The key for it is obtained from
2063-
* the "high key" position in the left page.
2064-
*/
2065-
itemid=PageGetItemId(lpage,P_HIKEY);
2066-
itemsz=ItemIdGetLength(itemid);
2067-
item= (IndexTuple)PageGetItem(lpage,itemid);
2068-
new_item=CopyIndexTuple(item);
2069-
ItemPointerSet(&(new_item->t_tid),rbkno,P_HIKEY);
20702071

20712072
/*
20722073
* insert the right page pointer into the new root page.
20732074
*/
2074-
if (PageAddItem(rootpage, (Item)new_item,itemsz,P_FIRSTKEY,
2075+
if (PageAddItem(rootpage, (Item)right_item,right_item_sz,P_FIRSTKEY,
20752076
false, false)==InvalidOffsetNumber)
20762077
elog(PANIC,"failed to add rightkey to new root page"
20772078
" while splitting block %u of index \"%s\"",
20782079
BufferGetBlockNumber(lbuf),RelationGetRelationName(rel));
2079-
pfree(new_item);
20802080

20812081
/* Clear the incomplete-split flag in the left child */
20822082
Assert(P_INCOMPLETE_SPLIT(lopaque));
@@ -2129,6 +2129,9 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf)
21292129
/* done with metapage */
21302130
_bt_relbuf(rel,metabuf);
21312131

2132+
pfree(left_item);
2133+
pfree(right_item);
2134+
21322135
returnrootbuf;
21332136
}
21342137

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

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,8 @@ cmpOffsetNumbers(const void *a, const void *b)
122122
*
123123
* NB: this is used during WAL replay, so beware of trying to make it too
124124
* smart. In particular, it shouldn't use "state" except for calling
125-
* spgFormDeadTuple().
125+
* spgFormDeadTuple(). This is also used in a critical section, so no
126+
* pallocs either!
126127
*/
127128
void
128129
spgPageIndexMultiDelete(SpGistState*state,Pagepage,
@@ -131,7 +132,7 @@ spgPageIndexMultiDelete(SpGistState *state, Page page,
131132
BlockNumberblkno,OffsetNumberoffnum)
132133
{
133134
OffsetNumberfirstItem;
134-
OffsetNumber*sortednos;
135+
OffsetNumbersortednos[MaxIndexTuplesPerPage];
135136
SpGistDeadTupletuple=NULL;
136137
inti;
137138

@@ -145,7 +146,6 @@ spgPageIndexMultiDelete(SpGistState *state, Page page,
145146
* replacement tuples.) However, we must not scribble on the caller's
146147
* array, so we have to make a copy.
147148
*/
148-
sortednos= (OffsetNumber*)palloc(sizeof(OffsetNumber)*nitems);
149149
memcpy(sortednos,itemnos,sizeof(OffsetNumber)*nitems);
150150
if (nitems>1)
151151
qsort(sortednos,nitems,sizeof(OffsetNumber),cmpOffsetNumbers);
@@ -173,8 +173,6 @@ spgPageIndexMultiDelete(SpGistState *state, Page page,
173173
elseif (tupstate==SPGIST_PLACEHOLDER)
174174
SpGistPageGetOpaque(page)->nPlaceholder++;
175175
}
176-
177-
pfree(sortednos);
178176
}
179177

180178
/*

‎src/backend/access/transam/xlog.c

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -859,9 +859,8 @@ XLogInsert(RmgrId rmid, uint8 info, XLogRecData *rdata)
859859

860860
if (rechdr==NULL)
861861
{
862-
rechdr=malloc(SizeOfXLogRecord);
863-
if (rechdr==NULL)
864-
elog(ERROR,"out of memory");
862+
staticcharrechdrbuf[SizeOfXLogRecord+MAXIMUM_ALIGNOF];
863+
rechdr= (XLogRecord*)MAXALIGN(&rechdrbuf);
865864
MemSet(rechdr,0,SizeOfXLogRecord);
866865
}
867866

@@ -3080,6 +3079,7 @@ XLogFileInit(XLogSegNo logsegno, bool *use_existent, bool use_lock)
30803079
{
30813080
charpath[MAXPGPATH];
30823081
chartmppath[MAXPGPATH];
3082+
charzbuffer_raw[BLCKSZ+MAXIMUM_ALIGNOF];
30833083
char*zbuffer;
30843084
XLogSegNoinstalled_segno;
30853085
intmax_advance;
@@ -3118,16 +3118,6 @@ XLogFileInit(XLogSegNo logsegno, bool *use_existent, bool use_lock)
31183118

31193119
unlink(tmppath);
31203120

3121-
/*
3122-
* Allocate a buffer full of zeros. This is done before opening the file
3123-
* so that we don't leak the file descriptor if palloc fails.
3124-
*
3125-
* Note: palloc zbuffer, instead of just using a local char array, to
3126-
* ensure it is reasonably well-aligned; this may save a few cycles
3127-
* transferring data to the kernel.
3128-
*/
3129-
zbuffer= (char*)palloc0(XLOG_BLCKSZ);
3130-
31313121
/* do not use get_sync_bit() here --- want to fsync only at end of fill */
31323122
fd=BasicOpenFile(tmppath,O_RDWR |O_CREAT |O_EXCL |PG_BINARY,
31333123
S_IRUSR |S_IWUSR);
@@ -3144,7 +3134,12 @@ XLogFileInit(XLogSegNo logsegno, bool *use_existent, bool use_lock)
31443134
* fsync below) that all the indirect blocks are down on disk.Therefore,
31453135
* fdatasync(2) or O_DSYNC will be sufficient to sync future writes to the
31463136
* log file.
3137+
*
3138+
* Note: ensure the buffer is reasonably well-aligned; this may save a few
3139+
* cycles transferring data to the kernel.
31473140
*/
3141+
zbuffer= (char*)MAXALIGN(zbuffer_raw);
3142+
memset(zbuffer,0,BLCKSZ);
31483143
for (nbytes=0;nbytes<XLogSegSize;nbytes+=XLOG_BLCKSZ)
31493144
{
31503145
errno=0;
@@ -3167,7 +3162,6 @@ XLogFileInit(XLogSegNo logsegno, bool *use_existent, bool use_lock)
31673162
errmsg("could not write to file \"%s\": %m",tmppath)));
31683163
}
31693164
}
3170-
pfree(zbuffer);
31713165

31723166
if (pg_fsync(fd)!=0)
31733167
{

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

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include"postgres.h"
1616

1717
#include"access/htup_details.h"
18+
#include"access/itup.h"
1819
#include"access/xlog.h"
1920
#include"storage/checksum.h"
2021
#include"utils/memdebug.h"
@@ -433,8 +434,6 @@ PageRepairFragmentation(Page page)
433434
Offsetpd_lower= ((PageHeader)page)->pd_lower;
434435
Offsetpd_upper= ((PageHeader)page)->pd_upper;
435436
Offsetpd_special= ((PageHeader)page)->pd_special;
436-
itemIdSortitemidbase,
437-
itemidptr;
438437
ItemIdlp;
439438
intnline,
440439
nstorage,
@@ -484,10 +483,11 @@ PageRepairFragmentation(Page page)
484483
((PageHeader)page)->pd_upper=pd_special;
485484
}
486485
else
487-
{/* nstorage != 0 */
486+
{
488487
/* Need to compact the page the hard way */
489-
itemidbase= (itemIdSort)palloc(sizeof(itemIdSortData)*nstorage);
490-
itemidptr=itemidbase;
488+
itemIdSortDataitemidbase[MaxHeapTuplesPerPage];
489+
itemIdSortitemidptr=itemidbase;
490+
491491
totallen=0;
492492
for (i=0;i<nline;i++)
493493
{
@@ -532,8 +532,6 @@ PageRepairFragmentation(Page page)
532532
}
533533

534534
((PageHeader)page)->pd_upper=upper;
535-
536-
pfree(itemidbase);
537535
}
538536

539537
/* Set hint bit for PageAddItem */
@@ -782,8 +780,8 @@ PageIndexMultiDelete(Page page, OffsetNumber *itemnos, int nitems)
782780
Offsetpd_lower=phdr->pd_lower;
783781
Offsetpd_upper=phdr->pd_upper;
784782
Offsetpd_special=phdr->pd_special;
785-
itemIdSortitemidbase,
786-
itemidptr;
783+
itemIdSortDataitemidbase[MaxIndexTuplesPerPage];
784+
itemIdSortitemidptr;
787785
ItemIdlp;
788786
intnline,
789787
nused;
@@ -795,6 +793,8 @@ PageIndexMultiDelete(Page page, OffsetNumber *itemnos, int nitems)
795793
intnextitm;
796794
OffsetNumberoffnum;
797795

796+
Assert(nitems<MaxIndexTuplesPerPage);
797+
798798
/*
799799
* If there aren't very many items to delete, then retail
800800
* PageIndexTupleDelete is the best way. Delete the items in reverse
@@ -829,7 +829,6 @@ PageIndexMultiDelete(Page page, OffsetNumber *itemnos, int nitems)
829829
* still validity-checking.
830830
*/
831831
nline=PageGetMaxOffsetNumber(page);
832-
itemidbase= (itemIdSort)palloc(sizeof(itemIdSortData)*nline);
833832
itemidptr=itemidbase;
834833
totallen=0;
835834
nused=0;
@@ -895,8 +894,6 @@ PageIndexMultiDelete(Page page, OffsetNumber *itemnos, int nitems)
895894

896895
phdr->pd_lower=SizeOfPageHeaderData+nused*sizeof(ItemIdData);
897896
phdr->pd_upper=upper;
898-
899-
pfree(itemidbase);
900897
}
901898

902899

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp