Skip to content

Don't rewrite _map files on the save_principal_key redo #217

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions contrib/pg_tde/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ tap_tests = [
't/010_change_key_provider.pl',
't/011_unlogged_tables.pl',
't/012_replication.pl',
't/013_crash_recovery.pl',
]

tests += {
Expand Down
2 changes: 1 addition & 1 deletion contrib/pg_tde/src/access/pg_tde_tdemap.c
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ pg_tde_save_principal_key_redo(const TDESignedPrincipalKeyInfo *signed_key_info)

LWLockAcquire(tde_lwlock_enc_keys(), LW_EXCLUSIVE);

map_fd = pg_tde_open_file_write(db_map_path, signed_key_info, true, &curr_pos);
map_fd = pg_tde_open_file_write(db_map_path, signed_key_info, false, &curr_pos);
close(map_fd);

LWLockRelease(tde_lwlock_enc_keys());
Expand Down
94 changes: 94 additions & 0 deletions contrib/pg_tde/t/013_crash_recovery.pl
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
#!/usr/bin/perl

use strict;
use warnings;
use File::Basename;
use Test::More;
use lib 't';
use pgtde;

PGTDE::setup_files_dir(basename($0));

my $node = PostgreSQL::Test::Cluster->new('main');
$node->init;
$node->append_conf(
'postgresql.conf', q{
checkpoint_timeout = 1h
shared_preload_libraries = 'pg_tde'
});
$node->start;

PGTDE::psql($node, 'postgres', 'CREATE EXTENSION IF NOT EXISTS pg_tde;');
PGTDE::psql($node, 'postgres',
"SELECT pg_tde_add_global_key_provider_file('global_keyring', '/tmp/crash_recovery.per');"
);
PGTDE::psql($node, 'postgres',
"SELECT pg_tde_set_server_key_using_global_key_provider('wal_encryption_key', 'global_keyring');"
);
PGTDE::psql($node, 'postgres',
"SELECT pg_tde_add_database_key_provider_file('db_keyring', '/tmp/crash_recovery.per');"
);
PGTDE::psql($node, 'postgres',
"SELECT pg_tde_set_key_using_database_key_provider('db_key', 'db_keyring');"
);

PGTDE::psql($node, 'postgres',
"CREATE TABLE test_enc (x int PRIMARY KEY) USING tde_heap;");
PGTDE::psql($node, 'postgres', "INSERT INTO test_enc (x) VALUES (1), (2);");

PGTDE::psql($node, 'postgres',
"CREATE TABLE test_plain (x int PRIMARY KEY) USING heap;");
PGTDE::psql($node, 'postgres', "INSERT INTO test_plain (x) VALUES (3), (4);");

PGTDE::psql($node, 'postgres', "ALTER SYSTEM SET pg_tde.wal_encrypt = 'on';");

PGTDE::append_to_result_file("-- kill -9");
$node->kill9;

PGTDE::append_to_result_file("-- server start");
$node->start;

PGTDE::append_to_result_file("-- rotate wal key");
PGTDE::psql($node, 'postgres',
"SELECT pg_tde_set_server_key_using_global_key_provider('wal_encryption_key_1', 'global_keyring', true);"
);
PGTDE::psql($node, 'postgres',
"SELECT pg_tde_set_key_using_database_key_provider('db_key_1', 'db_keyring');"
);
PGTDE::psql($node, 'postgres', "INSERT INTO test_enc (x) VALUES (3), (4);");
PGTDE::append_to_result_file("-- kill -9");
$node->kill9;
PGTDE::append_to_result_file("-- server start");
PGTDE::append_to_result_file(
"-- check that pg_tde_save_principal_key_redo hasn't destroyed a WAL key created during the server start"
);
$node->start;

PGTDE::append_to_result_file("-- rotate wal key");
PGTDE::psql($node, 'postgres',
"SELECT pg_tde_set_server_key_using_global_key_provider('wal_encryption_key_2', 'global_keyring', true);"
);
PGTDE::psql($node, 'postgres',
"SELECT pg_tde_set_key_using_database_key_provider('db_key_2', 'db_keyring');"
);
PGTDE::psql($node, 'postgres', "INSERT INTO test_enc (x) VALUES (5), (6);");
PGTDE::append_to_result_file("-- kill -9");
$node->kill9;
PGTDE::append_to_result_file("-- server start");
PGTDE::append_to_result_file(
"-- check that the key rotation hasn't destroyed a WAL key created during the server start"
);
$node->start;

PGTDE::psql($node, 'postgres', "TABLE test_enc;");

$node->stop;

# Compare the expected and out file
my $compare = PGTDE->compare_results();

is($compare, 0,
"Compare Files: $PGTDE::expected_filename_with_path and $PGTDE::out_filename_with_path files."
);

done_testing();
77 changes: 77 additions & 0 deletions contrib/pg_tde/t/expected/013_crash_recovery.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
CREATE EXTENSION IF NOT EXISTS pg_tde;
SELECT pg_tde_add_global_key_provider_file('global_keyring', '/tmp/crash_recovery.per');
pg_tde_add_global_key_provider_file
-------------------------------------
-1
(1 row)

SELECT pg_tde_set_server_key_using_global_key_provider('wal_encryption_key', 'global_keyring');
pg_tde_set_server_key_using_global_key_provider
-------------------------------------------------

(1 row)

SELECT pg_tde_add_database_key_provider_file('db_keyring', '/tmp/crash_recovery.per');
pg_tde_add_database_key_provider_file
---------------------------------------
1
(1 row)

SELECT pg_tde_set_key_using_database_key_provider('db_key', 'db_keyring');
pg_tde_set_key_using_database_key_provider
--------------------------------------------

(1 row)

CREATE TABLE test_enc (x int PRIMARY KEY) USING tde_heap;
INSERT INTO test_enc (x) VALUES (1), (2);
CREATE TABLE test_plain (x int PRIMARY KEY) USING heap;
INSERT INTO test_plain (x) VALUES (3), (4);
ALTER SYSTEM SET pg_tde.wal_encrypt = 'on';
-- kill -9
-- server start
-- rotate wal key
SELECT pg_tde_set_server_key_using_global_key_provider('wal_encryption_key_1', 'global_keyring', true);
pg_tde_set_server_key_using_global_key_provider
-------------------------------------------------

(1 row)

SELECT pg_tde_set_key_using_database_key_provider('db_key_1', 'db_keyring');
pg_tde_set_key_using_database_key_provider
--------------------------------------------

(1 row)

INSERT INTO test_enc (x) VALUES (3), (4);
-- kill -9
-- server start
-- check that pg_tde_save_principal_key_redo hasn't destroyed a WAL key created during the server start
-- rotate wal key
SELECT pg_tde_set_server_key_using_global_key_provider('wal_encryption_key_2', 'global_keyring', true);
pg_tde_set_server_key_using_global_key_provider
-------------------------------------------------

(1 row)

SELECT pg_tde_set_key_using_database_key_provider('db_key_2', 'db_keyring');
pg_tde_set_key_using_database_key_provider
--------------------------------------------

(1 row)

INSERT INTO test_enc (x) VALUES (5), (6);
-- kill -9
-- server start
-- check that the key rotation hasn't destroyed a WAL key created during the server start
TABLE test_enc;
x
---
1
2
3
4
5
6
(6 rows)