aboutsummaryrefslogtreecommitdiff
path: root/src/include/access/gist_private.h
diff options
context:
space:
mode:
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>2014-04-03 15:09:37 +0300
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>2014-04-03 15:44:09 +0300
commit003a31a7c9fabed9b247ccd4c4123da017fddf58 (patch)
tree372a62ef7c17a948d2c477d845b60e43b4bcc2b4 /src/include/access/gist_private.h
parent029decfec6befe3bba14918590af5c998402ff08 (diff)
downloadpostgresql-003a31a7c9fabed9b247ccd4c4123da017fddf58.tar.gz
postgresql-003a31a7c9fabed9b247ccd4c4123da017fddf58.zip
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.
Diffstat (limited to 'src/include/access/gist_private.h')
-rw-r--r--src/include/access/gist_private.h15
1 files changed, 15 insertions, 0 deletions
diff --git a/src/include/access/gist_private.h b/src/include/access/gist_private.h
index d9b1fa2fec5..53f794f3b9e 100644
--- a/src/include/access/gist_private.h
+++ b/src/include/access/gist_private.h
@@ -22,6 +22,21 @@
#include "utils/rbtree.h"
#include "utils/hsearch.h"
+/*
+ * Maximum number of "halves" a page can be split into in one operation.
+ * Typically a split produces 2 halves, but can be more if keys have very
+ * different lengths, or when inserting multiple keys in one operation (as
+ * when inserting downlinks to an internal node). There is no theoretical
+ * limit on this, but in practice if you get more than a handful page halves
+ * in one split, there's something wrong with the opclass implementation.
+ * GIST_MAX_SPLIT_PAGES is an arbitrary limit on that, used to size some
+ * local arrays used during split. Note that there is also a limit on the
+ * number of buffers that can be held locked at a time, MAX_SIMUL_LWLOCKS,
+ * so if you raise this higher than that limit, you'll just get a different
+ * error.
+ */
+#define GIST_MAX_SPLIT_PAGES 75
+
/* Buffer lock modes */
#define GIST_SHARE BUFFER_LOCK_SHARE
#define GIST_EXCLUSIVE BUFFER_LOCK_EXCLUSIVE