From ee71da72c469ca7a4910a90c953deee5b0fd36ae Mon Sep 17 00:00:00 2001 From: Sehrope Sarkuni Date: Tue, 28 Jul 2026 15:24:13 +0000 Subject: [PATCH] Enlarge the syslogger pipe with F_SETPIPE_SZ Backends block in write() once the syslogger pipe is full, so its capacity bounds how far they can run ahead of the collector during a burst. The kernel default of 64 kB holds only sixteen maximum-size chunks, which a handful of backends emitting multi-chunk messages can exhaust immediately. Ask for 1 MB when the pipe is created. The request is capped by a system limit and can fail, so retry with smaller sizes, stopping at the capacity the kernel already gave the pipe to avoid shrinking it. This is best effort. If F_GETPIPE_SZ or F_SETPIPE_SZ is unavailable, or no request is accepted, the kernel default stands and behavior is unchanged. There is one such pipe per cluster, so the extra kernel memory is bounded by that single buffer. --- src/backend/postmaster/syslogger.c | 31 ++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/backend/postmaster/syslogger.c b/src/backend/postmaster/syslogger.c index b4b599c4c69..f0d07a9d293 100644 --- a/src/backend/postmaster/syslogger.c +++ b/src/backend/postmaster/syslogger.c @@ -60,6 +60,15 @@ */ #define READ_BUF_SIZE (2 * PIPE_CHUNK_SIZE) +/* + * Capacity we ask the kernel for on the syslogger pipe. Writers block once + * the pipe is full, so its capacity is what lets them run ahead of the + * syslogger across a burst. The request is subject to a system limit and can + * fail, hence the retry with smaller values, stopping before we would shrink + * the pipe below the capacity the kernel already gave it. + */ +#define SYSLOGGER_PIPE_SIZE (1024 * 1024) + /* Log rotation signal file path, relative to $PGDATA */ #define LOGROTATE_SIGNAL_FILE "logrotate" @@ -643,6 +652,28 @@ SysLogger_Start(int child_slot) ereport(FATAL, (errcode_for_socket_access(), errmsg("could not create pipe for syslog: %m"))); + +#if defined(F_GETPIPE_SZ) && defined(F_SETPIPE_SZ) + /* + * Best effort only. Increase the pipe capacity where allowed, but + * never reduce the capacity selected by the kernel. + */ + { + int current_size; + + current_size = fcntl(syslogPipe[0], F_GETPIPE_SZ); + if (current_size > 0) + { + for (int size = SYSLOGGER_PIPE_SIZE; + size > current_size; + size /= 2) + { + if (fcntl(syslogPipe[0], F_SETPIPE_SZ, size) >= 0) + break; + } + } + } +#endif } #else if (!syslogPipe[0]) -- 2.55.0