]> granicus.if.org Git - postgresql/commitdiff
Fix the overrun in hash index metapage for smaller block sizes.
authorAmit Kapila <akapila@postgresql.org>
Thu, 6 Sep 2018 03:57:19 +0000 (09:27 +0530)
committerAmit Kapila <akapila@postgresql.org>
Thu, 6 Sep 2018 03:57:19 +0000 (09:27 +0530)
The commit 620b49a1 changed the value of HASH_MAX_BITMAPS with the intent
to allow many non-unique values in hash indexes without worrying to reach
the limit of the number of overflow pages.  At that time, this didn't
occur to us that it can overrun the block for smaller block sizes.

Choose the value of HASH_MAX_BITMAPS based on BLCKSZ such that it gives
the same answer as now for the cases where the overrun doesn't occur, and
some other sufficiently-value for the cases where an overrun currently
does occur.  This allows us not to change the behavior in any case that
currently works, so there's really no reason for a HASH_VERSION bump.

Author: Dilip Kumar
Reviewed-by: Amit Kapila
Backpatch-through: 10
Discussion: https://postgr.es/m/CAA4eK1LtF4VmU4mx_+i72ff1MdNZ8XaJMGkt2HV8+uSWcn8t4A@mail.gmail.com

src/include/access/hash.h

index 543d802949196d98b7f4be26a4536c28e77c22ab..02ef67c974b44a352c09e909d601c56fdcdbcd82 100644 (file)
@@ -230,9 +230,12 @@ typedef HashScanOpaqueData *HashScanOpaque;
  *
  * There is no particular upper limit on the size of mapp[], other than
  * needing to fit into the metapage.  (With 8K block size, 1024 bitmaps
- * limit us to 256 GB of overflow space...)
+ * limit us to 256 GB of overflow space...).  For smaller block size we
+ * can not use 1024 bitmaps as it will lead to the meta page data crossing
+ * the block size boundary.  So we use BLCKSZ to determine the maximum number
+ * of bitmaps.
  */
-#define HASH_MAX_BITMAPS                       1024
+#define HASH_MAX_BITMAPS                       Min(BLCKSZ / 8, 1024)
 
 #define HASH_SPLITPOINT_PHASE_BITS     2
 #define HASH_SPLITPOINT_PHASES_PER_GRP (1 << HASH_SPLITPOINT_PHASE_BITS)