Skip to content

Commit 014e977

Browse files
committed
Add crash recovery tests
Tests to trigger redo routines after the server crash. It mostly checks invariants when different redo functions might rewrite WAL keys created on the init stage. For PG-1539, PG-1541, PG-1468, PG-1413
1 parent a0c6e3d commit 014e977

File tree

3 files changed

+172
-0
lines changed

3 files changed

+172
-0
lines changed

contrib/pg_tde/meson.build

+1
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ tap_tests = [
114114
't/010_change_key_provider.pl',
115115
't/011_unlogged_tables.pl',
116116
't/012_replication.pl',
117+
't/013_crash_recovery.pl',
117118
]
118119

119120
tests += {
+94
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
#!/usr/bin/perl
2+
3+
use strict;
4+
use warnings;
5+
use File::Basename;
6+
use Test::More;
7+
use lib 't';
8+
use pgtde;
9+
10+
PGTDE::setup_files_dir(basename($0));
11+
12+
my $node = PostgreSQL::Test::Cluster->new('main');
13+
$node->init;
14+
$node->append_conf(
15+
'postgresql.conf', q{
16+
checkpoint_timeout = 1h
17+
shared_preload_libraries = 'pg_tde'
18+
});
19+
$node->start;
20+
21+
PGTDE::psql($node, 'postgres', 'CREATE EXTENSION IF NOT EXISTS pg_tde;');
22+
PGTDE::psql($node, 'postgres',
23+
"SELECT pg_tde_add_global_key_provider_file('global_keyring', '/tmp/crash_recovery.per');"
24+
);
25+
PGTDE::psql($node, 'postgres',
26+
"SELECT pg_tde_set_server_key_using_global_key_provider('wal_encryption_key', 'global_keyring');"
27+
);
28+
PGTDE::psql($node, 'postgres',
29+
"SELECT pg_tde_add_database_key_provider_file('db_keyring', '/tmp/crash_recovery.per');"
30+
);
31+
PGTDE::psql($node, 'postgres',
32+
"SELECT pg_tde_set_key_using_database_key_provider('db_key', 'db_keyring');"
33+
);
34+
35+
PGTDE::psql($node, 'postgres',
36+
"CREATE TABLE test_enc (x int PRIMARY KEY) USING tde_heap;");
37+
PGTDE::psql($node, 'postgres', "INSERT INTO test_enc (x) VALUES (1), (2);");
38+
39+
PGTDE::psql($node, 'postgres',
40+
"CREATE TABLE test_plain (x int PRIMARY KEY) USING heap;");
41+
PGTDE::psql($node, 'postgres', "INSERT INTO test_plain (x) VALUES (3), (4);");
42+
43+
PGTDE::psql($node, 'postgres', "ALTER SYSTEM SET pg_tde.wal_encrypt = 'on';");
44+
45+
PGTDE::append_to_result_file("-- kill -9");
46+
$node->kill9;
47+
48+
PGTDE::append_to_result_file("-- server start");
49+
$node->start;
50+
51+
PGTDE::append_to_result_file("-- rotate wal key");
52+
PGTDE::psql($node, 'postgres',
53+
"SELECT pg_tde_set_server_key_using_global_key_provider('wal_encryption_key_1', 'global_keyring', true);"
54+
);
55+
PGTDE::psql($node, 'postgres',
56+
"SELECT pg_tde_set_key_using_database_key_provider('db_key_1', 'db_keyring');"
57+
);
58+
PGTDE::psql($node, 'postgres', "INSERT INTO test_enc (x) VALUES (3), (4);");
59+
PGTDE::append_to_result_file("-- kill -9");
60+
$node->kill9;
61+
PGTDE::append_to_result_file("-- server start");
62+
PGTDE::append_to_result_file(
63+
"-- check that pg_tde_save_principal_key_redo hasn't destroyed a WAL key created during the server start"
64+
);
65+
$node->start;
66+
67+
PGTDE::append_to_result_file("-- rotate wal key");
68+
PGTDE::psql($node, 'postgres',
69+
"SELECT pg_tde_set_server_key_using_global_key_provider('wal_encryption_key_2', 'global_keyring', true);"
70+
);
71+
PGTDE::psql($node, 'postgres',
72+
"SELECT pg_tde_set_key_using_database_key_provider('db_key_2', 'db_keyring');"
73+
);
74+
PGTDE::psql($node, 'postgres', "INSERT INTO test_enc (x) VALUES (5), (6);");
75+
PGTDE::append_to_result_file("-- kill -9");
76+
$node->kill9;
77+
PGTDE::append_to_result_file("-- server start");
78+
PGTDE::append_to_result_file(
79+
"-- check that the key rotation hasn't destroyed a WAL key created during the server start"
80+
);
81+
$node->start;
82+
83+
PGTDE::psql($node, 'postgres', "TABLE test_enc;");
84+
85+
$node->stop;
86+
87+
# Compare the expected and out file
88+
my $compare = PGTDE->compare_results();
89+
90+
is($compare, 0,
91+
"Compare Files: $PGTDE::expected_filename_with_path and $PGTDE::out_filename_with_path files."
92+
);
93+
94+
done_testing();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
CREATE EXTENSION IF NOT EXISTS pg_tde;
2+
SELECT pg_tde_add_global_key_provider_file('global_keyring', '/tmp/crash_recovery.per');
3+
pg_tde_add_global_key_provider_file
4+
-------------------------------------
5+
-1
6+
(1 row)
7+
8+
SELECT pg_tde_set_server_key_using_global_key_provider('wal_encryption_key', 'global_keyring');
9+
pg_tde_set_server_key_using_global_key_provider
10+
-------------------------------------------------
11+
12+
(1 row)
13+
14+
SELECT pg_tde_add_database_key_provider_file('db_keyring', '/tmp/crash_recovery.per');
15+
pg_tde_add_database_key_provider_file
16+
---------------------------------------
17+
1
18+
(1 row)
19+
20+
SELECT pg_tde_set_key_using_database_key_provider('db_key', 'db_keyring');
21+
pg_tde_set_key_using_database_key_provider
22+
--------------------------------------------
23+
24+
(1 row)
25+
26+
CREATE TABLE test_enc (x int PRIMARY KEY) USING tde_heap;
27+
INSERT INTO test_enc (x) VALUES (1), (2);
28+
CREATE TABLE test_plain (x int PRIMARY KEY) USING heap;
29+
INSERT INTO test_plain (x) VALUES (3), (4);
30+
ALTER SYSTEM SET pg_tde.wal_encrypt = 'on';
31+
-- kill -9
32+
-- server start
33+
-- rotate wal key
34+
SELECT pg_tde_set_server_key_using_global_key_provider('wal_encryption_key_1', 'global_keyring', true);
35+
pg_tde_set_server_key_using_global_key_provider
36+
-------------------------------------------------
37+
38+
(1 row)
39+
40+
SELECT pg_tde_set_key_using_database_key_provider('db_key_1', 'db_keyring');
41+
pg_tde_set_key_using_database_key_provider
42+
--------------------------------------------
43+
44+
(1 row)
45+
46+
INSERT INTO test_enc (x) VALUES (3), (4);
47+
-- kill -9
48+
-- server start
49+
-- check that pg_tde_save_principal_key_redo hasn't destroyed a WAL key created during the server start
50+
-- rotate wal key
51+
SELECT pg_tde_set_server_key_using_global_key_provider('wal_encryption_key_2', 'global_keyring', true);
52+
pg_tde_set_server_key_using_global_key_provider
53+
-------------------------------------------------
54+
55+
(1 row)
56+
57+
SELECT pg_tde_set_key_using_database_key_provider('db_key_2', 'db_keyring');
58+
pg_tde_set_key_using_database_key_provider
59+
--------------------------------------------
60+
61+
(1 row)
62+
63+
INSERT INTO test_enc (x) VALUES (5), (6);
64+
-- kill -9
65+
-- server start
66+
-- check that the key rotation hasn't destroyed a WAL key created during the server start
67+
TABLE test_enc;
68+
x
69+
---
70+
1
71+
2
72+
3
73+
4
74+
5
75+
6
76+
(6 rows)
77+

0 commit comments

Comments
 (0)