Improve runtime and output of tests for replication slots checkpointing. master github/master
authorAlexander Korotkov
Thu, 19 Jun 2025 22:41:28 +0000 (01:41 +0300)
committerAlexander Korotkov
Thu, 19 Jun 2025 22:41:28 +0000 (01:41 +0300)
The TAP tests that verify logical and physical replication slot behavior
during checkpoints (046_checkpoint_logical_slot.pl and
047_checkpoint_physical_slot.pl) inserted two batches of 2 million rows each,
generating approximately 520 MB of WAL.  On slow machines, or when compiled
with '-DRELCACHE_FORCE_RELEASE -DCATCACHE_FORCE_RELEASE', this caused the
tests to run for 8-9 minutes and occasionally time out, as seen on the
buildfarm animal prion.

This commit modifies the mentioned tests to utilize the $node->advance_wal()
function, thereby reducing runtime. Once we do not use the generated data,
the proposed function is a good alternative, which cuts the total wall-clock
run time.

While here, remove superfluous '\n' characters from several note() calls;
these appeared literally in the build-farm logs and looked odd.  Also, remove
excessive 'shared_preload_libraries' GUC from the config and add a check for
'injection_points' extension availability.

Reported-by: Alexander Lakhin
Reported-by: Tom Lane
Author: Alexander Korotkov 
Author: Vitaly Davydov 
Reviewed-by: Hayato Kuroda
Discussion: https://postgr.es/m/fbc5d94e-6fbd-4a64-85d4-c9e284a58eb2%40gmail.com
Backpatch-through: 17

src/test/recovery/t/046_checkpoint_logical_slot.pl
src/test/recovery/t/047_checkpoint_physical_slot.pl

index b4265c4a6a53f5a434e6653df1476645d7054826..d67c5108d78009955af1c0b93c8fcec96f9310b2 100644 (file)
@@ -21,15 +21,18 @@ my ($node, $result);
 
 $node = PostgreSQL::Test::Cluster->new('mike');
 $node->init;
 
 $node = PostgreSQL::Test::Cluster->new('mike');
 $node->init;
-$node->append_conf('postgresql.conf',
-   "shared_preload_libraries = 'injection_points'");
 $node->append_conf('postgresql.conf', "wal_level = 'logical'");
 $node->start;
 $node->append_conf('postgresql.conf', "wal_level = 'logical'");
 $node->start;
-$node->safe_psql('postgres', q(CREATE EXTENSION injection_points));
 
 
-# Create a simple table to generate data into.
-$node->safe_psql('postgres',
-   q{create table t (id serial primary key, b text)});
+# Check if the extension injection_points is available, as it may be
+# possible that this script is run with installcheck, where the module
+# would not be installed by default.
+if (!$node->check_extension('injection_points'))
+{
+   plan skip_all => 'Extension injection_points not installed';
+}
+
+$node->safe_psql('postgres', q(CREATE EXTENSION injection_points));
 
 # Create the two slots we'll need.
 $node->safe_psql('postgres',
 
 # Create the two slots we'll need.
 $node->safe_psql('postgres',
@@ -58,23 +61,17 @@ SELECT 1 \watch 0.1
 \q
 ));
 
 \q
 ));
 
-# Insert 2M rows; that's about 260MB (~20 segments) worth of WAL.
-$node->safe_psql('postgres',
-   q{insert into t (b) select md5(i::text) from generate_series(1,1000000) s(i)}
-);
+$node->advance_wal(20);
 
 # Run another checkpoint to set a new restore LSN.
 $node->safe_psql('postgres', q{checkpoint});
 
 
 # Run another checkpoint to set a new restore LSN.
 $node->safe_psql('postgres', q{checkpoint});
 
-# Another 2M rows; that's about 260MB (~20 segments) worth of WAL.
-$node->safe_psql('postgres',
-   q{insert into t (b) select md5(i::text) from generate_series(1,1000000) s(i)}
-);
+$node->advance_wal(20);
 
 # Run another checkpoint, this time in the background, and make it wait
 # on the injection point) so that the checkpoint stops right before
 # removing old WAL segments.
 
 # Run another checkpoint, this time in the background, and make it wait
 # on the injection point) so that the checkpoint stops right before
 # removing old WAL segments.
