]> granicus.if.org Git - postgresql/commitdiff
Fix oversight in sizing of shared buffer lookup hashtable. Because
authorTom Lane <tgl@sss.pgh.pa.us>
Sun, 23 Jul 2006 18:34:45 +0000 (18:34 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Sun, 23 Jul 2006 18:34:45 +0000 (18:34 +0000)
BufferAlloc tries to insert a new mapping entry before deleting the old one
for a buffer, we have a transient need for more than NBuffers entries ---
one more in 8.1, and as many as NUM_BUFFER_PARTITIONS more in CVS HEAD.
In theory this could lead to an "out of shared memory" failure if shmem
had already been completely claimed by the time the extra entries were
needed.

src/backend/storage/buffer/freelist.c

index 7db8b766aaa5257cfe9dafe20ea12536360f7750..333053c1c93f360c8bcbca46fd1131864aae9177 100644 (file)
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/storage/buffer/freelist.c,v 1.55 2006/03/05 15:58:36 momjian Exp $
+ *       $PostgreSQL: pgsql/src/backend/storage/buffer/freelist.c,v 1.56 2006/07/23 18:34:45 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -213,8 +213,8 @@ StrategyShmemSize(void)
 {
        Size            size = 0;
 
-       /* size of lookup hash table */
-       size = add_size(size, BufTableShmemSize(NBuffers));
+       /* size of lookup hash table ... see comment in StrategyInitialize */
+       size = add_size(size, BufTableShmemSize(NBuffers + NUM_BUFFER_PARTITIONS));
 
        /* size of the shared replacement strategy control block */
        size = add_size(size, MAXALIGN(sizeof(BufferStrategyControl)));
@@ -236,8 +236,15 @@ StrategyInitialize(bool init)
 
        /*
         * Initialize the shared buffer lookup hashtable.
+        *
+        * Since we can't tolerate running out of lookup table entries, we
+        * must be sure to specify an adequate table size here.  The maximum
+        * steady-state usage is of course NBuffers entries, but BufferAlloc()
+        * tries to insert a new entry before deleting the old.  In principle
+        * this could be happening in each partition concurrently, so we
+        * could need as many as NBuffers + NUM_BUFFER_PARTITIONS entries.
         */
-       InitBufTable(NBuffers);
+       InitBufTable(NBuffers + NUM_BUFFER_PARTITIONS);
 
        /*
         * Get or create the shared strategy control block