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

Commit7d1e0e8

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

File tree

4 files changed

+46
-48
lines changed

4 files changed

+46
-48
lines changed

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

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1839,8 +1839,10 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf)
18391839
BTPageOpaquerootopaque;
18401840
ItemIditemid;
18411841
IndexTupleitem;
1842-
Sizeitemsz;
1843-
IndexTuplenew_item;
1842+
IndexTupleleft_item;
1843+
Sizeleft_item_sz;
1844+
IndexTupleright_item;
1845+
Sizeright_item_sz;
18441846
Buffermetabuf;
18451847
Pagemetapg;
18461848
BTMetaPageData*metad;
@@ -1859,6 +1861,26 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf)
18591861
metapg=BufferGetPage(metabuf);
18601862
metad=BTPageGetMeta(metapg);
18611863

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

@@ -1876,16 +1898,6 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf)
18761898
metad->btm_fastroot=rootblknum;
18771899
metad->btm_fastlevel=rootopaque->btpo.level;
18781900

1879-
/*
1880-
* Create downlink item for left page (old root). Since this will be the
1881-
* first item in a non-leaf page, it implicitly has minus-infinity key
1882-
* value, so we need not store any actual key in it.
1883-
*/
1884-
itemsz=sizeof(IndexTupleData);
1885-
new_item= (IndexTuple)palloc(itemsz);
1886-
new_item->t_info=itemsz;
1887-
ItemPointerSet(&(new_item->t_tid),lbkno,P_HIKEY);
1888-
18891901
/*
18901902
* Insert the left page pointer into the new root page. The root page is
18911903
* the rightmost page on its level so there is no "high key" in it; the
@@ -1894,32 +1906,20 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf)
18941906
* Note: we *must* insert the two items in item-number order, for the
18951907
* benefit of _bt_restore_page().
18961908
*/
1897-
if (PageAddItem(rootpage, (Item)new_item,itemsz,P_HIKEY,
1909+
if (PageAddItem(rootpage, (Item)left_item,left_item_sz,P_HIKEY,
18981910
false, false)==InvalidOffsetNumber)
18991911
elog(PANIC,"failed to add leftkey to new root page"
19001912
" while splitting block %u of index \"%s\"",
19011913
BufferGetBlockNumber(lbuf),RelationGetRelationName(rel));
1902-
pfree(new_item);
1903-
1904-
/*
1905-
* Create downlink item for right page. The key for it is obtained from
1906-
* the "high key" position in the left page.
1907-
*/
1908-
itemid=PageGetItemId(lpage,P_HIKEY);
1909-
itemsz=ItemIdGetLength(itemid);
1910-
item= (IndexTuple)PageGetItem(lpage,itemid);
1911-
new_item=CopyIndexTuple(item);
1912-
ItemPointerSet(&(new_item->t_tid),rbkno,P_HIKEY);
19131914

19141915
/*
19151916
* insert the right page pointer into the new root page.
19161917
*/
1917-
if (PageAddItem(rootpage, (Item)new_item,itemsz,P_FIRSTKEY,
1918+
if (PageAddItem(rootpage, (Item)right_item,right_item_sz,P_FIRSTKEY,
19181919
false, false)==InvalidOffsetNumber)
19191920
elog(PANIC,"failed to add rightkey to new root page"
19201921
" while splitting block %u of index \"%s\"",
19211922
BufferGetBlockNumber(lbuf),RelationGetRelationName(rel));
1922-
pfree(new_item);
19231923

19241924
MarkBufferDirty(rootbuf);
19251925
MarkBufferDirty(metabuf);
@@ -1967,6 +1967,9 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf)
19671967
/* done with metapage */
19681968
_bt_relbuf(rel,metabuf);
19691969

1970+
pfree(left_item);
1971+
pfree(right_item);
1972+
19701973
returnrootbuf;
19711974
}
19721975

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

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

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

179177
/*

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2449,6 +2449,7 @@ XLogFileInit(uint32 log, uint32 seg,
24492449
{
24502450
charpath[MAXPGPATH];
24512451
chartmppath[MAXPGPATH];
2452+
charzbuffer_raw[BLCKSZ+MAXIMUM_ALIGNOF];
24522453
char*zbuffer;
24532454
uint32installed_log;
24542455
uint32installed_seg;
@@ -2506,11 +2507,11 @@ XLogFileInit(uint32 log, uint32 seg,
25062507
* fdatasync(2) or O_DSYNC will be sufficient to sync future writes to the
25072508
* log file.
25082509
*
2509-
* Note: palloc zbuffer, instead of just using a local char array, to
2510-
* ensure it is reasonably well-aligned; this may save a few cycles
2511-
* transferring data to the kernel.
2510+
* Note: ensure the buffer is reasonably well-aligned; this may save a few
2511+
* cycles transferring data to the kernel.
25122512
*/
2513-
zbuffer= (char*)palloc0(XLOG_BLCKSZ);
2513+
zbuffer= (char*)MAXALIGN(zbuffer_raw);
2514+
memset(zbuffer,0,BLCKSZ);
25142515
for (nbytes=0;nbytes<XLogSegSize;nbytes+=XLOG_BLCKSZ)
25152516
{
25162517
errno=0;
@@ -2530,7 +2531,6 @@ XLogFileInit(uint32 log, uint32 seg,
25302531
errmsg("could not write to file \"%s\": %m",tmppath)));
25312532
}
25322533
}
2533-
pfree(zbuffer);
25342534