-note('starting checkpoint\n');
+note('starting checkpoint');
 
 my $checkpoint = $node->background_psql('postgres');
 $checkpoint->query_safe(
 
 my $checkpoint = $node->background_psql('postgres');
 $checkpoint->query_safe(
@@ -88,7 +85,7 @@ checkpoint;
 ));
 
 # Wait until the checkpoint stops right before removing WAL segments.
 ));
 
 # Wait until the checkpoint stops right before removing WAL segments.
-note('waiting for injection_point\n');
+note('waiting for injection_point');
 $node->wait_for_event('checkpointer', 'checkpoint-before-old-wal-removal');
 note('injection_point is reached');
 
 $node->wait_for_event('checkpointer', 'checkpoint-before-old-wal-removal');
 note('injection_point is reached');
 
@@ -107,7 +104,7 @@ select count(*) from pg_logical_slot_get_changes('slot_logical', null, null) \wa
 ));
 
 # Wait until the slot's restart_lsn points to the next WAL segment.
 ));
 
 # Wait until the slot's restart_lsn points to the next WAL segment.
-note('waiting for injection_point\n');
+note('waiting for injection_point');
 $node->wait_for_event('client backend',
    'logical-replication-slot-advance-segment');
 note('injection_point is reached');
 $node->wait_for_event('client backend',
    'logical-replication-slot-advance-segment');
 note('injection_point is reached');
index 454e56b9bd2da4460ffd75e877da9c71dfdcb755..a1332b5d44cbe529cd6865a3875f704e414cc881 100644 (file)
@@ -21,15 +21,18 @@ my ($node, $result);
 
 $node = PostgreSQL::Test::Cluster->new('mike');
 $node->init;
 
 $node = PostgreSQL::Test::Cluster->new('mike');
 $node->init;
-$node->append_conf('postgresql.conf',
-   "shared_preload_libraries = 'injection_points'");
 $node->append_conf('postgresql.conf', "wal_level = 'replica'");
 $node->start;
 $node->append_conf('postgresql.conf', "wal_level = 'replica'");
 $node->start;
-$node->safe_psql('postgres', q(CREATE EXTENSION injection_points));
 
 
-# Create a simple table to generate data into.
-$node->safe_psql('postgres',
-   q{create table t (id serial primary key, b text)});
+# Check if the extension injection_points is available, as it may be
+# possible that this script is run with installcheck, where the module
+# would not be installed by default.
+if (!$node->check_extension('injection_points'))
+{
+   plan skip_all => 'Extension injection_points not installed';
+}
+
+$node->safe_psql('postgres', q(CREATE EXTENSION injection_points));
 
 # Create a physical replication slot.
 $node->safe_psql('postgres',
 
 # Create a physical replication slot.
 $node->safe_psql('postgres',
@@ -44,9 +47,7 @@ $node->safe_psql('postgres',
 $node->safe_psql('postgres', q{checkpoint});
 
 # Insert 2M rows; that's about 260MB (~20 segments) worth of WAL.
 $node->safe_psql('postgres', q{checkpoint});
 
 # Insert 2M rows; that's about 260MB (~20 segments) worth of WAL.
-$node->safe_psql('postgres',
-   q{insert into t (b) select md5(i::text) from generate_series(1,100000) s(i)}
-);
+$node->advance_wal(20);
 
 # Advance slot to the current position, just to have everything "valid".
 $node->safe_psql('postgres',
 
 # Advance slot to the current position, just to have everything "valid".
 $node->safe_psql('postgres',
@@ -57,9 +58,7 @@ $node->safe_psql('postgres',
 $node->safe_psql('postgres', q{checkpoint});
 
 # Another 2M rows; that's about 260MB (~20 segments) worth of WAL.
 $node->safe_psql('postgres', q{checkpoint});
 
 # Another 2M rows; that's about 260MB (~20 segments) worth of WAL.
-$node->safe_psql('postgres',
-   q{insert into t (b) select md5(i::text) from generate_series(1,1000000) s(i)}
-);
+$node->advance_wal(20);
 
 my $restart_lsn_init = $node->safe_psql('postgres',
    q{select restart_lsn from pg_replication_slots where slot_name = 'slot_physical'}
 
 my $restart_lsn_init = $node->safe_psql('postgres',
    q{select restart_lsn from pg_replication_slots where slot_name = 'slot_physical'}