v30-0008-Remove-the-max-memory-deduction-from-TidStore.patch

application/octet-stream

Filename: v30-0008-Remove-the-max-memory-deduction-from-TidStore.patch
Type: application/octet-stream
Part: 0
Message: Re: [PoC] Improve dead tuple storage for lazy vacuum

Patch

Format: format-patch
Series: patch v30-0008
Subject: Remove the max memory deduction from TidStore.
File+
src/backend/access/common/tidstore.c 10 33
From 5e3e7098eb12ec1d7ee546cc8f6e635638f131be Mon Sep 17 00:00:00 2001
From: Masahiko Sawada <sawada.mshk@gmail.com>
Date: Wed, 8 Mar 2023 15:08:58 +0900
Subject: [PATCH v30 08/11] Remove the max memory deduction from TidStore.

---
 src/backend/access/common/tidstore.c | 43 +++++++---------------------
 1 file changed, 10 insertions(+), 33 deletions(-)

diff --git a/src/backend/access/common/tidstore.c b/src/backend/access/common/tidstore.c
index 2d6f2b3ab9..54e2ef29db 100644
--- a/src/backend/access/common/tidstore.c
+++ b/src/backend/access/common/tidstore.c
@@ -82,6 +82,7 @@ typedef uint64 offsetbm;
 #define RT_SCOPE static
 #define RT_DECLARE
 #define RT_DEFINE
+#define RT_MEASURE_MEMORY_USAGE
 #define RT_VALUE_TYPE tidkey
 #include "lib/radixtree.h"
 
@@ -90,6 +91,7 @@ typedef uint64 offsetbm;
 #define RT_SCOPE static
 #define RT_DECLARE
 #define RT_DEFINE
+#define RT_MEASURE_MEMORY_USAGE
 #define RT_VALUE_TYPE tidkey
 #include "lib/radixtree.h"
 
@@ -182,39 +184,15 @@ TidStoreCreate(size_t max_bytes, OffsetNumber max_off, dsa_area *area)
 
 	ts = palloc0(sizeof(TidStore));
 
-	/*
-	 * Create the radix tree for the main storage.
-	 *
-	 * Memory consumption depends on the number of stored tids, but also on the
-	 * distribution of them, how the radix tree stores, and the memory management
-	 * that backed the radix tree. The maximum bytes that a TidStore can
-	 * use is specified by the max_bytes in TidStoreCreate(). We want the total
-	 * amount of memory consumption by a TidStore not to exceed the max_bytes.
-	 *
-	 * In local TidStore cases, the radix tree uses slab allocators for each kind
-	 * of node class. The most memory consuming case while adding Tids associated
-	 * with one page (i.e. during TidStoreSetBlockOffsets()) is that we allocate a new
-	 * slab block for a new radix tree node, which is approximately 70kB. Therefore,
-	 * we deduct 70kB from the max_bytes.
-	 *
-	 * In shared cases, DSA allocates the memory segments big enough to follow
-	 * a geometric series that approximately doubles the total DSA size (see
-	 * make_new_segment() in dsa.c). We simulated the how DSA increases segment
-	 * size and the simulation revealed, the 75% threshold for the maximum bytes
-	 * perfectly works in case where the max_bytes is a power-of-2, and the 60%
-	 * threshold works for other cases.
-	 */
 	if (area != NULL)
 	{
 		dsa_pointer dp;
-		float ratio = ((max_bytes & (max_bytes - 1)) == 0) ? 0.75 : 0.6;
 
 		ts->tree.shared = shared_rt_create(CurrentMemoryContext, area,
 										   LWTRANCHE_SHARED_TIDSTORE);
 
 		dp = dsa_allocate0(area, sizeof(TidStoreControl));
 		ts->control = (TidStoreControl *) dsa_get_address(area, dp);
-		ts->control->max_bytes = (size_t) (max_bytes * ratio);
 		ts->area = area;
 
 		ts->control->magic = TIDSTORE_MAGIC;
@@ -225,11 +203,15 @@ TidStoreCreate(size_t max_bytes, OffsetNumber max_off, dsa_area *area)
 	else
 	{
 		ts->tree.local = local_rt_create(CurrentMemoryContext);
-
 		ts->control = (TidStoreControl *) palloc0(sizeof(TidStoreControl));
-		ts->control->max_bytes = max_bytes - (70 * 1024);
 	}
 
+	/*
+	 * max_bytes is forced to be at least 64KB, the current minimum valid value
+	 * for the work_mem GUC.
+	 */
+	ts->control->max_bytes = Max(64 * 1024L, max_bytes);
+
 	ts->control->max_off = max_off;
 	ts->control->max_off_nbits = pg_ceil_log2_32(max_off);
 
@@ -333,14 +315,8 @@ TidStoreReset(TidStore *ts)
 
 		LWLockAcquire(&ts->control->lock, LW_EXCLUSIVE);
 
-		/*
-		 * Free the radix tree and return allocated DSA segments to
-		 * the operating system.
-		 */
-		shared_rt_free(ts->tree.shared);
-		dsa_trim(ts->area);
-
 		/* Recreate the radix tree */
+		shared_rt_free(ts->tree.shared);
 		ts->tree.shared = shared_rt_create(CurrentMemoryContext, ts->area,
 										   LWTRANCHE_SHARED_TIDSTORE);
 
@@ -354,6 +330,7 @@ TidStoreReset(TidStore *ts)
 	}
 	else
 	{
+		/* Recreate the radix tree */
 		local_rt_free(ts->tree.local);
 		ts->tree.local = local_rt_create(CurrentMemoryContext);
 
-- 
2.31.1