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

Commit1891a4b

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

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
@@ -1845,8 +1845,10 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf)
18451845
BTPageOpaquerootopaque;
18461846
ItemIditemid;
18471847
IndexTupleitem;
1848-
Sizeitemsz;
1849-
IndexTuplenew_item;
1848+
IndexTupleleft_item;
1849+
Sizeleft_item_sz;
1850+
IndexTupleright_item;
1851+
Sizeright_item_sz;
18501852
Buffermetabuf;
18511853
Pagemetapg;
18521854
BTMetaPageData*metad;
@@ -1865,6 +1867,26 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf)
18651867
metapg=BufferGetPage(metabuf);
18661868
metad=BTPageGetMeta(metapg);
18671869

1870+
/*
1871+
* Create downlink item for left page (old root). Since this will be the
1872+
* first item in a non-leaf page, it implicitly has minus-infinity key
1873+
* value, so we need not store any actual key in it.
1874+
*/
1875+
left_item_sz=sizeof(IndexTupleData);
1876+
left_item= (IndexTuple)palloc(left_item_sz);
1877+
left_item->t_info=left_item_sz;
1878+
ItemPointerSet(&(left_item->t_tid),lbkno,P_HIKEY);
1879+
1880+
/*
1881+
* Create downlink item for right page. The key for it is obtained from
1882+
* the "high key" position in the left page.
1883+
*/
1884+
itemid=PageGetItemId(lpage,P_HIKEY);
1885+
right_item_sz=ItemIdGetLength(itemid);
1886+
item= (IndexTuple)PageGetItem(lpage,itemid);
1887+
right_item=CopyIndexTuple(item);
1888+
ItemPointerSet(&(right_item->t_tid),rbkno,P_HIKEY);
1889+
18681890
/* NO EREPORT(ERROR) from here till newroot op is logged */
18691891
START_CRIT_SECTION();
18701892

@@ -1882,16 +1904,6 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf)
18821904
metad->btm_fastroot=rootblknum;
18831905
metad->btm_fastlevel=rootopaque->btpo.level;
18841906

1885-
/*
1886-
* Create downlink item for left page (old root). Since this will be the
1887-
* first item in a non-leaf page, it implicitly has minus-infinity key
1888-
* value, so we need not store any actual key in it.
1889-
*/
1890-
itemsz=sizeof(IndexTupleData);
1891-
new_item= (IndexTuple)palloc(itemsz);
1892-
new_item->t_info=itemsz;
1893-
ItemPointerSet(&(new_item->t_tid),lbkno,P_HIKEY);
1894-
18951907
/*
18961908
* Insert the left page pointer into the new root page. The root page is
18971909
* the rightmost page on its level so there is no "high key" in it; the
@@ -1900,32 +1912,20 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf)
19001912
* Note: we *must* insert the two items in item-number order, for the
19011913
* benefit of _bt_restore_page().
19021914
*/
1903-
if (PageAddItem(rootpage, (Item)new_item,itemsz,P_HIKEY,
1915+
if (PageAddItem(rootpage, (Item)left_item,left_item_sz,P_HIKEY,
19041916
false, false)==InvalidOffsetNumber)
19051917
elog(PANIC,"failed to add leftkey to new root page"
19061918
" while splitting block %u of index \"%s\"",
19071919
BufferGetBlockNumber(lbuf),RelationGetRelationName(rel));
1908-
pfree(new_item);
1909-
1910-
/*
1911-
* Create downlink item for right page. The key for it is obtained from
1912-
* the "high key" position in the left page.
1913-
*/
1914-
itemid=PageGetItemId(lpage,P_HIKEY);
1915-
itemsz=ItemIdGetLength(itemid);
1916-
item= (IndexTuple)PageGetItem(lpage,itemid);
1917-
new_item=CopyIndexTuple(item);
1918-
ItemPointerSet(&(new_item->t_tid),rbkno,P_HIKEY);
19191920

19201921
/*
19211922
* insert the right page pointer into the new root page.
19221923
*/
1923-
if (PageAddItem(rootpage, (Item)new_item,itemsz,P_FIRSTKEY,
1924+
if (PageAddItem(rootpage, (Item)right_item,right_item_sz,P_FIRSTKEY,
19241925
false, false)==InvalidOffsetNumber)
19251926
elog(PANIC,"failed to add rightkey to new root page"
19261927
" while splitting block %u of index \"%s\"",
19271928
BufferGetBlockNumber(lbuf),RelationGetRelationName(rel));
1928-
pfree(new_item);
19291929

19301930
MarkBufferDirty(rootbuf);
19311931
MarkBufferDirty(metabuf);
@@ -1971,6 +1971,9 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf)
19711971
/* done with metapage */
19721972
_bt_relbuf(rel,metabuf);
19731973

1974+
pfree(left_item);
1975+
pfree(right_item);
1976+
19741977
returnrootbuf;
19751978
}
19761979

‎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
@@ -739,9 +739,8 @@ XLogInsert(RmgrId rmid, uint8 info, XLogRecData *rdata)
739739

740740
if (rechdr==NULL)
741741
{
742-
rechdr=malloc(SizeOfXLogRecord);
743-
if (rechdr==NULL)
744-
elog(ERROR,"out of memory");
742+
staticcharrechdrbuf[SizeOfXLogRecord+MAXIMUM_ALIGNOF];
743+
rechdr= (XLogRecord*)MAXALIGN(&rechdrbuf);
745744
MemSet(rechdr,0,SizeOfXLogRecord);
746745
}
747746

@@ -2248,6 +2247,7 @@ XLogFileInit(XLogSegNo logsegno, bool *use_existent, bool use_lock)
22482247
{
22492248
charpath[MAXPGPATH];
22502249
chartmppath[MAXPGPATH];
2250+
charzbuffer_raw[BLCKSZ+MAXIMUM_ALIGNOF];
22512251
char*zbuffer;
22522252
XLogSegNoinstalled_segno;
22532253
intmax_advance;
@@ -2286,16 +2286,6 @@ XLogFileInit(XLogSegNo logsegno, bool *use_existent, bool use_lock)
22862286

22872287
unlink(tmppath);
22882288

2289-
/*
2290-
* Allocate a buffer full of zeros. This is done before opening the file
2291-
* so that we don't leak the file descriptor if palloc fails.
2292-
*
2293-
* Note: palloc zbuffer, instead of just using a local char array, to
2294-
* ensure it is reasonably well-aligned; this may save a few cycles
2295-
* transferring data to the kernel.
2296-
*/
2297-
zbuffer= (char*)palloc0(XLOG_BLCKSZ);
2298-
22992289
/* do not use get_sync_bit() here --- want to fsync only at end of fill */
23002290
fd=BasicOpenFile(tmppath,O_RDWR |O_CREAT |O_EXCL |PG_BINARY,
23012291
S_IRUSR |S_IWUSR);
@@ -2312,7 +2302,12 @@ XLogFileInit(XLogSegNo logsegno, bool *use_existent, bool use_lock)
23122302
* fsync below) that all the indirect blocks are down on disk.Therefore,
23132303
* fdatasync(2) or O_DSYNC will be sufficient to sync future writes to the
23142304
* log file.
2305+
*
2306+
* Note: ensure the buffer is reasonably well-aligned; this may save a few
2307+
* cycles transferring data to the kernel.
23152308
*/
2309+
zbuffer= (char*)MAXALIGN(zbuffer_raw);
2310+
memset(zbuffer,0,BLCKSZ);
23162311
for (nbytes=0;nbytes<XLogSegSize;nbytes+=XLOG_BLCKSZ)
23172312
{
23182313
errno=0;
@@ -2335,7 +2330,6 @@ XLogFileInit(XLogSegNo logsegno, bool *use_existent, bool use_lock)
23352330
errmsg("could not write to file \"%s\": %m",tmppath)));
23362331
}
23372332
}
2338-
pfree(zbuffer);
23392333

