@@ -51,6 +51,27 @@ sub configure_and_reload
51
51
) );
52
52
$node_paris -> start;
53
53
54
+ # Check if the extension injection_points is available, as it may be
55
+ # possible that this script is run with installcheck, where the module
56
+ # would not be installed by default.
57
+ my $injection_points_supported =
58
+ $node_london -> check_extension(' injection_points' );
59
+ if ($injection_points_supported != 0)
60
+ {
61
+ $node_london -> safe_psql(' postgres' , ' CREATE EXTENSION injection_points;' );
62
+
63
+ # Set shared_preload_libraries, to allow the injection points to persist
64
+ # across restarts.
65
+ $node_london -> append_conf(
66
+ ' postgresql.conf' , qq(
67
+ shared_preload_libraries = 'injection_points'
68
+ ) );
69
+ $node_paris -> append_conf(
70
+ ' postgresql.conf' , qq(
71
+ shared_preload_libraries = 'injection_points'
72
+ ) );
73
+ }
74
+
54
75
# Switch to synchronous replication in both directions
55
76
configure_and_reload($node_london , " synchronous_standby_names = 'paris'" );
56
77
configure_and_reload($node_paris , " synchronous_standby_names = 'london'" );
@@ -327,6 +348,23 @@ sub configure_and_reload
327
348
INSERT INTO t_009_tbl_standby_mvcc VALUES (2, 'issued to ${cur_primary_name} ');
328
349
PREPARE TRANSACTION 'xact_009_standby_mvcc';
329
350
" );
351
+
352
+ # Attach an injection point to wait in the checkpointer when configuring
353
+ # the shared memory state data related to synchronous_standby_names, then
354
+ # persist the attached point to disk so as the follow-up restart will be able
355
+ # to wait at the early stages of the checkpointer startup sequence.
356
+ #
357
+ # Note that as the checkpointer has already applied the
358
+ # synchronous_standby_names configuration, this has no effect until the
359
+ # next startup of the primary.
360
+ if ($injection_points_supported != 0)
361
+ {
362
+ $cur_primary -> psql(' postgres' ,
363
+ " SELECT injection_points_attach('checkpointer-syncrep-update', 'wait')"
364
+ );
365
+ $cur_primary -> psql(' postgres' , " SELECT injection_points_flush()" );
366
+ }
367
+
330
368
$cur_primary -> stop;
331
369
$cur_standby -> restart;
332
370
@@ -341,6 +379,16 @@ sub configure_and_reload
341
379
342
380
# Commit the transaction in primary
343
381
$cur_primary -> start;
382
+
383
+ # Make sure that the checkpointer is waiting before setting up the data of
384
+ # synchronous_standby_names in shared memory. We want the checkpointer to be
385
+ # stuck and make sure that the next COMMIT PREPARED is detected correctly on
386
+ # the standby when remote_apply is set on the primary.
387
+ if ($injection_points_supported != 0)
388
+ {
389
+ $cur_primary -> wait_for_event(' checkpointer' ,
390
+ ' checkpointer-syncrep-update' );
391
+ }
344
392
$cur_primary -> psql(
345
393
' postgres' , "
346
394
SET synchronous_commit='remote_apply'; -- To ensure the standby is caught up
@@ -361,6 +409,18 @@ sub configure_and_reload
361
409
" Committed prepared transaction is visible to new snapshot in standby" );
362
410
$standby_session -> quit;
363
411
412
+ # Remove the injection point, the checkpointer now applies the configuration
413
+ # related to synchronous_standby_names in shared memory.
414
+ if ($injection_points_supported != 0)
415
+ {
416
+ $cur_primary -> psql(' postgres' ,
417
+ " SELECT injection_points_wakeup('checkpointer-syncrep-update')" );
418
+ $cur_primary -> psql(' postgres' ,
419
+ " SELECT injection_points_detach('checkpointer-syncrep-update')" );
420
+ }
421
+
422
+ $cur_standby -> restart;
423
+
364
424
# ##############################################################################
365
425
# Check for a lock conflict between prepared transaction with DDL inside and
366
426
# replay of XLOG_STANDBY_LOCK wal record.
0 commit comments