Skip to content

Commit 9826c9f

Browse files
authored
Merge pull request #573 from dutow/pg2258
PG-2258: Create WAL principal key eagerly with default keys
2 parents 1ae37b1 + 388037f commit 9826c9f

2 files changed

Lines changed: 80 additions & 0 deletions

File tree

src/catalog/tde_principal_key.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -537,13 +537,30 @@ pg_tde_set_default_key_using_global_key_provider(PG_FUNCTION_ARGS)
537537
{
538538
char *principal_key_name = PG_ARGISNULL(0) ? NULL : text_to_cstring(PG_GETARG_TEXT_PP(0));
539539
char *provider_name = PG_ARGISNULL(1) ? NULL : text_to_cstring(PG_GETARG_TEXT_PP(1));
540+
bool need_server_key;
540541

541542
/* Using a global provider for the default encryption setting */
542543
pg_tde_set_principal_key_internal(GLOBAL_DATA_TDE_OID,
543544
DEFAULT_DATA_TDE_OID,
544545
principal_key_name,
545546
provider_name);
546547

548+
/*
549+
* Ensure a server (WAL) principal key exists so that operations needing
550+
* it (e.g. pg_basebackup -E) work without first restarting the server.
551+
* Without this, the server key is only materialized lazily during the
552+
* next startup when WAL encryption is initialized.
553+
*/
554+
LWLockAcquire(tde_lwlock_enc_keys(), LW_SHARED);
555+
need_server_key = (GetPrincipalKeyNoDefault(GLOBAL_DATA_TDE_OID, LW_SHARED) == NULL);
556+
LWLockRelease(tde_lwlock_enc_keys());
557+
558+
if (need_server_key)
559+
pg_tde_set_principal_key_internal(GLOBAL_DATA_TDE_OID,
560+
GLOBAL_DATA_TDE_OID,
561+
principal_key_name,
562+
provider_name);
563+
547564
PG_RETURN_VOID();
548565
}
549566

t/basebackup_default_key.pl

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
#!/usr/bin/perl
2+
3+
# Tests that pg_tde_basebackup -E works after setting just a default
4+
# principal key, without first restarting the primary. Before the fix,
5+
# the server (WAL) principal key was only materialized lazily on the
6+
# next server start, so taking an encrypted-WAL base backup of a freshly
7+
# configured cluster would fail with "could not find server principal key".
8+
9+
use strict;
10+
use warnings;
11+
use File::Basename;
12+
use Test::More;
13+
use PostgreSQL::Test::Cluster;
14+
use PostgreSQL::Test::Utils;
15+
use PostgreSQL::Test::RecursiveCopy;
16+
17+
my $keyfile = '/tmp/basebackup_default_key.per';
18+
unlink($keyfile);
19+
20+
my $primary = PostgreSQL::Test::Cluster->new('primary');
21+
$primary->init(allows_streaming => 1);
22+
$primary->append_conf('postgresql.conf',
23+
"shared_preload_libraries = 'pg_tde'");
24+
$primary->start;
25+
26+
$primary->safe_psql('postgres', 'CREATE EXTENSION pg_tde;');
27+
$primary->safe_psql('postgres',
28+
"SELECT pg_tde_add_global_key_provider_file('file-provider','$keyfile');"
29+
);
30+
$primary->safe_psql('postgres',
31+
"SELECT pg_tde_create_key_using_global_key_provider('key1','file-provider');"
32+
);
33+
$primary->safe_psql('postgres',
34+
"SELECT pg_tde_set_default_key_using_global_key_provider('key1','file-provider');"
35+
);
36+
37+
my $server_key = $primary->safe_psql('postgres',
38+
'SELECT key_name FROM pg_tde_server_key_info();');
39+
is($server_key, 'key1',
40+
'server principal key auto-configured when default key is set');
41+
42+
my $tempdir = PostgreSQL::Test::Utils::tempdir;
43+
my $backup_dir = "$tempdir/backup";
44+
45+
mkdir $backup_dir or die "mkdir $backup_dir failed: $!";
46+
PostgreSQL::Test::RecursiveCopy::copypath($primary->data_dir . '/pg_tde',
47+
$backup_dir . '/pg_tde');
48+
49+
$primary->command_ok(
50+
[
51+
'pg_tde_basebackup', '-D',
52+
$backup_dir, '-h',
53+
$primary->host, '-p',
54+
$primary->port, '--checkpoint',
55+
'fast', '--no-sync',
56+
'-E', '-X',
57+
'stream',
58+
],
59+
'pg_tde_basebackup -E succeeds after only setting default key');
60+
61+
$primary->stop;
62+
63+
done_testing();

0 commit comments

Comments
 (0)