Skip to content

Commit 895243d

Browse files
committed
Avoid allocations in critical sections.
If a palloc in a critical section fails, it becomes a PANIC.
1 parent 447e237 commit 895243d

File tree

3 files changed

+43
-43
lines changed

3 files changed

+43
-43
lines changed

src/backend/access/nbtree/nbtinsert.c

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1840,8 +1840,10 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf)
18401840
BTPageOpaque rootopaque;
18411841
ItemId itemid;
18421842
IndexTuple item;
1843-
Size itemsz;
1844-
IndexTuple new_item;
1843+
IndexTuple left_item;
1844+
Size left_item_sz;
1845+
IndexTuple right_item;
1846+
Size right_item_sz;
18451847
Buffer metabuf;
18461848
Page metapg;
18471849
BTMetaPageData *metad;
@@ -1860,6 +1862,26 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf)
18601862
metapg = BufferGetPage(metabuf);
18611863
metad = BTPageGetMeta(metapg);
18621864

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

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

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

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

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

1971+
pfree(left_item);
1972+
pfree(right_item);
1973+
19711974
return rootbuf;
19721975
}
19731976

src/backend/access/transam/xlog.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2348,6 +2348,7 @@ XLogFileInit(uint32 log, uint32 seg,
23482348
{
23492349
char path[MAXPGPATH];
23502350
char tmppath[MAXPGPATH];
2351+
char zbuffer_raw[BLCKSZ + MAXIMUM_ALIGNOF];
23512352
char *zbuffer;
23522353
uint32 installed_log;
23532354
uint32 installed_seg;
@@ -2405,11 +2406,11 @@ XLogFileInit(uint32 log, uint32 seg,
24052406
* fdatasync(2) or O_DSYNC will be sufficient to sync future writes to the
24062407
* log file.
24072408
*
2408-
* Note: palloc zbuffer, instead of just using a local char array, to
2409-
* ensure it is reasonably well-aligned; this may save a few cycles
2410-
* transferring data to the kernel.
2409+
* Note: ensure the buffer is reasonably well-aligned; this may save a few
2410+
* cycles transferring data to the kernel.
24112411
*/
2412-
zbuffer = (char *) palloc0(XLOG_BLCKSZ);
2412+
zbuffer = (char *) MAXALIGN(zbuffer_raw);
2413+
memset(zbuffer, 0, BLCKSZ);
24132414
for (nbytes = 0; nbytes < XLogSegSize; nbytes += XLOG_BLCKSZ)
24142415
{
24152416
errno = 0;
@@ -2429,7 +2430,6 @@ XLogFileInit(uint32 log, uint32 seg,
24292430
errmsg("could not write to file \"%s\": %m", tmppath)));
24302431
}
24312432
}
2432-
pfree(zbuffer);
24332433

24342434
if (pg_fsync(fd) != 0)
24352435
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
#include "storage/bufpage.h"
1920

2021

@@ -363,8 +364,6 @@ PageRepairFragmentation(Page page)
363364
Offset pd_lower = ((PageHeader) page)->pd_lower;
364365
Offset pd_upper = ((PageHeader) page)->pd_upper;
365366
Offset pd_special = ((PageHeader) page)->pd_special;
366-
itemIdSort itemidbase,
367-
itemidptr;
368367
ItemId lp;
369368
int nline,
370369
nstorage,
@@ -414,10 +413,11 @@ PageRepairFragmentation(Page page)
414413
((PageHeader) page)->pd_upper = pd_special;
415414
}
416415
else
417-
{ /* nstorage != 0 */
416+
{
418417
/* Need to compact the page the hard way */
419-
itemidbase = (itemIdSort) palloc(sizeof(itemIdSortData) * nstorage);
420-
itemidptr = itemidbase;
418+
itemIdSortData itemidbase[MaxHeapTuplesPerPage];
419+
itemIdSort itemidptr = itemidbase;
420+
421421
totallen = 0;
422422
for (i = 0; i < nline; i++)
423423
{
@@ -462,8 +462,6 @@ PageRepairFragmentation(Page page)
462462
}
463463

464464
((PageHeader) page)->pd_upper = upper;
465-
466-
pfree(itemidbase);
467465
}
468466

469467
/* Set hint bit for PageAddItem */
@@ -712,8 +710,8 @@ PageIndexMultiDelete(Page page, OffsetNumber *itemnos, int nitems)
712710
Offset pd_lower = phdr->pd_lower;
713711
Offset pd_upper = phdr->pd_upper;
714712
Offset pd_special = phdr->pd_special;
715-
itemIdSort itemidbase,
716-
itemidptr;
713+
itemIdSortData itemidbase[MaxIndexTuplesPerPage];
714+
itemIdSort itemidptr;
717715
ItemId lp;
718716
int nline,
719717
nused;
@@ -725,6 +723,8 @@ PageIndexMultiDelete(Page page, OffsetNumber *itemnos, int nitems)
725723
int nextitm;
726724
OffsetNumber offnum;
727725

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

826825
phdr->pd_lower = SizeOfPageHeaderData + nused * sizeof(ItemIdData);
827826
phdr->pd_upper = upper;
828-
829-
pfree(itemidbase);
830827
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy