v1-0004-Add-function-to-make-pg_resetwal-to-support-TDE.patch
application/octet-stream
Filename: v1-0004-Add-function-to-make-pg_resetwal-to-support-TDE.patch
Type: application/octet-stream
Part: 1
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: unified
Series: patch v1-0004
| File | + | − |
|---|---|---|
| src/bin/pg_resetwal/compat.c | 125 | 0 |
| src/bin/pg_resetwal/Makefile | 10 | 2 |
| src/bin/pg_resetwal/pg_resetwal.c | 26 | 4 |
diff --git a/src/bin/pg_resetwal/Makefile b/src/bin/pg_resetwal/Makefile
index 2a38356..d3326b4 100644
--- a/src/bin/pg_resetwal/Makefile
+++ b/src/bin/pg_resetwal/Makefile
@@ -15,13 +15,21 @@ subdir = src/bin/pg_resetwal
top_builddir = ../../..
include $(top_builddir)/src/Makefile.global
-OBJS= pg_resetwal.o $(WIN32RES)
+OBJS= pg_resetwal.o compat.o $(ENCRYPTIONOBJS) $(WIN32RES)
+
+override CPPFLAGS := -DFRONTEND $(CPPFLAGS)
+
+ENCRYPTIONSOURCES = $(sort $(notdir $(wildcard $(top_srcdir)/src/backend/storage/encryption/*.c)))
+ENCRYPTIONOBJS = $(patsubst %.c,%.o,$(ENCRYPTIONSOURCES))
all: pg_resetwal
pg_resetwal: $(OBJS) | submake-libpgport
$(CC) $(CFLAGS) $^ $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $@$(X)
+$(ENCRYPTIONSOURCES): % : $(top_srcdir)/src/backend/storage/encryption/%
+ rm -f $@ && $(LN_S) $< .
+
install: all installdirs
$(INSTALL_PROGRAM) pg_resetwal$(X) '$(DESTDIR)$(bindir)/pg_resetwal$(X)'
@@ -32,7 +40,7 @@ uninstall:
rm -f '$(DESTDIR)$(bindir)/pg_resetwal$(X)'
clean distclean maintainer-clean:
- rm -f pg_resetwal$(X) $(OBJS)
+ rm -f pg_resetwal$(X) $(OBJS) $(ENCRYPTIONSOURCES)
rm -rf tmp_check
check:
diff --git a/src/bin/pg_resetwal/compat.c b/src/bin/pg_resetwal/compat.c
new file mode 100644
index 0000000..1555176
--- /dev/null
+++ b/src/bin/pg_resetwal/compat.c
@@ -0,0 +1,125 @@
+/*-------------------------------------------------------------------------
+ *
+ * compat.c
+ * Reimplementations of various backend functions.
+ *
+ * Portions Copyright (c) 2013-2019, PostgreSQL Global Development Group
+ *
+ * IDENTIFICATION
+ * src/bin/pg_waldump/compat.c
+ *
+ * This file contains client-side implementations for various backend
+ * functions that the rm_desc functions in *desc.c files rely on.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/* ugly hack, same as in e.g pg_controldata */
+#define FRONTEND 1
+#include "postgres.h"
+
+#include <time.h>
+
+#include "lib/stringinfo.h"
+#include "utils/datetime.h"
+#include "common/logging.h"
+
+/* copied from timestamp.c */
+pg_time_t
+timestamptz_to_time_t(TimestampTz t)
+{
+ pg_time_t result;
+
+ result = (pg_time_t) (t / USECS_PER_SEC +
+ ((POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * SECS_PER_DAY));
+ return result;
+}
+
+/*
+ * Stopgap implementation of timestamptz_to_str that doesn't depend on backend
+ * infrastructure. This will work for timestamps that are within the range
+ * of the platform time_t type. (pg_time_t is compatible except for possibly
+ * being wider.)
+ *
+ * XXX the return value points to a static buffer, so beware of using more
+ * than one result value concurrently.
+ *
+ * XXX: The backend timestamp infrastructure should instead be split out and
+ * moved into src/common. That's a large project though.
+ */
+const char *
+timestamptz_to_str(TimestampTz dt)
+{
+ static char buf[MAXDATELEN + 1];
+ char ts[MAXDATELEN + 1];
+ char zone[MAXDATELEN + 1];
+ time_t result = (time_t) timestamptz_to_time_t(dt);
+ struct tm *ltime = localtime(&result);
+
+ strftime(ts, sizeof(ts), "%Y-%m-%d %H:%M:%S", ltime);
+ strftime(zone, sizeof(zone), "%Z", ltime);
+
+ snprintf(buf, sizeof(buf), "%s.%06d %s",
+ ts, (int) (dt % USECS_PER_SEC), zone);
+
+ return buf;
+}
+
+/*
+ * Provide a hacked up compat layer for StringInfos so xlog desc functions can
+ * be linked/called.
+ */
+void
+initStringInfo(StringInfo str)
+{
+ int size = 1024; /* initial default buffer size */
+
+ str->data = (char *) palloc(size);
+ str->maxlen = size;
+ str->data[0] = '\0';
+ str->len = 0;
+ str->cursor = 0;
+}
+
+void
+appendStringInfo(StringInfo str, const char *fmt,...)
+{
+ va_list args;
+
+ va_start(args, fmt);
+ if (str)
+ {
+ int avail;
+ size_t nprinted;
+
+ avail = str->maxlen - str->len;
+ nprinted = pvsnprintf(str->data + str->len, (size_t) avail, fmt, args);
+
+ if (nprinted < (size_t) avail)
+ {
+ /* Success. Note nprinted does not include trailing null. */
+ str->len += (int) nprinted;
+ }
+ else
+ {
+ pg_log_error("the string is too long");
+ exit(1);
+ }
+
+ }
+ else
+ vprintf(fmt, args);
+ va_end(args);
+}
+
+void
+appendStringInfoString(StringInfo str, const char *string)
+{
+ appendStringInfo(str, "%s", string);
+}
+
+void
+appendStringInfoChar(StringInfo str, char ch)
+{
+ appendStringInfo(str, "%c", ch);
+}
diff --git a/src/bin/pg_resetwal/pg_resetwal.c b/src/bin/pg_resetwal/pg_resetwal.c
index c4ee016..c6273e6 100644
--- a/src/bin/pg_resetwal/pg_resetwal.c
+++ b/src/bin/pg_resetwal/pg_resetwal.c
@@ -58,6 +58,8 @@
#include "getopt_long.h"
#include "pg_getopt.h"
#include "storage/large_object.h"
+#include "catalog/pg_control.h"
+#include "storage/encryption.h"
static ControlFileData ControlFile; /* pg_control values */
static XLogSegNo newXlogSegNo; /* new XLOG segment # */
@@ -101,6 +103,7 @@ main(int argc, char *argv[])
{"dry-run", no_argument, NULL, 'n'},
{"next-oid", required_argument, NULL, 'o'},
{"multixact-offset", required_argument, NULL, 'O'},
+ {"cluster-passphrase-command", required_argument, NULL, 'p'},
{"next-transaction-id", required_argument, NULL, 'x'},
{"wal-segsize", required_argument, NULL, 1},
{NULL, 0, NULL, 0}
@@ -115,6 +118,7 @@ main(int argc, char *argv[])
char *DataDir = NULL;
char *log_fname = NULL;
int fd;
+ char *cluster_passphrase = NULL;
pg_logging_init(argv[0]);
set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_resetwal"));
@@ -135,7 +139,7 @@ main(int argc, char *argv[])
}
- while ((c = getopt_long(argc, argv, "c:D:e:fl:m:no:O:x:", long_options, NULL)) != -1)
+ while ((c = getopt_long(argc, argv, "c:D:e:fl:m:no:O:p:x:", long_options, NULL)) != -1)
{
switch (c)
{
@@ -277,6 +281,11 @@ main(int argc, char *argv[])
}
break;
+ case 'p':
+ {
+ cluster_passphrase = pg_strdup(optarg);
+ break;
+ }
case 'l':
if (strspn(optarg, "01234567890ABCDEFabcdef") != XLOG_FNAME_LEN)
{
@@ -390,6 +399,9 @@ main(int argc, char *argv[])
exit(1);
}
+ if (DataDir && cluster_passphrase)
+ getKmgr(DataDir, cluster_passphrase, progname);
+
/*
* Attempt to read the existing pg_control file
*/
@@ -1122,6 +1134,7 @@ WriteEmptyXLOG(void)
int fd;
int nbytes;
char *recptr;
+ char *buftowrite;
memset(buffer.data, 0, XLOG_BLCKSZ);
@@ -1157,6 +1170,13 @@ WriteEmptyXLOG(void)
FIN_CRC32C(crc);
record->xl_crc = crc;
+ if (DataEncryptionEnabled())
+ {
+ buftowrite = EncryptXLog(buffer.data, XLOG_BLCKSZ, newXlogSegNo, 0);
+ }
+ else
+ buftowrite = buffer.data;
+
/* Write the first page */
XLogFilePath(path, ControlFile.checkPointCopy.ThisTimeLineID,
newXlogSegNo, WalSegSz);
@@ -1172,7 +1192,7 @@ WriteEmptyXLOG(void)
}
errno = 0;
- if (write(fd, buffer.data, XLOG_BLCKSZ) != XLOG_BLCKSZ)
+ if (write(fd, buftowrite, XLOG_BLCKSZ) != XLOG_BLCKSZ)
{
/* if write didn't set errno, assume problem is no disk space */
if (errno == 0)
@@ -1182,11 +1202,11 @@ WriteEmptyXLOG(void)
}
/* Fill the rest of the file with zeroes */
- memset(buffer.data, 0, XLOG_BLCKSZ);
+ memset(buftowrite, 0, XLOG_BLCKSZ);
for (nbytes = XLOG_BLCKSZ; nbytes < WalSegSz; nbytes += XLOG_BLCKSZ)
{
errno = 0;
- if (write(fd, buffer.data, XLOG_BLCKSZ) != XLOG_BLCKSZ)
+ if (write(fd, buftowrite, XLOG_BLCKSZ) != XLOG_BLCKSZ)
{
if (errno == 0)
errno = ENOSPC;
@@ -1222,6 +1242,8 @@ usage(void)
printf(_(" -n, --dry-run no update, just show what would be done\n"));
printf(_(" -o, --next-oid=OID set next OID\n"));
printf(_(" -O, --multixact-offset=OFFSET set next multitransaction offset\n"));
+ printf(_(" -p --cluster-passphrase-command=COMMAND\n"
+ " set command to obtain passphrase for data encryption key\n"));
printf(_(" -V, --version output version information, then exit\n"));
printf(_(" -x, --next-transaction-id=XID set next transaction ID\n"));
printf(_(" --wal-segsize=SIZE size of WAL segments, in megabytes\n"));