From 3e0ae46d907dd5f36342dd288841f4502bd571f6 Mon Sep 17 00:00:00 2001 From: Heikki Linnakangas Date: Mon, 10 Nov 2025 16:11:41 +0200 Subject: [PATCH] Move SLRU_PAGES_PER_SEGMENT to pg_config_manual.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It seems plausible that someone might want to experiment with different values. The pressing reason though is that I'm reviewing a patch that requires pg_upgrade to manipulate SLRU files. That patch needs to access SLRU_PAGES_PER_SEGMENT from pg_upgrade code, and slru.h, where SLRU_PAGES_PER_SEGMENT is currently defined, cannot be included from frontend code. Moving it to pg_config_manual.h makes it accessible. Now that it's a little more likely that someone might change SLRU_PAGES_PER_SEGMENT, add a cluster compatibility check for it. Bump catalog version because of the new field in the control file. Reviewed-by: Daniel Gustafsson Reviewed-by: Álvaro Herrera Discussion: https://www.postgresql.org/message-id/c7a4ea90-9f7b-4953-81be-b3fcb47db057@iki.fi --- src/backend/access/transam/xlog.c | 11 +++++++++++ src/include/access/slru.h | 15 --------------- src/include/catalog/catversion.h | 2 +- src/include/catalog/pg_control.h | 2 ++ src/include/pg_config_manual.h | 10 ++++++++++ 5 files changed, 24 insertions(+), 16 deletions(-) diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 101b616b028..22d0a2e8c3a 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -4271,6 +4271,7 @@ WriteControlFile(void) ControlFile->blcksz = BLCKSZ; ControlFile->relseg_size = RELSEG_SIZE; + ControlFile->slru_pages_per_segment = SLRU_PAGES_PER_SEGMENT; ControlFile->xlog_blcksz = XLOG_BLCKSZ; ControlFile->xlog_seg_size = wal_segment_size; @@ -4490,6 +4491,16 @@ ReadControlFile(void) "RELSEG_SIZE", ControlFile->relseg_size, "RELSEG_SIZE", RELSEG_SIZE), errhint("It looks like you need to recompile or initdb."))); + if (ControlFile->slru_pages_per_segment != SLRU_PAGES_PER_SEGMENT) + ereport(FATAL, + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("database files are incompatible with server"), + /* translator: %s is a variable name and %d is its value */ + errdetail("The database cluster was initialized with %s %d," + " but the server was compiled with %s %d.", + "SLRU_PAGES_PER_SEGMENT", ControlFile->slru_pages_per_segment, + "SLRU_PAGES_PER_SEGMENT", SLRU_PAGES_PER_SEGMENT), + errhint("It looks like you need to recompile or initdb."))); if (ControlFile->xlog_blcksz != XLOG_BLCKSZ) ereport(FATAL, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), diff --git a/src/include/access/slru.h b/src/include/access/slru.h index 8d57753ed01..8576649b15e 100644 --- a/src/include/access/slru.h +++ b/src/include/access/slru.h @@ -23,21 +23,6 @@ */ #define SLRU_MAX_ALLOWED_BUFFERS ((1024 * 1024 * 1024) / BLCKSZ) -/* - * Define SLRU segment size. A page is the same BLCKSZ as is used everywhere - * else in Postgres. The segment size can be chosen somewhat arbitrarily; - * we make it 32 pages by default, or 256Kb, i.e. 1M transactions for CLOG - * or 64K transactions for SUBTRANS. - * - * Note: because TransactionIds are 32 bits and wrap around at 0xFFFFFFFF, - * page numbering also wraps around at 0xFFFFFFFF/xxxx_XACTS_PER_PAGE (where - * xxxx is CLOG or SUBTRANS, respectively), and segment numbering at - * 0xFFFFFFFF/xxxx_XACTS_PER_PAGE/SLRU_PAGES_PER_SEGMENT. We need - * take no explicit notice of that fact in slru.c, except when comparing - * segment and page numbers in SimpleLruTruncate (see PagePrecedes()). - */ -#define SLRU_PAGES_PER_SEGMENT 32 - /* * Page status codes. Note that these do not include the "dirty" bit. * page_dirty can be true only in the VALID or WRITE_IN_PROGRESS states; diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index 60e7fd047d1..7eefca1ae42 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -57,6 +57,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 202511071 +#define CATALOG_VERSION_NO 202511101 #endif diff --git a/src/include/catalog/pg_control.h b/src/include/catalog/pg_control.h index 63e834a6ce4..1ac0d5126fc 100644 --- a/src/include/catalog/pg_control.h +++ b/src/include/catalog/pg_control.h @@ -207,6 +207,8 @@ typedef struct ControlFileData uint32 blcksz; /* data block size for this DB */ uint32 relseg_size; /* blocks per segment of large relation */ + uint32 slru_pages_per_segment; /* size of each SLRU segment */ + uint32 xlog_blcksz; /* block size within WAL files */ uint32 xlog_seg_size; /* size of each WAL segment */ diff --git a/src/include/pg_config_manual.h b/src/include/pg_config_manual.h index 7e1aa422332..c61a9faf870 100644 --- a/src/include/pg_config_manual.h +++ b/src/include/pg_config_manual.h @@ -19,6 +19,16 @@ */ #define DEFAULT_XLOG_SEG_SIZE (16*1024*1024) +/* + * SLRU segment size. A page is the same BLCKSZ as is used everywhere else in + * Postgres. The segment size can be chosen somewhat arbitrarily; we make it + * 32 pages by default, or 256Kb, i.e. 1M transactions for CLOG or 64K + * transactions for SUBTRANS. + * + * Changing this requires an initdb. + */ +#define SLRU_PAGES_PER_SEGMENT 32 + /* * Maximum length for identifiers (e.g. table names, column names, * function names). Names actually are limited to one fewer byte than this,