23402334
if (pg_fsync(fd)!=0)
23412335
{

‎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/memutils.h"
@@ -418,8 +419,6 @@ PageRepairFragmentation(Page page)
418419
Offsetpd_lower= ((PageHeader)page)->pd_lower;
419420
Offsetpd_upper= ((PageHeader)page)->pd_upper;
420421
Offsetpd_special= ((PageHeader)page)->pd_special;
421-
itemIdSortitemidbase,
422-
itemidptr;
423422
ItemIdlp;
424423
intnline,
425424
nstorage,
@@ -469,10 +468,11 @@ PageRepairFragmentation(Page page)
469468
((PageHeader)page)->pd_upper=pd_special;
470469
}
471470
else
472-
{/* nstorage != 0 */
471+
{
473472
/* Need to compact the page the hard way */
474-
itemidbase= (itemIdSort)palloc(sizeof(itemIdSortData)*nstorage);
475-
itemidptr=itemidbase;
473+
itemIdSortDataitemidbase[MaxHeapTuplesPerPage];
474+
itemIdSortitemidptr=itemidbase;
475+
476476
totallen=0;
477477
for (i=0;i<nline;i++)
478478
{
@@ -517,8 +517,6 @@ PageRepairFragmentation(Page page)
517517
}
518518

519519
((PageHeader)page)->pd_upper=upper;
520-
521-
pfree(itemidbase);
522520
}
523521

524522
/* Set hint bit for PageAddItem */
@@ -767,8 +765,8 @@ PageIndexMultiDelete(Page page, OffsetNumber *itemnos, int nitems)
767765
Offsetpd_lower=phdr->pd_lower;
768766
Offsetpd_upper=phdr->pd_upper;
769767
Offsetpd_special=phdr->pd_special;
770-
itemIdSortitemidbase,
771-
itemidptr;
768+
itemIdSortDataitemidbase[MaxIndexTuplesPerPage];
769+
itemIdSortitemidptr;
772770
ItemIdlp;
773771
intnline,
774772
nused;
@@ -780,6 +778,8 @@ PageIndexMultiDelete(Page page, OffsetNumber *itemnos, int nitems)
780778
intnextitm;
781779
OffsetNumberoffnum;
782780

781+
Assert(nitems<MaxIndexTuplesPerPage);
782+
783783
/*
784784
* If there aren't very many items to delete, then retail
785785
* PageIndexTupleDelete is the best way. Delete the items in reverse
@@ -814,7 +814,6 @@ PageIndexMultiDelete(Page page, OffsetNumber *itemnos, int nitems)
814814
* still validity-checking.
815815
*/
816816
nline=PageGetMaxOffsetNumber(page);
817-
itemidbase= (itemIdSort)palloc(sizeof(itemIdSortData)*nline);
818817
itemidptr=itemidbase;
819818
totallen=0;
820819
nused=0;
@@ -880,8 +879,6 @@ PageIndexMultiDelete(Page page, OffsetNumber *itemnos, int nitems)
880879

881880
phdr->pd_lower=SizeOfPageHeaderData+nused*sizeof(ItemIdData);
882881
phdr->pd_upper=upper;
883-
884-
pfree(itemidbase);
885882
}
886883

887884

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp