Skip to content

Commit 129b8ad

Browse files
committed
Avoid allocations in critical sections.
If a palloc in a critical section fails, it becomes a PANIC.
1 parent 98b1dda commit 129b8ad

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
@@ -1726,8 +1726,10 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf)
17261726
BTPageOpaque rootopaque;
17271727
ItemId itemid;
17281728
IndexTuple item;
1729-
Size itemsz;
1730-
IndexTuple new_item;
1729+
IndexTuple left_item;
1730+
Size left_item_sz;
1731+
IndexTuple right_item;
1732+
Size right_item_sz;
17311733
Buffer metabuf;
17321734
Page metapg;
17331735
BTMetaPageData *metad;
@@ -1746,6 +1748,26 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf)
17461748
metapg = BufferGetPage(metabuf);
17471749
metad = BTPageGetMeta(metapg);
17481750

1751+
/*
1752+
* Create downlink item for left page (old root). Since this will be the
1753+
* first item in a non-leaf page, it implicitly has minus-infinity key
1754+
* value, so we need not store any actual key in it.
1755+
*/
1756+
left_item_sz = sizeof(IndexTupleData);
1757+
left_item = (IndexTuple) palloc(left_item_sz);
1758+
left_item->t_info = left_item_sz;
1759+
ItemPointerSet(&(left_item->t_tid), lbkno, P_HIKEY);
1760+
1761+
/*
1762+
* Create downlink item for right page. The key for it is obtained from
1763+
* the "high key" position in the left page.
1764+
*/
1765+
itemid = PageGetItemId(lpage, P_HIKEY);
1766+
right_item_sz = ItemIdGetLength(itemid);
1767+
item = (IndexTuple) PageGetItem(lpage, itemid);
1768+
right_item = CopyIndexTuple(item);
1769+
ItemPointerSet(&(right_item->t_tid), rbkno, P_HIKEY);
1770+
17491771
/* NO EREPORT(ERROR) from here till newroot op is logged */
17501772
START_CRIT_SECTION();
17511773

@@ -1763,16 +1785,6 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf)
17631785
metad->btm_fastroot = rootblknum;
17641786
metad->btm_fastlevel = rootopaque->btpo.level;
17651787

1766-
/*
1767-
* Create downlink item for left page (old root). Since this will be the
1768-
* first item in a non-leaf page, it implicitly has minus-infinity key
1769-
* value, so we need not store any actual key in it.
1770-
*/
1771-
itemsz = sizeof(IndexTupleData);
1772-
new_item = (IndexTuple) palloc(itemsz);
1773-
new_item->t_info = itemsz;
1774-
ItemPointerSet(&(new_item->t_tid), lbkno, P_HIKEY);
1775-
17761788
/*
17771789
* Insert the left page pointer into the new root page. The root page is
17781790
* the rightmost page on its level so there is no "high key" in it; the
@@ -1781,32 +1793,20 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf)
17811793
* Note: we *must* insert the two items in item-number order, for the
17821794
* benefit of _bt_restore_page().
17831795
*/
1784-
if (PageAddItem(rootpage, (Item) new_item, itemsz, P_HIKEY,
1796+
if (PageAddItem(rootpage, (Item) left_item, left_item_sz, P_HIKEY,
17851797
false, false) == InvalidOffsetNumber)
17861798
elog(PANIC, "failed to add leftkey to new root page"
17871799
" while splitting block %u of index \"%s\"",
17881800
BufferGetBlockNumber(lbuf), RelationGetRelationName(rel));
1789-
pfree(new_item);
1790-
1791-
/*
1792-
* Create downlink item for right page. The key for it is obtained from
1793-
* the "high key" position in the left page.
1794-
*/
1795-
itemid = PageGetItemId(lpage, P_HIKEY);
1796-
itemsz = ItemIdGetLength(itemid);
1797-
item = (IndexTuple) PageGetItem(lpage, itemid);
1798-
new_item = CopyIndexTuple(item);
1799-
ItemPointerSet(&(new_item->t_tid), rbkno, P_HIKEY);
18001801

18011802
/*
18021803
* insert the right page pointer into the new root page.
18031804
*/
1804-
if (PageAddItem(rootpage, (Item) new_item, itemsz, P_FIRSTKEY,
1805+
if (PageAddItem(rootpage, (Item) right_item, right_item_sz, P_FIRSTKEY,
18051806
false, false) == InvalidOffsetNumber)
18061807
elog(PANIC, "failed to add rightkey to new root page"
18071808
" while splitting block %u of index \"%s\"",
18081809
BufferGetBlockNumber(lbuf), RelationGetRelationName(rel));
1809-
pfree(new_item);
18101810

18111811
MarkBufferDirty(rootbuf);
18121812
MarkBufferDirty(metabuf);
@@ -1854,6 +1854,9 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf)
18541854
/* done with metapage */
18551855
_bt_relbuf(rel, metabuf);
18561856

1857+
pfree(left_item);
1858+
pfree(right_item);
1859+
18571860
return rootbuf;
18581861
}
18591862

src/backend/access/transam/xlog.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2167,6 +2167,7 @@ XLogFileInit(uint32 log, uint32 seg,
21672167
{
21682168
char path[MAXPGPATH];
21692169
char tmppath[MAXPGPATH];
2170+
char zbuffer_raw[BLCKSZ + MAXIMUM_ALIGNOF];
21702171
char *zbuffer;
21712172
uint32 installed_log;
21722173
uint32 installed_seg;
@@ -2224,11 +2225,11 @@ XLogFileInit(uint32 log, uint32 seg,
22242225
* fdatasync(2) or O_DSYNC will be sufficient to sync future writes to the
22252226
* log file.
22262227
*
2227-
* Note: palloc zbuffer, instead of just using a local char array, to
2228-
* ensure it is reasonably well-aligned; this may save a few cycles
2229-
* transferring data to the kernel.
2228+
* Note: ensure the buffer is reasonably well-aligned; this may save a few
2229+
* cycles transferring data to the kernel.
22302230
*/
2231-
zbuffer = (char *) palloc0(XLOG_BLCKSZ);
2231+
zbuffer = (char *) MAXALIGN(zbuffer_raw);
2232+
memset(zbuffer, 0, BLCKSZ);
22322233
for (nbytes = 0; nbytes < XLogSegSize; nbytes += XLOG_BLCKSZ)
22332234
{
22342235
errno = 0;
@@ -2248,7 +2249,6 @@ XLogFileInit(uint32 log, uint32 seg,
22482249
errmsg("could not write to file \"%s\": %m", tmppath)));
22492250
}
22502251
}
2251-
pfree(zbuffer);
22522252

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