1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-30 21:42:05 +03:00

Avoid palloc in critical section in GiST WAL-logging.

Memory allocation can fail if you run out of memory, and inside a critical
section that will lead to a PANIC. Use conservatively-sized arrays in stack
instead.

There was previously no explicit limit on the number of pages a GiST split
can produce, it was only limited by the number of LWLocks that can be held
simultaneously (100 at the moment). This patch adds an explicit limit of 75
pages. That should be plenty, a typical split shouldn't produce more than
2-3 page halves.

The bug has been there forever, but only backpatch down to 9.1. The code
was changed significantly in 9.1, and it doesn't seem worth the risk or
trouble to adapt this for 9.0 and 8.4.
This commit is contained in:
Heikki Linnakangas
2014-04-03 15:09:37 +03:00
parent 029decfec6
commit 003a31a7c9
4 changed files with 38 additions and 9 deletions

View File

@ -206,6 +206,7 @@ gistplacetopage(Relation rel, Size freespace, GISTSTATE *giststate,
GistNSN oldnsn = {0, 0};
SplitedPageLayout rootpg;
bool is_rootsplit;
int npage;
is_rootsplit = (blkno == GIST_ROOT_BLKNO);
@ -226,6 +227,19 @@ gistplacetopage(Relation rel, Size freespace, GISTSTATE *giststate,
itvec = gistjoinvector(itvec, &tlen, itup, ntup);
dist = gistSplit(rel, page, itvec, tlen, giststate);
/*
* Check that split didn't produce too many pages.
*/
npage = 0;
for (ptr = dist; ptr; ptr = ptr->next)
npage++;
/* in a root split, we'll add one more page to the list below */
if (is_rootsplit)
npage++;
if (npage > GIST_MAX_SPLIT_PAGES)
elog(ERROR, "GiST page split into too many halves (%d, maximum %d)",
npage, GIST_MAX_SPLIT_PAGES);
/*
* Set up pages to work with. Allocate new buffers for all but the
* leftmost page. The original page becomes the new leftmost page, and