25352535
if (pg_fsync(fd)!=0)
25362536
ereport(ERROR,

‎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.h"
18+
#include"access/itup.h"
1819

1920

2021
/* ----------------------------------------------------------------
@@ -362,8 +363,6 @@ PageRepairFragmentation(Page page)
362363
Offsetpd_lower= ((PageHeader)page)->pd_lower;
363364
Offsetpd_upper= ((PageHeader)page)->pd_upper;
364365
Offsetpd_special= ((PageHeader)page)->pd_special;
365-
itemIdSortitemidbase,
366-
itemidptr;
367366
ItemIdlp;
368367
intnline,
369368
nstorage,
@@ -413,10 +412,11 @@ PageRepairFragmentation(Page page)
413412
((PageHeader)page)->pd_upper=pd_special;
414413
}
415414
else
416-
{/* nstorage != 0 */
415+
{
417416
/* Need to compact the page the hard way */
418-
itemidbase= (itemIdSort)palloc(sizeof(itemIdSortData)*nstorage);
419-
itemidptr=itemidbase;
417+
itemIdSortDataitemidbase[MaxHeapTuplesPerPage];
418+
itemIdSortitemidptr=itemidbase;
419+
420420
totallen=0;
421421
for (i=0;i<nline;i++)
422422
{
@@ -461,8 +461,6 @@ PageRepairFragmentation(Page page)
461461
}
462462

463463
((PageHeader)page)->pd_upper=upper;
464-
465-
pfree(itemidbase);
466464
}
467465

468466
/* Set hint bit for PageAddItem */
@@ -711,8 +709,8 @@ PageIndexMultiDelete(Page page, OffsetNumber *itemnos, int nitems)
711709
Offsetpd_lower=phdr->pd_lower;
712710
Offsetpd_upper=phdr->pd_upper;
713711
Offsetpd_special=phdr->pd_special;
714-
itemIdSortitemidbase,
715-
itemidptr;
712+
itemIdSortDataitemidbase[MaxIndexTuplesPerPage];
713+
itemIdSortitemidptr;
716714
ItemIdlp;
717715
intnline,
718716
nused;
@@ -724,6 +722,8 @@ PageIndexMultiDelete(Page page, OffsetNumber *itemnos, int nitems)
724722
intnextitm;
725723
OffsetNumberoffnum;
726724

725+
Assert(nitems<MaxIndexTuplesPerPage);
726+
727727
/*
728728
* If there aren't very many items to delete, then retail
729729
* PageIndexTupleDelete is the best way. Delete the items in reverse
@@ -758,7 +758,6 @@ PageIndexMultiDelete(Page page, OffsetNumber *itemnos, int nitems)
758758
* still validity-checking.
759759
*/
760760
nline=PageGetMaxOffsetNumber(page);
761-
itemidbase= (itemIdSort)palloc(sizeof(itemIdSortData)*nline);
762761
itemidptr=itemidbase;
763762
totallen=0;
764763
nused=0;
@@ -824,6 +823,4 @@ PageIndexMultiDelete(Page page, OffsetNumber *itemnos, int nitems)
824823

825824
phdr->pd_lower=SizeOfPageHeaderData+nused*sizeof(ItemIdData);
826825
phdr->pd_upper=upper;
827-
828-
pfree(itemidbase);
829826
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp