From 8d4315cb29088fe46907ab638656df295f3ab43c Mon Sep 17 00:00:00 2001 From: Tomas Vondra Date: Fri, 7 Mar 2025 23:07:44 +0100 Subject: [PATCH v20250310 3/5] sync the data_checksums GUC with the local variable We now have three places that in some way express the state of data checksums in the instance. - control file / data_checksum_version - LocalDataChecksumVersion as a local cache to reduce locking - data_checksums backing the GUC We need to keep the GUC variable in sync, to ensure we get the correct value even early during startup (e.g. with -C). Introduces a new SetLocalDataChecksumVersion() which sets the local variable, and also updates the data_checksum GUC at the same time. --- src/backend/access/transam/xlog.c | 51 +++++++++++++++++++++++++---- src/backend/utils/misc/guc_tables.c | 3 +- src/include/access/xlog.h | 1 + 3 files changed, 47 insertions(+), 8 deletions(-) diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index b5190a7e104..f137cdc6d42 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -657,6 +657,14 @@ static bool updateMinRecoveryPoint = true; */ static uint32 LocalDataChecksumVersion = 0; +/* + * Variable backing the GUC, keep it in sync with LocalDataChecksumVersion. + * See SetLocalDataChecksumVersion(). + */ +int data_checksums = 0; + +static void SetLocalDataChecksumVersion(uint32 data_checksum_version); + /* For WALInsertLockAcquire/Release functions */ static int MyLockNo = 0; static bool holdingAllLocks = false; @@ -4594,7 +4602,7 @@ ReadControlFile(void) CalculateCheckpointSegments(); - LocalDataChecksumVersion = ControlFile->data_checksum_version; + SetLocalDataChecksumVersion(ControlFile->data_checksum_version); } /* @@ -4913,7 +4921,7 @@ SetDataChecksumsOff(void) bool AbsorbChecksumsOnInProgressBarrier(void) { - LocalDataChecksumVersion = PG_DATA_CHECKSUM_INPROGRESS_ON_VERSION; + SetLocalDataChecksumVersion(PG_DATA_CHECKSUM_INPROGRESS_ON_VERSION); return true; } @@ -4921,21 +4929,21 @@ bool AbsorbChecksumsOnBarrier(void) { Assert(LocalDataChecksumVersion == PG_DATA_CHECKSUM_INPROGRESS_ON_VERSION); - LocalDataChecksumVersion = PG_DATA_CHECKSUM_VERSION; + SetLocalDataChecksumVersion(PG_DATA_CHECKSUM_VERSION); return true; } bool AbsorbChecksumsOffInProgressBarrier(void) { - LocalDataChecksumVersion = PG_DATA_CHECKSUM_INPROGRESS_OFF_VERSION; + SetLocalDataChecksumVersion(PG_DATA_CHECKSUM_INPROGRESS_OFF_VERSION); return true; } bool AbsorbChecksumsOffBarrier(void) { - LocalDataChecksumVersion = 0; + SetLocalDataChecksumVersion(0); return true; } @@ -4951,10 +4959,41 @@ void InitLocalControldata(void) { LWLockAcquire(ControlFileLock, LW_EXCLUSIVE); - LocalDataChecksumVersion = ControlFile->data_checksum_version; + SetLocalDataChecksumVersion(ControlFile->data_checksum_version); LWLockRelease(ControlFileLock); } +/* + * XXX probably should be called in all places that modify the value of + * LocalDataChecksumVersion (to make sure data_checksums GUC is in sync) + * + * XXX aren't PG_DATA_ and DATA_ constants the same? why do we need both? + */ +void +SetLocalDataChecksumVersion(uint32 data_checksum_version) +{ + LocalDataChecksumVersion = data_checksum_version; + + switch (LocalDataChecksumVersion) + { + case PG_DATA_CHECKSUM_VERSION: + data_checksums = DATA_CHECKSUMS_ON; + break; + + case PG_DATA_CHECKSUM_INPROGRESS_ON_VERSION: + data_checksums = DATA_CHECKSUMS_INPROGRESS_ON; + break; + + case PG_DATA_CHECKSUM_INPROGRESS_OFF_VERSION: + data_checksums = DATA_CHECKSUMS_INPROGRESS_OFF; + break; + + default: + data_checksums = DATA_CHECKSUMS_OFF; + break; + } +} + /* guc hook */ const char * show_data_checksums(void) diff --git a/src/backend/utils/misc/guc_tables.c b/src/backend/utils/misc/guc_tables.c index 05cba3a02e3..66abf056159 100644 --- a/src/backend/utils/misc/guc_tables.c +++ b/src/backend/utils/misc/guc_tables.c @@ -609,7 +609,6 @@ static int shared_memory_size_mb; static int shared_memory_size_in_huge_pages; static int wal_block_size; static int num_os_semaphores; -static int data_checksums; static bool integer_datetimes; #ifdef USE_ASSERT_CHECKING @@ -5300,7 +5299,7 @@ struct config_enum ConfigureNamesEnum[] = {"data_checksums", PGC_INTERNAL, PRESET_OPTIONS, gettext_noop("Shows whether data checksums are turned on for this cluster."), NULL, - GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE + GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE | GUC_RUNTIME_COMPUTED }, &data_checksums, DATA_CHECKSUMS_OFF, data_checksums_options, diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h index 0bb32c9c0fc..aec3ea0bc63 100644 --- a/src/include/access/xlog.h +++ b/src/include/access/xlog.h @@ -56,6 +56,7 @@ extern PGDLLIMPORT int CommitDelay; extern PGDLLIMPORT int CommitSiblings; extern PGDLLIMPORT bool track_wal_io_timing; extern PGDLLIMPORT int wal_decode_buffer_size; +extern PGDLLIMPORT int data_checksums; extern PGDLLIMPORT int CheckPointSegments; -- 2.48.1