diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index c3baca5193b..3eddec89ad0 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -4283,6 +4283,7 @@ InitControlFile(uint64 sysidentifier, uint32 data_checksum_version) ControlFile->wal_log_hints = wal_log_hints; ControlFile->track_commit_timestamp = track_commit_timestamp; ControlFile->data_checksum_version = data_checksum_version; + ControlFile->data_checksum_version_init = data_checksum_version; /* * Set the data_checksum_version value into XLogCtl, which is where all diff --git a/src/backend/utils/misc/pg_controldata.c b/src/backend/utils/misc/pg_controldata.c index d229ae35209..d4feec95b26 100644 --- a/src/backend/utils/misc/pg_controldata.c +++ b/src/backend/utils/misc/pg_controldata.c @@ -254,7 +254,7 @@ pg_control_init(PG_FUNCTION_ARGS) values[9] = BoolGetDatum(ControlFile->float8ByVal); nulls[9] = false; - values[10] = Int32GetDatum(ControlFile->data_checksum_version); + values[10] = Int32GetDatum(ControlFile->data_checksum_version_init); nulls[10] = false; values[11] = BoolGetDatum(ControlFile->default_char_signedness); diff --git a/src/include/catalog/pg_control.h b/src/include/catalog/pg_control.h index 80b3a730e03..7b5404460ec 100644 --- a/src/include/catalog/pg_control.h +++ b/src/include/catalog/pg_control.h @@ -22,7 +22,7 @@ /* Version identifier for this pg_control format */ -#define PG_CONTROL_VERSION 1902 +#define PG_CONTROL_VERSION 1903 /* Nonce key length, see below */ #define MOCK_AUTH_NONCE_LEN 32 @@ -228,7 +228,13 @@ typedef struct ControlFileData bool float8ByVal; /* float8, int8, etc pass-by-value? */ - /* Are data pages protected by checksums? Zero if no checksum version */ + /* + * Data checksum state at cluster initialization. Since the state can be + * changed during runtime, we need to store the initial value for system + * functions which report initdb settings. + */ + uint32 data_checksum_version_init; + /* Current data checksums state */ uint32 data_checksum_version; /* diff --git a/src/test/modules/test_checksums/t/001_basic.pl b/src/test/modules/test_checksums/t/001_basic.pl index 72e0d0df46f..7477f00947d 100644 --- a/src/test/modules/test_checksums/t/001_basic.pl +++ b/src/test/modules/test_checksums/t/001_basic.pl @@ -14,24 +14,33 @@ use lib $FindBin::RealBin; use DataChecksums::Utils; -# Initialize node with checksums disabled. +# Initialize node with checksums enabled to test pg_control_init returning +# 1 for this cluster, the remaining tests will initialize to off to test the +# return value for a cluster initialized without checksums my $node = PostgreSQL::Test::Cluster->new('basic_node'); -$node->init(no_data_checksums => 1); +$node->init; $node->start; -# Create some content to have un-checksummed data in the cluster +# Create some content to have data in the cluster $node->safe_psql('postgres', "CREATE TABLE t AS SELECT generate_series(1,10000) AS a;"); -# Ensure that checksums are turned off -test_checksum_state($node, 'off'); +# Ensure that checksums are turned on +test_checksum_state($node, 'on'); + +# Disable data checksums and wait for the state transition to 'off' +disable_data_checksums($node, wait => 'off'); + +# Make sure pg_control_init reports the initial enabled state +my $result = $node->safe_psql('postgres', + 'SELECT data_page_checksum_version FROM pg_control_init();'); +is($result, '1', 'ensure pg_control_init reports enabled state'); # Enable data checksums and wait for the state transition to 'on' enable_data_checksums($node, wait => 'on'); # Run a dummy query just to make sure we can read back data -my $result = - $node->safe_psql('postgres', "SELECT count(*) FROM t WHERE a > 1 "); +$result = $node->safe_psql('postgres', "SELECT count(*) FROM t WHERE a > 1 "); is($result, '9999', 'ensure checksummed pages can be read back'); # Enable data checksums again which should be a no-op so we explicitly don't diff --git a/src/test/modules/test_checksums/t/002_restarts.pl b/src/test/modules/test_checksums/t/002_restarts.pl index d98c8024f29..bef0bb90993 100644 --- a/src/test/modules/test_checksums/t/002_restarts.pl +++ b/src/test/modules/test_checksums/t/002_restarts.pl @@ -30,6 +30,11 @@ $node->safe_psql('postgres', # Ensure that checksums are disabled test_checksum_state($node, 'off'); +# Make sure pg_control_init reports the initial disabled state +$result = $node->safe_psql('postgres', + 'SELECT data_page_checksum_version FROM pg_control_init();'); +is($result, '0', 'ensure pg_control_init reports disabled state'); + SKIP: { skip 'Data checksum delay tests not enabled in PG_TEST_EXTRA', 6 @@ -134,9 +139,14 @@ wait_for_checksum_state($node, "off"); $block_session->quit; # Finish test suite by enabling checksums and make sure all data can be read -# back and no processes are left over +# back, no processes are left over and the initial state is still correctly +# reported enable_data_checksums($node, wait => 'on'); +$result = $node->safe_psql('postgres', + 'SELECT data_page_checksum_version FROM pg_control_init();'); +is($result, '0', 'ensure pg_control_init still reports disabled state'); + $result = $node->safe_psql('postgres', "SELECT count(*) FROM t WHERE a > 1"); is($result, '9999', 'ensure checksummed pages can be read back'); diff --git a/src/test/modules/test_checksums/t/004_offline.pl b/src/test/modules/test_checksums/t/004_offline.pl index 73c279e75e0..48254111410 100644 --- a/src/test/modules/test_checksums/t/004_offline.pl +++ b/src/test/modules/test_checksums/t/004_offline.pl @@ -20,6 +20,11 @@ my $node = PostgreSQL::Test::Cluster->new('offline_node'); $node->init(no_data_checksums => 1); $node->start; +# Make sure pg_control_init reports the initial state as disabled +my $result = $node->safe_psql('postgres', + 'SELECT data_page_checksum_version FROM pg_control_init();'); +is($result, '0', 'ensure pg_control_init reports disabled state'); + # Create some content to have un-checksummed data in the cluster $node->safe_psql('postgres', "CREATE TABLE t AS SELECT generate_series(1,10000) AS a;"); @@ -35,9 +40,14 @@ $node->start; # Ensure that checksums are enabled test_checksum_state($node, 'on'); +# Make sure pg_control_init still reports the initial state as disabled even +# though the current state has changed. +$result = $node->safe_psql('postgres', + 'SELECT data_page_checksum_version FROM pg_control_init();'); +is($result, '0', 'ensure pg_control_init still reports disabled state'); + # Run a dummy query just to make sure we can read back some data -my $result = - $node->safe_psql('postgres', "SELECT count(*) FROM t WHERE a > 1"); +$result = $node->safe_psql('postgres', "SELECT count(*) FROM t WHERE a > 1"); is($result, '9999', 'ensure checksummed pages can be read back'); # Disable checksums offline again using pg_checksums