From 557c21a0255144af3deff45caf61b8aac7cb2c51 Mon Sep 17 00:00:00 2001
From: Julien Tachoires <julmon@gmail.com>
Date: Sun, 23 Jun 2024 08:22:10 -0700
Subject: [PATCH 2/7] Add GUC logical_decoding_spill_compression

This new GUC defines the compression method used to compress
decoded changes spilled on disk during logical decoding.

Default value is 'off', meaning no compression involved.
---
 doc/src/sgml/config.sgml                      | 25 +++++++++++++++++++
 .../replication/logical/reorderbuffer.c       |  4 ---
 src/backend/utils/misc/guc_tables.c           | 22 ++++++++++++++++
 src/backend/utils/misc/postgresql.conf.sample |  1 +
 .../replication/reorderbuffer_compression.h   |  3 +++
 5 files changed, 51 insertions(+), 4 deletions(-)

diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index b14c5d81a1..955f4f4a8b 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -2002,6 +2002,31 @@ include_dir 'conf.d'
       </listitem>
      </varlistentry>
 
+     <varlistentry id="guc-logical-decoding-spill-files-compression" xreflabel="logical_decoding_spill_compression">
+      <term><varname>logical_decoding_spill_compression</varname> (<type>enum</type>)
+      <indexterm>
+       <primary><varname>logical_decoding_spill_compression</varname> configuration parameter</primary>
+      </indexterm>
+      </term>
+      <listitem>
+       <para>
+        This parameter enables compression of decoded changes written to local
+        disk by logical decoding when the transaction size does not fit in
+        <xref linkend="guc-logical-decoding-work-mem"/>.
+        When the subscribtion is created with the option <varname>streaming</varname>
+        set to <varname>on</varname> or <varname>parallel</varname>, then
+        the transaction are not fully decoded on the publisher, then, this
+        parameter has not effect if there is no data to spill on disk.
+        The supported methods are <literal>lz4</literal> (if
+        <productname>PostgreSQL</productname> was compiled with
+        <option>--with-lz4</option>) and <literal>off></literal>.
+        The default value is <literal>off</literal>.
+        Only superusers and users with the appropriate <literal>SET</literal>
+        privilege can change this setting.
+       </para>
+      </listitem>
+     </varlistentry>
+
      <varlistentry id="guc-commit-timestamp-buffers" xreflabel="commit_timestamp_buffers">
       <term><varname>commit_timestamp_buffers</varname> (<type>integer</type>)
       <indexterm>
diff --git a/src/backend/replication/logical/reorderbuffer.c b/src/backend/replication/logical/reorderbuffer.c
index 4e08167d03..ef2cd8bdf3 100644
--- a/src/backend/replication/logical/reorderbuffer.c
+++ b/src/backend/replication/logical/reorderbuffer.c
@@ -114,11 +114,7 @@
 #include "utils/relfilenumbermap.h"
 
 /* GUC */
-#ifdef USE_LZ4
-int			logical_decoding_spill_compression = REORDER_BUFFER_LZ4_COMPRESSION;
-#else
 int			logical_decoding_spill_compression = REORDER_BUFFER_NO_COMPRESSION;
-#endif
 
 /* entry for a hash table we use to map from xid to our transaction state */
 typedef struct ReorderBufferTXNByIdEnt
diff --git a/src/backend/utils/misc/guc_tables.c b/src/backend/utils/misc/guc_tables.c
index 630ed0f162..27ce376fd4 100644
--- a/src/backend/utils/misc/guc_tables.c
+++ b/src/backend/utils/misc/guc_tables.c
@@ -67,6 +67,7 @@
 #include "postmaster/walsummarizer.h"
 #include "postmaster/walwriter.h"
 #include "replication/logicallauncher.h"
+#include "replication/reorderbuffer_compression.h"
 #include "replication/slot.h"
 #include "replication/slotsync.h"
 #include "replication/syncrep.h"
@@ -484,6 +485,17 @@ static const struct config_enum_entry wal_compression_options[] = {
 	{NULL, 0, false}
 };
 
+static const struct config_enum_entry logical_decoding_spill_compression_options[] = {
+#ifdef  USE_LZ4
+	{"lz4", REORDER_BUFFER_LZ4_COMPRESSION, false},
+#endif
+	{"off", REORDER_BUFFER_NO_COMPRESSION, false},
+	{"false", REORDER_BUFFER_NO_COMPRESSION, true},
+	{"no", REORDER_BUFFER_NO_COMPRESSION, true},
+	{"0", REORDER_BUFFER_NO_COMPRESSION, true},
+	{NULL, 0, false}
+};
+
 /*
  * Options for enum values stored in other modules
  */
@@ -5120,6 +5132,16 @@ struct config_enum ConfigureNamesEnum[] =
 		NULL, NULL, NULL
 	},
 
+	{
+		{"logical_decoding_spill_compression", PGC_SUSET, RESOURCES_DISK,
+			gettext_noop("Compresses logical decoding spill files."),
+			NULL
+		},
+		&logical_decoding_spill_compression,
+		REORDER_BUFFER_NO_COMPRESSION, logical_decoding_spill_compression_options,
+		NULL, NULL, NULL
+	},
+
 	/* End-of-list marker */
 	{
 		{NULL, 0, 0, NULL, NULL}, NULL, 0, NULL, NULL, NULL, NULL
diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample
index 9ec9f97e92..a3a35c4ad8 100644
--- a/src/backend/utils/misc/postgresql.conf.sample
+++ b/src/backend/utils/misc/postgresql.conf.sample
@@ -335,6 +335,7 @@
 #wal_sender_timeout = 60s	# in milliseconds; 0 disables
 #track_commit_timestamp = off	# collect timestamp of transaction commit
 				# (change requires restart)
+#logical_decoding_spill_compression = off	# Compress decoded changes spilled on disk
 
 # - Primary Server -
 
diff --git a/src/include/replication/reorderbuffer_compression.h b/src/include/replication/reorderbuffer_compression.h
index 9aa8aea56f..d59e9543a8 100644
--- a/src/include/replication/reorderbuffer_compression.h
+++ b/src/include/replication/reorderbuffer_compression.h
@@ -19,6 +19,9 @@
 #include <lz4.h>
 #endif
 
+/* GUC support */
+extern PGDLLIMPORT int logical_decoding_spill_compression;
+
 /* ReorderBuffer on disk compression algorithms */
 typedef enum ReorderBufferCompressionMethod
 {
-- 
2.43.0

