Fix race condition in test_decoding "slot" test.
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 12 Dec 2016 19:32:09 +0000 (14:32 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 12 Dec 2016 19:32:13 +0000 (14:32 -0500)
This test, just added in commit a924c327e, sometimes fails because
the old backend hasn't finished dropping the temporary replication slot
when the new backend looks.  Borrow the previously-invented methodology
for waiting for the old process to disappear from pg_stat_activity.

Petr Jelinek

Discussion: https://postgr.es/m/62935e6f-4f1b-c433-e0fa-7f936a38b3e5@2ndquadrant.com

contrib/test_decoding/expected/slot.out
contrib/test_decoding/sql/slot.sql

index 5e6b70ba38aa180a2c4fce4b42b6a4ab7f9d2c3c..c9171ffa5feae0f058ded7286a8827f5de06540b 100644 (file)
@@ -22,17 +22,26 @@ SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot_p', 'test
  init
 (1 row)
 
--- reconnect to clean temp slots
-\c
+-- here we want to start a new session and wait till old one is gone
+select pg_backend_pid() as oldpid \gset
+\c -
+do 'declare c int = 0;
+begin
+  while (select count(*) from pg_stat_activity where pid = '
+    :'oldpid'
+  ') > 0 loop c := c + 1; perform pg_stat_clear_snapshot(); end loop;
+  raise log ''slot test looped % times'', c;
+end';
+-- should fail because the temporary slot was dropped automatically
+SELECT pg_drop_replication_slot('regression_slot_t');
+ERROR:  replication slot "regression_slot_t" does not exist
+-- permanent slot has survived
 SELECT pg_drop_replication_slot('regression_slot_p');
  pg_drop_replication_slot 
 --------------------------
  
 (1 row)
 
--- should fail because the temporary slot was dropped automatically
-SELECT pg_drop_replication_slot('regression_slot_t');
-ERROR:  replication slot "regression_slot_t" does not exist
 -- test switching between slots in a session
 SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot1', 'test_decoding', true);
  ?column? 
index 3b0aecd6a88a735dc713477610ce2d2c1a5069d8..5d6d97a9e360de13394e38e207d30e6c016c65a1 100644 (file)
@@ -4,14 +4,22 @@ SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot_t', 'test
 SELECT pg_drop_replication_slot('regression_slot_p');
 SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot_p', 'test_decoding', false);
 
--- reconnect to clean temp slots
-\c
-
-SELECT pg_drop_replication_slot('regression_slot_p');
+-- here we want to start a new session and wait till old one is gone
+select pg_backend_pid() as oldpid \gset
+\c -
+do 'declare c int = 0;
+begin
+  while (select count(*) from pg_stat_activity where pid = '
+    :'oldpid'
+  ') > 0 loop c := c + 1; perform pg_stat_clear_snapshot(); end loop;
+  raise log ''slot test looped % times'', c;
+end';
 
 -- should fail because the temporary slot was dropped automatically
 SELECT pg_drop_replication_slot('regression_slot_t');
 
+-- permanent slot has survived
+SELECT pg_drop_replication_slot('regression_slot_p');
 
 -- test switching between slots in a session
 SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot1', 'test_decoding', true);