Depending on specific values of restart_lsn or pg_current_wal_lsn()
is obviously unsafe. The previous coding tried to dodge this issue
by rounding off, but that's not good enough, as shown by multiple
buildfarm members. Nuke all the uses of these values except for
null-ness checks, pending some credible argument why we should think
something else could be usefully stable.
Kyotaro Horiguchi, further modified by me
Discussion: https://postgr.es/m/E1jM1Sa-0003mS-99@gemulon.postgresql.org
# The slot state and remain should be null before the first connection
my$result=$node_master->safe_psql('postgres',"SELECT restart_lsn is NULL, wal_status is NULL, min_safe_lsn is NULL FROM pg_replication_slots WHERE slot_name = 'rep1'");
my$result=$node_master->safe_psql('postgres',"SELECT restart_lsn IS NULL, wal_status is NULL, min_safe_lsn is NULL FROM pg_replication_slots WHERE slot_name = 'rep1'");
is($result,"t|t|t",'check the state of non-reserved slot is "unknown"');
$result=$node_master->safe_psql('postgres',"SELECT restart_lsn, wal_status, pg_size_pretty(pg_current_wal_lsn() - min_safe_lsn) FROM pg_replication_slots WHERE slot_name = 'rep1'");
is($result,"$start_lsn|normal|2048 kB",'check that min_safe_lsn gets close to the current LSN');
$result=$node_master->safe_psql('postgres',"SELECT wal_status FROM pg_replication_slots WHERE slot_name = 'rep1'");
is($result,"normal",'check that min_safe_lsn gets close to the current LSN');
# The standby can reconnect to master
$node_standby->start;
@ -106,8 +106,8 @@ $node_standby->stop;
$result=$node_master->safe_psql('postgres',"ALTER SYSTEM SET wal_keep_segments to 8; SELECT pg_reload_conf();");
# Advance WAL again then checkpoint, reducing remain by 6 MB.
advance_wal($node_master,6);
$result=$node_master->safe_psql('postgres',"SELECT restart_lsn, wal_status, pg_size_pretty(pg_current_wal_lsn() - min_safe_lsn) as remain FROM pg_replication_slots WHERE slot_name = 'rep1'");
is($result,"$start_lsn|normal|8192 kB",'check that wal_keep_segments overrides max_slot_wal_keep_size');
$result=$node_master->safe_psql('postgres',"SELECT wal_status as remain FROM pg_replication_slots WHERE slot_name = 'rep1'");
is($result,"normal",'check that wal_keep_segments overrides max_slot_wal_keep_size');
# restore wal_keep_segments
$result=$node_master->safe_psql('postgres',"ALTER SYSTEM SET wal_keep_segments to 0; SELECT pg_reload_conf();");
$result=$node_master->safe_psql('postgres',"SELECT wal_status FROM pg_replication_slots WHERE slot_name = 'rep1'");
is($result,"lost",'check that the slot state changes to "lost"');
$result=$node_master->safe_psql('postgres',"SELECT wal_status, min_safe_lsn is NULL FROM pg_replication_slots WHERE slot_name = 'rep1'");
is($result,"lost|t",'check that the slot state changes to "lost"');
# The standby still can connect to master before a checkpoint
$node_standby->start;
@ -158,8 +158,8 @@ ok(find_in_log($node_master,
'check that the warning is logged');
# This slot should be broken
$result=$node_master->safe_psql('postgres',"SELECT slot_name, active, restart_lsn, wal_status, min_safe_lsn FROM pg_replication_slots WHERE slot_name = 'rep1'");
is($result,"rep1|f|||",'check that the slot became inactive');
$result=$node_master->safe_psql('postgres',"SELECT slot_name, active, restart_lsn IS NULL, wal_status, min_safe_lsn FROM pg_replication_slots WHERE slot_name = 'rep1'");
is($result,"rep1|f|t||",'check that the slot became inactive');