#!/bin/bash
#
# This script assumes that the binaries are in ./bin.
#
# You must create ./walarchive. The script will create data directories
# data-master, and data-backup.
#
PGPATH=.

set -e

$PGPATH/bin/initdb -D data-master

cat >> data-master/postgresql.conf <<EOF
#added by setup_hot_standby.sh
max_wal_senders = 5
wal_level = archive
archive_mode=on
archive_command='test ! -f $PWD/walarchive/%f && cp %p $PWD/walarchive/%f'
EOF

echo "local   replication     all         trust" >> data-master/pg_hba.conf

$PGPATH/bin/pg_ctl -w -D data-master start

$PGPATH/bin/pg_basebackup -D data-backup

$PGPATH/bin/psql postgres -c "create table foo (id int4, foo text)";

# The insertions below are aiming at creating WAL records 106 byte in
# length, which happens to be the length of the shutdown checkpoint record.
#
# Insert rows, until we hit a location that's divisible by (8192 - 104 - 112)
# bytes. 104 is the length of the restore point record, and 112 is the length
# of a checkpoint record, after padding.
#
# Then we create the restore point, and write some more inserts while still
# on the old timeline.
#
# These lengths conspire so that when we restore to the restore point, and
# write a shutdown checkpoint record, the shutdown record on the new timeline
# ends at the same location as the first insert record on the old timeline.
# And that location is also a WAL page boundary.
$PGPATH/bin/psql postgres <<EOF
begin;
insert into foo select g, repeat('x', 46) from generate_series(1, 300000) g;
do \$\$
begin
  loop
    exit when pg_current_xlog_insert_location()::text like '%1F28';
    insert into foo values (1, repeat('y', 46));
  end loop;
end;
\$\$;
select pg_create_restore_point('between the many inserts');
insert into foo select g, repeat('x', 46) from generate_series(1, 400000) g;
commit;
EOF

$PGPATH/bin/pg_ctl -w -D data-master stop

# Recover to the restore point.
cat >> data-backup/recovery.conf <<EOF
recovery_target_name='between the many inserts'
restore_command='cp $PWD/walarchive/%f %p'
EOF
cat >> data-backup/postgresql.conf <<EOF
#hot_standby=on
log_line_prefix='S '
EOF

# Start the server, letting it recover to the restore point. Then kill the
# server. This creates a checkpoint record on the new timeline, but nothing
# else

$PGPATH/bin/pg_ctl -w -D data-backup start

$PGPATH/bin/pg_ctl -w -D data-backup stop -m immediate

# Restart the server again. This mistakenly tries to replay the WAL records
# copied from the old timeline, after the checkpoint record from the new
# timeline. That leads to a PANIC.
$PGPATH/bin/pg_ctl -D data-backup start

