From 2d81ea5a66791da38d9880e6424fd0a50eb22476 Mon Sep 17 00:00:00 2001
From: Andrey Borodin <amborodin@acm.org>
Date: Tue, 6 Oct 2026 11:27:54 +0500
Subject: [PATCH v10 2/2] Reuse the zstd context when compressing WAL images

Compressing each full-page image currently creates and destroys a zstd
compression context.  Keep a backend-local context, allocated on first
use, to avoid repeating those allocations.

Report an error if the context cannot be allocated.  Compression failures
continue to fall back to storing the image uncompressed.

Author: Andrey Borodin <amborodin@acm.org>
Reviewed-by: Michael Paquier <michael@paquier.xyz>
Reviewed-by: Anthonin Bonnefoy <anthonin.bonnefoy@datadoghq.com>
Discussion: https://www.postgresql.org/message-id/asRsOl73nf8GeBFd@paquier.xyz
---
 src/backend/access/transam/xloginsert.c | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/src/backend/access/transam/xloginsert.c b/src/backend/access/transam/xloginsert.c
index c9aff944a2e..15b4ac9cda3 100644
--- a/src/backend/access/transam/xloginsert.c
+++ b/src/backend/access/transam/xloginsert.c
@@ -116,6 +116,11 @@ static uint8 curinsert_flags = 0;
 static XLogRecData hdr_rdt;
 static char *hdr_scratch = NULL;
 
+#ifdef USE_ZSTD
+/* Reuse the compression context for the lifetime of the backend. */
+static ZSTD_CCtx *zstd_cctx = NULL;
+#endif
+
 #define SizeOfXlogOrigin	(sizeof(ReplOriginId) + sizeof(char))
 #define SizeOfXLogTransactionId	(sizeof(TransactionId) + sizeof(char))
 
@@ -1063,8 +1068,17 @@ XLogCompressBackupBlock(const PageData *page, uint16 hole_offset, uint16 hole_le
 
 		case WAL_COMPRESSION_ZSTD:
 #ifdef USE_ZSTD
-			len = ZSTD_compress(dest, COMPRESS_BUFSIZE, source, orig_len,
-								ZSTD_CLEVEL_DEFAULT);
+			if (zstd_cctx == NULL)
+			{
+				zstd_cctx = ZSTD_createCCtx();
+				if (zstd_cctx == NULL)
+					ereport(ERROR,
+							(errcode(ERRCODE_OUT_OF_MEMORY),
+							 errmsg("could not create zstd compression context")));
+			}
+
+			len = ZSTD_compressCCtx(zstd_cctx, dest, COMPRESS_BUFSIZE,
+									source, orig_len, ZSTD_CLEVEL_DEFAULT);
 			if (ZSTD_isError(len))
 				len = -1;		/* failure */
 #else
-- 
That's all, folks. May the source be with you.

