#! /bin/sh
set -ex

PGDATA=repro-btree-reuse
PGDATABASE=repro_btree_reuse
export PGDATA PGDATABASE PGPORT
unset PGUSER

# master
PGPORT=1
initdb
cat >$PGDATA/pg_hba.conf <<EOF
local all all ident
local replication all ident
EOF
cat >$PGDATA/postgresql.conf <<EOF
listen_addresses = ''
logging_collector = on
autovacuum = off
hot_standby = on
wal_level = hot_standby
archive_mode = on
archive_command = ':'
max_wal_senders = 1
wal_keep_segments = 5
hot_standby_feedback = on
wal_receiver_status_interval = 1
max_standby_streaming_delay = 0
EOF
pg_ctl -w start
createdb
psql -c "SELECT pg_start_backup('foo', true)"
cp -a $PGDATA standby_$PGDATA
psql -c 'SELECT pg_stop_backup()'

# standby
PGPORT=2
rm standby_$PGDATA/postmaster.pid
cat >standby_$PGDATA/recovery.conf <<EOF
standby_mode = 'on'
primary_conninfo = 'port=1'
EOF
pg_ctl -w -D standby_$PGDATA start

# Stage some B-tree pages full of pointers to dead tuples.
PGPORT=1 psql -X <<'EOSQL'
CREATE TABLE t (x) AS SELECT n FROM generate_series(1,1000) t(n);
CREATE INDEX ON t(x);
DELETE FROM t;
EOSQL
sleep 2 # let feedback catch up

# Any long-running command; its snapshot will conflict with recovery.
PGPORT=2 psql -c 'SELECT pg_sleep(600)' &
sleep 2

# Mark the pages BTP_DELETED, then reuse them.
PGPORT=1 psql -X <<EOSQL
VACUUM t;
VACUUM t;	-- second VACUUM required to make the reuse happen
INSERT INTO t SELECT n FROM generate_series(1,1000) t(n);
EOSQL
sleep 2

PGPORT=2 pg_ctl -w -D standby_$PGDATA -m fast stop
PGPORT=1 pg_ctl -w -m fast stop
