1use strict;
2use warnings;
3use TestLib;
4use Test::More tests => 8;
5
6use FindBin;
7use lib $FindBin::RealBin;
8
9use RewindTest;
10
11sub run_test
12{
13	my $test_mode = shift;
14
15	RewindTest::setup_cluster();
16	RewindTest::start_master();
17
18	# Create a test table and insert a row in master.
19	master_psql("CREATE TABLE tbl1 (d text)");
20	master_psql("INSERT INTO tbl1 VALUES ('in master')");
21
22	# This test table will be used to test truncation, i.e. the table
23	# is extended in the old master after promotion
24	master_psql("CREATE TABLE trunc_tbl (d text)");
25	master_psql("INSERT INTO trunc_tbl VALUES ('in master')");
26
27	# This test table will be used to test the "copy-tail" case, i.e. the
28	# table is truncated in the old master after promotion
29	master_psql("CREATE TABLE tail_tbl (id integer, d text)");
30	master_psql("INSERT INTO tail_tbl VALUES (0, 'in master')");
31
32	master_psql("CHECKPOINT");
33
34	RewindTest::create_standby();
35
36	# Insert additional data on master that will be replicated to standby
37	master_psql("INSERT INTO tbl1 values ('in master, before promotion')");
38	master_psql(
39		"INSERT INTO trunc_tbl values ('in master, before promotion')");
40	master_psql(
41"INSERT INTO tail_tbl SELECT g, 'in master, before promotion: ' || g FROM generate_series(1, 10000) g"
42	);
43
44	master_psql('CHECKPOINT');
45
46	RewindTest::promote_standby();
47
48	# Insert a row in the old master. This causes the master and standby
49	# to have "diverged", it's no longer possible to just apply the
50	# standy's logs over master directory - you need to rewind.
51	master_psql("INSERT INTO tbl1 VALUES ('in master, after promotion')");
52
53	# Also insert a new row in the standby, which won't be present in the
54	# old master.
55	standby_psql("INSERT INTO tbl1 VALUES ('in standby, after promotion')");
56
57	# Insert enough rows to trunc_tbl to extend the file. pg_rewind should
58	# truncate it back to the old size.
59	master_psql(
60"INSERT INTO trunc_tbl SELECT 'in master, after promotion: ' || g FROM generate_series(1, 10000) g"
61	);
62
63	# Truncate tail_tbl. pg_rewind should copy back the truncated part
64	# (We cannot use an actual TRUNCATE command here, as that creates a
65	# whole new relfilenode)
66	master_psql("DELETE FROM tail_tbl WHERE id > 10");
67	master_psql("VACUUM tail_tbl");
68
69	RewindTest::run_pg_rewind($test_mode);
70
71	check_query(
72		'SELECT * FROM tbl1',
73		qq(in master
74in master, before promotion
75in standby, after promotion
76),
77		'table content');
78
79	check_query(
80		'SELECT * FROM trunc_tbl',
81		qq(in master
82in master, before promotion
83),
84		'truncation');
85
86	check_query(
87		'SELECT count(*) FROM tail_tbl',
88		qq(10001
89),
90		'tail-copy');
91
92	RewindTest::clean_rewind_test();
93}
94
95# Run the test in both modes
96run_test('local');
97run_test('remote');
98
99exit(0);
100