Skip to content

Commit 2b55cf9

Browse files
committed
PG-1411 Make pg_resetwal work with TDE
As pg_resetwal removes old WAL segments and creates new one with empty record we can do that write in unencrypted mode. However that requires new WAL key creation in case if encryption was enabled before.
1 parent f631753 commit 2b55cf9

File tree

4 files changed

+70
-1
lines changed

4 files changed

+70
-1
lines changed

src/bin/pg_resetwal/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
11
/pg_resetwal
22
/tmp_check/
3+
4+
# Source files copied from src/backend/access/transam/
5+
/xlogreader.c

src/bin/pg_resetwal/Makefile

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,23 @@ OBJS = \
2121
$(WIN32RES) \
2222
pg_resetwal.o
2323

24+
ifeq ($(enable_percona_ext),yes)
25+
override CPPFLAGS := -DFRONTEND $(CPPFLAGS)
26+
27+
OBJS += \
28+
$(top_srcdir)/src/fe_utils/simple_list.o \
29+
$(top_builddir)/src/libtde/libtdexlog.a \
30+
$(top_builddir)/src/libtde/libtde.a \
31+
xlogreader.o
32+
33+
override CPPFLAGS := -I$(top_srcdir)/contrib/pg_tde/src/include -I$(top_srcdir)/contrib/pg_tde/src/libkmip/libkmip/include $(CPPFLAGS)
34+
endif
35+
2436
all: pg_resetwal
2537

38+
xlogreader.c: % : $(top_srcdir)/src/backend/access/transam/%
39+
rm -f $@ && $(LN_S) $< .
40+
2641
pg_resetwal: $(OBJS) | submake-libpgport
2742
$(CC) $(CFLAGS) $^ $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $@$(X)
2843

@@ -36,7 +51,7 @@ uninstall:
3651
rm -f '$(DESTDIR)$(bindir)/pg_resetwal$(X)'
3752

3853
clean distclean:
39-
rm -f pg_resetwal$(X) $(OBJS)
54+
rm -f pg_resetwal$(X) $(OBJS) xlogreader.c
4055
rm -rf tmp_check
4156

4257
check:

src/bin/pg_resetwal/meson.build

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,22 @@ if host_system == 'windows'
1010
'--FILEDESC', 'pg_resetwal - reset PostgreSQL WAL log'])
1111
endif
1212

13+
link_w = []
14+
include_dirs = [postgres_inc]
15+
16+
if percona_ext == true
17+
link_w = [pg_tde_frontend]
18+
include_dirs = [postgres_inc, pg_tde_inc]
19+
pg_resetwal_sources += xlogreader_sources
20+
endif
21+
1322
pg_resetwal = executable('pg_resetwal',
1423
pg_resetwal_sources,
1524
dependencies: [frontend_code],
25+
c_args: ['-DFRONTEND'], # needed for xlogreader et al
1626
kwargs: default_bin_args,
27+
include_directories: include_dirs,
28+
link_with: link_w
1729
)
1830
bin_targets += pg_resetwal
1931

src/bin/pg_resetwal/pg_resetwal.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,13 @@
5959
#include "pg_getopt.h"
6060
#include "storage/large_object.h"
6161

62+
#ifdef PERCONA_EXT
63+
#include "pg_tde.h"
64+
#include "access/pg_tde_fe_init.h"
65+
#include "access/pg_tde_xlog_smgr.h"
66+
#include "access/xlog_smgr.h"
67+
#endif
68+
6269
static ControlFileData ControlFile; /* pg_control values */
6370
static XLogSegNo newXlogSegNo; /* new XLOG segment # */
6471
static bool guessed = false; /* T if we had to guess at any values */
@@ -344,6 +351,15 @@ main(int argc, char *argv[])
344351
}
345352
#endif
346353

354+
#ifdef PERCONA_EXT
355+
{
356+
char tde_path[MAXPGPATH];
357+
snprintf(tde_path, sizeof(tde_path), "%s/%s", DataDir, PG_TDE_DATA_DIR);
358+
pg_tde_fe_init(tde_path);
359+
TDEXLogSmgrInit();
360+
}
361+
#endif
362+
347363
get_restricted_token();
348364

349365
/* Set mask based on PGDATA permissions */
@@ -488,6 +504,18 @@ main(int argc, char *argv[])
488504
exit(1);
489505
}
490506

507+
#ifdef PERCONA_EXT
508+
/*
509+
* The only thing that WAL will contain after reset is a checkpoint, so we can
510+
* write it in unencrypted form. There are no sensitive data in it.
511+
*
512+
* We invoke this function here because we want to be sure that everything
513+
* is checked and ready for writing as this function will create new WAL key
514+
* if WAL encryption is enabled.
515+
*/
516+
TDEXLogSmgrInitWrite(false);
517+
#endif
518+
491519
/*
492520
* Else, do the dirty deed.
493521
*/
@@ -1134,14 +1162,25 @@ WriteEmptyXLOG(void)
11341162
pg_fatal("could not open file \"%s\": %m", path);
11351163

11361164
errno = 0;
1165+
#ifdef PERCONA_EXT
1166+
if (xlog_smgr->seg_write(fd, buffer.data, XLOG_BLCKSZ, 0,
1167+
ControlFile.checkPointCopy.ThisTimeLineID,
1168+
newXlogSegNo, WalSegSz) != XLOG_BLCKSZ)
1169+
#else
11371170
if (write(fd, buffer.data, XLOG_BLCKSZ) != XLOG_BLCKSZ)
1171+
#endif
11381172
{
11391173
/* if write didn't set errno, assume problem is no disk space */
11401174
if (errno == 0)
11411175
errno = ENOSPC;
11421176
pg_fatal("could not write file \"%s\": %m", path);
11431177
}
11441178

1179+
#ifdef PERCONA_EXT
1180+
/* If we used xlog smgr, we need to update the file offset */
1181+
lseek(fd, XLOG_BLCKSZ, SEEK_CUR);
1182+
#endif
1183+
11451184
/* Fill the rest of the file with zeroes */
11461185
memset(buffer.data, 0, XLOG_BLCKSZ);
11471186
for (nbytes = XLOG_BLCKSZ; nbytes < WalSegSz; nbytes += XLOG_BLCKSZ)

0 commit comments

Comments
 (0)