Skip to content

Commit af7004e

Browse files
committed
Avoid allocations in critical sections.
If a palloc in a critical section fails, it becomes a PANIC.
1 parent 0de9963 commit af7004e

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
@@ -1828,8 +1828,10 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf)
18281828
BTPageOpaque rootopaque;
18291829
ItemId itemid;
18301830
IndexTuple item;
1831-
Size itemsz;
1832-
IndexTuple new_item;
1831+
IndexTuple left_item;
1832+
Size left_item_sz;
1833+
IndexTuple right_item;
1834+
Size right_item_sz;
18331835
Buffer metabuf;
18341836
Page metapg;
18351837
BTMetaPageData *metad;
@@ -1848,6 +1850,26 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf)
18481850
metapg = BufferGetPage(metabuf);
18491851
metad = BTPageGetMeta(metapg);
18501852

1853+
/*
1854+
* Create downlink item for left page (old root). Since this will be the
1855+
* first item in a non-leaf page, it implicitly has minus-infinity key
1856+
* value, so we need not store any actual key in it.
1857+
*/
1858+
left_item_sz = sizeof(IndexTupleData);
1859+
left_item = (IndexTuple) palloc(left_item_sz);
1860+
left_item->t_info = left_item_sz;
1861+
ItemPointerSet(&(left_item->t_tid), lbkno, P_HIKEY);
1862+
1863+
/*
1864+
* Create downlink item for right page. The key for it is obtained from
1865+
* the "high key" position in the left page.
1866+
*/
1867+
itemid = PageGetItemId(lpage, P_HIKEY);
1868+
right_item_sz = ItemIdGetLength(itemid);
1869+
item = (IndexTuple) PageGetItem(lpage, itemid);
1870+
right_item = CopyIndexTuple(item);
1871+
ItemPointerSet(&(right_item->t_tid), rbkno, P_HIKEY);
1872+
18511873
/* NO EREPORT(ERROR) from here till newroot op is logged */
18521874
START_CRIT_SECTION();
18531875

@@ -1865,16 +1887,6 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf)
18651887
metad->btm_fastroot = rootblknum;
18661888
metad->btm_fastlevel = rootopaque->btpo.level;
18671889

1868-
/*
1869-
* Create downlink item for left page (old root). Since this will be the
1870-
* first item in a non-leaf page, it implicitly has minus-infinity key
1871-
* value, so we need not store any actual key in it.
1872-
*/
1873-
itemsz = sizeof(IndexTupleData);
1874-
new_item = (IndexTuple) palloc(itemsz);
1875-
new_item->t_info = itemsz;
1876-
ItemPointerSet(&(new_item->t_tid), lbkno, P_HIKEY);
1877-
18781890
/*
18791891
* Insert the left page pointer into the new root page. The root page is
18801892
* the rightmost page on its level so there is no "high key" in it; the
@@ -1883,32 +1895,20 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf)
18831895
* Note: we *must* insert the two items in item-number order, for the
18841896
* benefit of _bt_restore_page().
18851897
*/
1886-
if (PageAddItem(rootpage, (Item) new_item, itemsz, P_HIKEY,
1898+
if (PageAddItem(rootpage, (Item) left_item, left_item_sz, P_HIKEY,
18871899
false, false) == InvalidOffsetNumber)
18881900
elog(PANIC, "failed to add leftkey to new root page"
18891901
" while splitting block %u of index \"%s\"",
18901902
BufferGetBlockNumber(lbuf), RelationGetRelationName(rel));
1891-
pfree(new_item);
1892-
1893-
/*
1894-
* Create downlink item for right page. The key for it is obtained from
1895-
* the "high key" position in the left page.
1896-
*/
1897-
itemid = PageGetItemId(lpage, P_HIKEY);
1898-
itemsz = ItemIdGetLength(itemid);
1899-
item = (IndexTuple) PageGetItem(lpage, itemid);
1900-
new_item = CopyIndexTuple(item);
1901-
ItemPointerSet(&(new_item->t_tid), rbkno, P_HIKEY);
19021903

19031904
/*
19041905
* insert the right page pointer into the new root page.
19051906
*/
1906-
if (PageAddItem(rootpage, (Item) new_item, itemsz, P_FIRSTKEY,
1907+
if (PageAddItem(rootpage, (Item) right_item, right_item_sz, P_FIRSTKEY,
19071908
false, false) == InvalidOffsetNumber)
19081909
elog(PANIC, "failed to add rightkey to new root page"
19091910
" while splitting block %u of index \"%s\"",
19101911
BufferGetBlockNumber(lbuf), RelationGetRelationName(rel));
1911-
pfree(new_item);
19121912

19131913
MarkBufferDirty(rootbuf);
19141914
MarkBufferDirty(metabuf);
@@ -1956,6 +1956,9 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf)
19561956
/* done with metapage */
19571957
_bt_relbuf(rel, metabuf);
19581958

1959+
pfree(left_item);
1960+
pfree(right_item);
1961+
19591962
return rootbuf;
19601963
}
19611964

src/backend/access/transam/xlog.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2289,6 +2289,7 @@ XLogFileInit(uint32 log, uint32 seg,
22892289
{
22902290
char path[MAXPGPATH];
22912291
char tmppath[MAXPGPATH];
2292+
char zbuffer_raw[BLCKSZ + MAXIMUM_ALIGNOF];
22922293
char *zbuffer;
22932294
uint32 installed_log;
22942295
uint32 installed_seg;
@@ -2346,11 +2347,11 @@ XLogFileInit(uint32 log, uint32 seg,
23462347
* fdatasync(2) or O_DSYNC will be sufficient to sync future writes to the
23472348
* log file.
23482349
*
2349-
* Note: palloc zbuffer, instead of just using a local char array, to
2350-
* ensure it is reasonably well-aligned; this may save a few cycles
2351-
* transferring data to the kernel.
2350+
* Note: ensure the buffer is reasonably well-aligned; this may save a few
2351+
* cycles transferring data to the kernel.
23522352
*/
2353-
zbuffer = (char *) palloc0(XLOG_BLCKSZ);
2353+
zbuffer = (char *) MAXALIGN(zbuffer_raw);
2354+
memset(zbuffer, 0, BLCKSZ);
23542355
for (nbytes = 0; nbytes < XLogSegSize; nbytes += XLOG_BLCKSZ)
23552356
{
23562357
errno = 0;
@@ -2370,7 +2371,6 @@ XLogFileInit(uint32 log, uint32 seg,
23702371
errmsg("could not write to file \"%s\": %m", tmppath)));
23712372
}
23722373
}
2373-
pfree(zbuffer);
23742374

23752375
if (pg_fsync(fd) != 0)
23762376
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