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)
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