Skip to content

Commit 9ec9225

Browse files
committed
PG-1213 Add function for checking if WAL record is encrypted
Add user function for checking if WAL record with given LSN is encrypted. Function assumes that provided LSN belongs to current timeline, however it allows to specify timeline ID as second argument.
1 parent 6ddc86c commit 9ec9225

File tree

10 files changed

+95
-5
lines changed

10 files changed

+95
-5
lines changed

contrib/pg_tde/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
PGFILEDESC = "pg_tde access method"
22
MODULE_big = pg_tde
33
EXTENSION = pg_tde
4-
DATA = pg_tde--1.0.sql
4+
DATA = pg_tde--1.0.sql pg_tde--1.0--2.0.sql
55

66
# Since meson supports skipping test suites this is a make only feature
77
ifndef TDE_MODE

contrib/pg_tde/expected/version.out

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ CREATE EXTENSION pg_tde;
22
SELECT pg_tde_version();
33
pg_tde_version
44
----------------
5-
pg_tde 1.0.0
5+
pg_tde 2.0.0
66
(1 row)
77

88
DROP EXTENSION pg_tde;

contrib/pg_tde/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ endif
7878
install_data(
7979
'pg_tde.control',
8080
'pg_tde--1.0.sql',
81+
'pg-tde--1.0--2.0.sql',
8182
kwargs: contrib_data_args,
8283
)
8384

contrib/pg_tde/pg_tde--1.0--2.0.sql

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
CREATE FUNCTION pg_tde_is_wal_record_encrypted(lsn pg_lsn, tli integer DEFAULT 0)
2+
RETURNS BOOLEAN
3+
LANGUAGE C
4+
AS 'MODULE_PATHNAME';
5+
REVOKE ALL ON FUNCTION pg_tde_is_wal_record_encrypted(pg_lsn, integer) FROM PUBLIC;

contrib/pg_tde/pg_tde.control

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
comment = 'pg_tde access method'
2-
default_version = '1.0'
2+
default_version = '2.0'
33
module_pathname = '$libdir/pg_tde'
44
relocatable = false

contrib/pg_tde/src/include/pg_tde.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
#define PG_TDE_H
33

44
#define PG_TDE_NAME "pg_tde"
5-
#define PG_TDE_VERSION "1.0.0"
5+
#define PG_TDE_VERSION "2.0.0"
66
#define PG_TDE_VERSION_STRING PG_TDE_NAME " " PG_TDE_VERSION
77

88
#define PG_TDE_DATA_DIR "pg_tde"

contrib/pg_tde/src/pg_tde.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,12 @@
1515
#include "storage/shmem.h"
1616
#include "utils/builtins.h"
1717
#include "utils/percona.h"
18+
#include "utils/pg_lsn.h"
1819

1920
#include "access/pg_tde_tdemap.h"
2021
#include "access/pg_tde_xlog.h"
2122
#include "access/pg_tde_xlog_smgr.h"
23+
#include "access/pg_tde_xlog_keys.h"
2224
#include "catalog/tde_global_space.h"
2325
#include "catalog/tde_principal_key.h"
2426
#include "encryption/enc_aes.h"
@@ -41,6 +43,7 @@ static shmem_request_hook_type prev_shmem_request_hook = NULL;
4143
PG_FUNCTION_INFO_V1(pg_tde_extension_initialize);
4244
PG_FUNCTION_INFO_V1(pg_tde_version);
4345
PG_FUNCTION_INFO_V1(pg_tdeam_handler);
46+
PG_FUNCTION_INFO_V1(pg_tde_is_wal_record_encrypted);
4447

4548
static void
4649
tde_shmem_request(void)
@@ -162,3 +165,39 @@ pg_tdeam_handler(PG_FUNCTION_ARGS)
162165
{
163166
PG_RETURN_POINTER(GetHeapamTableAmRoutine());
164167
}
168+
169+
/*
170+
* Returns true if the WAL record at the given LSN is encrypted.
171+
*/
172+
Datum
173+
pg_tde_is_wal_record_encrypted(PG_FUNCTION_ARGS)
174+
{
175+
XLogRecPtr lsn = PG_GETARG_LSN(0);
176+
int tli = PG_GETARG_INT32(1);
177+
WalLocation loc;
178+
WALKeyCacheRec *keys;
179+
180+
if (tli == 0)
181+
tli = GetWALInsertionTimeLine();
182+
183+
/* Load all keys for the given timeline */
184+
loc = (WalLocation)
185+
{
186+
.tli = tli,.lsn = 0
187+
};
188+
189+
keys = pg_tde_fetch_wal_keys(loc);
190+
if (!keys)
191+
PG_RETURN_BOOL(false);
192+
193+
loc.lsn = lsn;
194+
195+
for (WALKeyCacheRec *curr_key = keys; curr_key != NULL; curr_key = curr_key->next)
196+
{
197+
if (wal_location_cmp(loc, curr_key->start) >= 0 &&
198+
wal_location_cmp(loc, curr_key->end) < 0)
199+
PG_RETURN_BOOL(curr_key->key.type == WAL_KEY_TYPE_ENCRYPTED);
200+
}
201+
202+
PG_RETURN_BOOL(false);
203+
}

contrib/pg_tde/t/expected/basic.out

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ CREATE EXTENSION pg_tde;
2020
SELECT extname, extversion FROM pg_extension WHERE extname = 'pg_tde';
2121
extname | extversion
2222
---------+------------
23-
pg_tde | 1.0
23+
pg_tde | 2.0
2424
(1 row)
2525

2626
CREATE TABLE test_enc (id SERIAL, k INTEGER, PRIMARY KEY (id)) USING tde_heap;

contrib/pg_tde/t/expected/wal_encrypt.out

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@ SELECT key_name, provider_name, provider_id FROM pg_tde_server_key_info();
1313
| |
1414
(1 row)
1515

16+
SELECT pg_tde_is_wal_record_encrypted(pg_current_wal_lsn());
17+
pg_tde_is_wal_record_encrypted
18+
--------------------------------
19+
f
20+
(1 row)
21+
1622
SELECT pg_tde_create_key_using_global_key_provider('server-key', 'file-keyring-010');
1723
pg_tde_create_key_using_global_key_provider
1824
---------------------------------------------
@@ -53,6 +59,12 @@ SELECT slot_name FROM pg_create_logical_replication_slot('tde_slot', 'test_decod
5359

5460
CREATE TABLE test_wal (id SERIAL, k INTEGER, PRIMARY KEY (id));
5561
INSERT INTO test_wal (k) VALUES (1), (2);
62+
SELECT pg_tde_is_wal_record_encrypted(pg_current_wal_lsn());
63+
pg_tde_is_wal_record_encrypted
64+
--------------------------------
65+
t
66+
(1 row)
67+
5668
ALTER SYSTEM SET pg_tde.wal_encrypt = off;
5769
-- server restart without wal encryption
5870
SHOW pg_tde.wal_encrypt;
@@ -62,6 +74,12 @@ SHOW pg_tde.wal_encrypt;
6274
(1 row)
6375

6476
INSERT INTO test_wal (k) VALUES (3), (4);
77+
SELECT pg_tde_is_wal_record_encrypted(pg_current_wal_lsn());
78+
pg_tde_is_wal_record_encrypted
79+
--------------------------------
80+
f
81+
(1 row)
82+
6583
ALTER SYSTEM SET pg_tde.wal_encrypt = on;
6684
-- server restart with wal encryption
6785
SHOW pg_tde.wal_encrypt;
@@ -71,6 +89,12 @@ SHOW pg_tde.wal_encrypt;
7189
(1 row)
7290

7391
INSERT INTO test_wal (k) VALUES (5), (6);
92+
SELECT pg_tde_is_wal_record_encrypted(pg_current_wal_lsn());
93+
pg_tde_is_wal_record_encrypted
94+
--------------------------------
95+
t
96+
(1 row)
97+
7498
-- server restart with still wal encryption
7599
SHOW pg_tde.wal_encrypt;
76100
pg_tde.wal_encrypt
@@ -79,6 +103,12 @@ SHOW pg_tde.wal_encrypt;
79103
(1 row)
80104

81105
INSERT INTO test_wal (k) VALUES (7), (8);
106+
SELECT pg_tde_is_wal_record_encrypted('0/15883E8'::pg_lsn);
107+
pg_tde_is_wal_record_encrypted
108+
--------------------------------
109+
t
110+
(1 row)
111+
82112
SELECT data FROM pg_logical_slot_get_changes('tde_slot', NULL, NULL);
83113
data
84114
-----------------------------------------------------------

contrib/pg_tde/t/wal_encrypt.pl

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@
3131
'SELECT key_name, provider_name, provider_id FROM pg_tde_server_key_info();'
3232
);
3333

34+
PGTDE::psql($node, 'postgres',
35+
"SELECT pg_tde_is_wal_record_encrypted(pg_current_wal_lsn());");
36+
3437
PGTDE::psql($node, 'postgres',
3538
"SELECT pg_tde_create_key_using_global_key_provider('server-key', 'file-keyring-010');"
3639
);
@@ -60,6 +63,9 @@
6063

6164
PGTDE::psql($node, 'postgres', 'INSERT INTO test_wal (k) VALUES (1), (2);');
6265

66+
PGTDE::psql($node, 'postgres',
67+
"SELECT pg_tde_is_wal_record_encrypted(pg_current_wal_lsn());");
68+
6369
PGTDE::psql($node, 'postgres', 'ALTER SYSTEM SET pg_tde.wal_encrypt = off;');
6470

6571
PGTDE::append_to_result_file("-- server restart without wal encryption");
@@ -69,6 +75,9 @@
6975

7076
PGTDE::psql($node, 'postgres', 'INSERT INTO test_wal (k) VALUES (3), (4);');
7177

78+
PGTDE::psql($node, 'postgres',
79+
"SELECT pg_tde_is_wal_record_encrypted(pg_current_wal_lsn());");
80+
7281
PGTDE::psql($node, 'postgres', 'ALTER SYSTEM SET pg_tde.wal_encrypt = on;');
7382

7483
PGTDE::append_to_result_file("-- server restart with wal encryption");
@@ -78,13 +87,19 @@
7887

7988
PGTDE::psql($node, 'postgres', 'INSERT INTO test_wal (k) VALUES (5), (6);');
8089

90+
PGTDE::psql($node, 'postgres',
91+
"SELECT pg_tde_is_wal_record_encrypted(pg_current_wal_lsn());");
92+
8193
PGTDE::append_to_result_file("-- server restart with still wal encryption");
8294
$node->restart;
8395

8496
PGTDE::psql($node, 'postgres', "SHOW pg_tde.wal_encrypt;");
8597

8698
PGTDE::psql($node, 'postgres', 'INSERT INTO test_wal (k) VALUES (7), (8);');
8799

100+
PGTDE::psql($node, 'postgres',
101+
"SELECT pg_tde_is_wal_record_encrypted(pg_current_wal_lsn());");
102+
88103
PGTDE::psql($node, 'postgres',
89104
"SELECT data FROM pg_logical_slot_get_changes('tde_slot', NULL, NULL);");
90105

0 commit comments

Comments
 (0)