Skip to content
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
2 changes: 2 additions & 0 deletions ci_scripts/perl/PostgreSQL/Test/TdeCluster.pm
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ my %wal_skip = (
'pg_basebackup without -E from server with encrypted WAL produces broken backups',
'src/bin/pg_combinebackup/t/006_db_file_copy.pl' =>
'pg_basebackup without -E from server with encrypted WAL produces broken backups',
'src/bin/pg_combinebackup/t/012_vm_consistency.pl' =>
'pg_basebackup without -E from server with encrypted WAL produces broken backups',
'src/bin/pg_rewind/t/001_basic.pl' =>
'copies WAL directly to archive without using archive_command',
'src/bin/pg_verifybackup/t/009_extract.pl' =>
Expand Down
1 change: 1 addition & 0 deletions documentation/docs/release-notes/release-notes-v2.2.2.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,4 @@ Changes introduced in `pg_tde` 2.2.2:
- [PG-2492](https://perconadev.atlassian.net/browse/PG-2492) - Fixed crash when empty certificate parameters are passed to `pg_tde_add_global_key_provider_kmip()` or `pg_tde_add_database_key_provider_kmip()`
- [PG-2608](https://perconadev.atlassian.net/browse/PG-2608) - Fixed a race condition in the Vault key provider that could occur when multiple processes accessed the same cURL handle after a fork.
- [PG-2609](https://perconadev.atlassian.net/browse/PG-2609) - Fixed WAL archiving (`pg_tde_archive_decrypt` and `pg_tde_restore_encrypt`) when pg_wal dir is a symlink.
- Include bugfixes for frontend tools from PostgreSQL 16.15, 17.11 and 18.5
16 changes: 10 additions & 6 deletions fetools/pg16/pg_basebackup/pg_recvlogical.c
Original file line number Diff line number Diff line change
Expand Up @@ -230,8 +230,9 @@ StreamLogicalLog(void)

/* Initiate the replication stream at specified location */
query = createPQExpBuffer();
appendPQExpBuffer(query, "START_REPLICATION SLOT \"%s\" LOGICAL %X/%X",
replication_slot, LSN_FORMAT_ARGS(startpos));
appendPQExpBufferStr(query, "START_REPLICATION SLOT ");
AppendQuotedIdentifier(query, replication_slot);
appendPQExpBuffer(query, " LOGICAL %X/%X", LSN_FORMAT_ARGS(startpos));

/* print options if there are any */
if (noptions)
Expand All @@ -244,11 +245,14 @@ StreamLogicalLog(void)
appendPQExpBufferStr(query, ", ");

/* write option name */
appendPQExpBuffer(query, "\"%s\"", options[(i * 2)]);
AppendQuotedIdentifier(query, options[i * 2]);

/* write option value if specified */
if (options[(i * 2) + 1] != NULL)
appendPQExpBuffer(query, " '%s'", options[(i * 2) + 1]);
if (options[i * 2 + 1] != NULL)
{
appendPQExpBufferChar(query, ' ');
AppendQuotedLiteral(query, options[i * 2 + 1]);
}
}

if (noptions)
Expand Down Expand Up @@ -327,7 +331,7 @@ StreamLogicalLog(void)
outfd = fileno(stdout);
else
outfd = open(outfile, O_CREAT | O_APPEND | O_WRONLY | PG_BINARY,
S_IRUSR | S_IWUSR);
pg_file_create_mode);
if (outfd == -1)
{
pg_log_error("could not open log file \"%s\": %m", outfile);
Expand Down
28 changes: 17 additions & 11 deletions fetools/pg16/pg_basebackup/receivelog.c
Original file line number Diff line number Diff line change
Expand Up @@ -457,8 +457,7 @@ CheckServerVersionForStreaming(PGconn *conn)
bool
ReceiveXlogStream(PGconn *conn, StreamCtl *stream)
{
char query[128];
char slotcmd[128];
PQExpBuffer query;
PGresult *res;
XLogRecPtr stoppos;

Expand All @@ -483,15 +482,13 @@ ReceiveXlogStream(PGconn *conn, StreamCtl *stream)
if (stream->replication_slot != NULL)
{
reportFlushPosition = true;
sprintf(slotcmd, "SLOT \"%s\" ", stream->replication_slot);
}
else
{
if (stream->synchronous)
reportFlushPosition = true;
else
reportFlushPosition = false;
slotcmd[0] = 0;
}

if (stream->sysidentifier != NULL)
Expand Down Expand Up @@ -540,8 +537,10 @@ ReceiveXlogStream(PGconn *conn, StreamCtl *stream)
*/
if (!existsTimeLineHistoryFile(stream))
{
snprintf(query, sizeof(query), "TIMELINE_HISTORY %u", stream->timeline);
res = PQexec(conn, query);
query = createPQExpBuffer();
appendPQExpBuffer(query, "TIMELINE_HISTORY %u", stream->timeline);
res = PQexec(conn, query->data);
destroyPQExpBuffer(query);
if (PQresultStatus(res) != PGRES_TUPLES_OK)
{
/* FIXME: we might send it ok, but get an error */
Expand Down Expand Up @@ -577,11 +576,18 @@ ReceiveXlogStream(PGconn *conn, StreamCtl *stream)
return true;

/* Initiate the replication stream at specified location */
snprintf(query, sizeof(query), "START_REPLICATION %s%X/%X TIMELINE %u",
slotcmd,
LSN_FORMAT_ARGS(stream->startpos),
stream->timeline);
res = PQexec(conn, query);
query = createPQExpBuffer();
appendPQExpBufferStr(query, "START_REPLICATION");
if (stream->replication_slot != NULL)
{
appendPQExpBufferStr(query, " SLOT ");
AppendQuotedIdentifier(query, stream->replication_slot);
}
appendPQExpBuffer(query, " %X/%X TIMELINE %u",
LSN_FORMAT_ARGS(stream->startpos),
stream->timeline);
res = PQexec(conn, query->data);
destroyPQExpBuffer(query);
if (PQresultStatus(res) != PGRES_COPY_BOTH)
{
pg_log_error("could not send replication command \"%s\": %s",
Expand Down
57 changes: 42 additions & 15 deletions fetools/pg16/pg_basebackup/streamutil.c
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,8 @@ GetSlotInformation(PGconn *conn, const char *slot_name,
*restart_tli = tli_loc;

query = createPQExpBuffer();
appendPQExpBuffer(query, "READ_REPLICATION_SLOT %s", slot_name);
appendPQExpBufferStr(query, "READ_REPLICATION_SLOT ");
AppendQuotedIdentifier(query, slot_name);
res = PQexec(conn, query->data);
destroyPQExpBuffer(query);

Expand Down Expand Up @@ -588,13 +589,17 @@ CreateReplicationSlot(PGconn *conn, const char *slot_name, const char *plugin,
Assert(slot_name != NULL);

/* Build base portion of query */
appendPQExpBuffer(query, "CREATE_REPLICATION_SLOT \"%s\"", slot_name);
appendPQExpBufferStr(query, "CREATE_REPLICATION_SLOT ");
AppendQuotedIdentifier(query, slot_name);
if (is_temporary)
appendPQExpBufferStr(query, " TEMPORARY");
if (is_physical)
appendPQExpBufferStr(query, " PHYSICAL");
else
appendPQExpBuffer(query, " LOGICAL \"%s\"", plugin);
{
appendPQExpBufferStr(query, " LOGICAL ");
AppendQuotedIdentifier(query, plugin);
}

/* Add any requested options */
if (use_new_option_syntax)
Expand Down Expand Up @@ -690,8 +695,8 @@ DropReplicationSlot(PGconn *conn, const char *slot_name)
query = createPQExpBuffer();

/* Build query */
appendPQExpBuffer(query, "DROP_REPLICATION_SLOT \"%s\"",
slot_name);
appendPQExpBufferStr(query, "DROP_REPLICATION_SLOT ");
AppendQuotedIdentifier(query, slot_name);
res = PQexec(conn, query->data);
if (PQresultStatus(res) != PGRES_COMMAND_OK)
{
Expand Down Expand Up @@ -719,6 +724,29 @@ DropReplicationSlot(PGconn *conn, const char *slot_name)
return true;
}

/*
* Append a suitably-quoted identifier or string literal to buf.
* "quote" should be either a double-quote or single-quote character.
*
* Caution: this quoting logic is sufficient for identifiers and literals
* in the replication grammar, but not always in regular SQL. Specifically,
* it'd fail for a string literal if standard_conforming_strings is off.
*/
void
AppendQuotedString(PQExpBuffer buf, const char *str, char quote)
{
appendPQExpBufferChar(buf, quote);
while (*str)
{
char c = *str++;

if (c == quote)
appendPQExpBufferChar(buf, c);
appendPQExpBufferChar(buf, c);
}
appendPQExpBufferChar(buf, quote);
}

/*
* Append a "plain" option - one with no value - to a server command that
* is being constructed.
Expand All @@ -727,10 +755,13 @@ DropReplicationSlot(PGconn *conn, const char *slot_name)
* write things like SOME_COMMAND OPTION1 OPTION2 'opt2value' OPTION3 42. The
* new syntax uses a comma-separated list surrounded by parentheses, so the
* equivalent is SOME_COMMAND (OPTION1, OPTION2 'optvalue', OPTION3 42).
*
* Note: we assume option names do not require quotes. Do not use this
* with option names coming from outside sources.
*/
void
AppendPlainCommandOption(PQExpBuffer buf, bool use_new_option_syntax,
char *option_name)
const char *option_name)
{
if (buf->len > 0 && buf->data[buf->len - 1] != '(')
{
Expand All @@ -751,30 +782,26 @@ AppendPlainCommandOption(PQExpBuffer buf, bool use_new_option_syntax,
*/
void
AppendStringCommandOption(PQExpBuffer buf, bool use_new_option_syntax,
char *option_name, char *option_value)
const char *option_name, const char *option_value)
{
AppendPlainCommandOption(buf, use_new_option_syntax, option_name);

if (option_value != NULL)
{
size_t length = strlen(option_value);
char *escaped_value = palloc(1 + 2 * length);

PQescapeStringConn(conn, escaped_value, option_value, length, NULL);
appendPQExpBuffer(buf, " '%s'", escaped_value);
pfree(escaped_value);
appendPQExpBufferChar(buf, ' ');
AppendQuotedLiteral(buf, option_value);
}
}

/*
* Append an option with an associated integer value to a server command
* Append an option with an associated integer value to a server command that
* is being constructed.
*
* See comments for AppendPlainCommandOption, above.
*/
void
AppendIntegerCommandOption(PQExpBuffer buf, bool use_new_option_syntax,
char *option_name, int32 option_value)
const char *option_name, int32 option_value)
{
AppendPlainCommandOption(buf, use_new_option_syntax, option_name);

Expand Down
11 changes: 8 additions & 3 deletions fetools/pg16/pg_basebackup/streamutil.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,20 @@ extern bool RunIdentifySystem(PGconn *conn, char **sysid,
XLogRecPtr *startpos,
char **db_name);

extern void AppendQuotedString(PQExpBuffer buf, const char *str, char quote);
#define AppendQuotedIdentifier(b, s) AppendQuotedString(b, s, '"')
#define AppendQuotedLiteral(b, s) AppendQuotedString(b, s, '\'')
extern void AppendPlainCommandOption(PQExpBuffer buf,
bool use_new_option_syntax,
char *option_name);
const char *option_name);
extern void AppendStringCommandOption(PQExpBuffer buf,
bool use_new_option_syntax,
char *option_name, char *option_value);
const char *option_name,
const char *option_value);
extern void AppendIntegerCommandOption(PQExpBuffer buf,
bool use_new_option_syntax,
char *option_name, int32 option_value);
const char *option_name,
int32 option_value);

extern bool GetSlotInformation(PGconn *conn, const char *slot_name,
XLogRecPtr *restart_lsn,
Expand Down
2 changes: 0 additions & 2 deletions fetools/pg17/pg_basebackup/pg_createsubscriber.c
Original file line number Diff line number Diff line change
Expand Up @@ -1402,7 +1402,6 @@ drop_replication_slot(PGconn *conn, struct LogicalRepInfo *dbinfo,
{
pg_log_error("could not drop replication slot \"%s\" in database \"%s\": %s",
slot_name, dbinfo->dbname, PQresultErrorMessage(res));
dbinfo->made_replslot = false; /* don't try again. */
}

PQclear(res);
Expand Down Expand Up @@ -1665,7 +1664,6 @@ drop_publication(PGconn *conn, struct LogicalRepInfo *dbinfo)
{
pg_log_error("could not drop publication \"%s\" in database \"%s\": %s",
dbinfo->pubname, dbinfo->dbname, PQresultErrorMessage(res));
dbinfo->made_publication = false; /* don't try again. */

/*
* Don't disconnect and exit here. This routine is used by primary
Expand Down
16 changes: 10 additions & 6 deletions fetools/pg17/pg_basebackup/pg_recvlogical.c
Original file line number Diff line number Diff line change
Expand Up @@ -242,8 +242,9 @@ StreamLogicalLog(void)

/* Initiate the replication stream at specified location */
query = createPQExpBuffer();
appendPQExpBuffer(query, "START_REPLICATION SLOT \"%s\" LOGICAL %X/%X",
replication_slot, LSN_FORMAT_ARGS(startpos));
appendPQExpBufferStr(query, "START_REPLICATION SLOT ");
AppendQuotedIdentifier(query, replication_slot);
appendPQExpBuffer(query, " LOGICAL %X/%X", LSN_FORMAT_ARGS(startpos));

/* print options if there are any */
if (noptions)
Expand All @@ -256,11 +257,14 @@ StreamLogicalLog(void)
appendPQExpBufferStr(query, ", ");

/* write option name */
appendPQExpBuffer(query, "\"%s\"", options[(i * 2)]);
AppendQuotedIdentifier(query, options[i * 2]);

/* write option value if specified */
if (options[(i * 2) + 1] != NULL)
appendPQExpBuffer(query, " '%s'", options[(i * 2) + 1]);
if (options[i * 2 + 1] != NULL)
{
appendPQExpBufferChar(query, ' ');
AppendQuotedLiteral(query, options[i * 2 + 1]);
}
}

if (noptions)
Expand Down Expand Up @@ -340,7 +344,7 @@ StreamLogicalLog(void)
outfd = fileno(stdout);
else
outfd = open(outfile, O_CREAT | O_APPEND | O_WRONLY | PG_BINARY,
S_IRUSR | S_IWUSR);
pg_file_create_mode);
if (outfd == -1)
{
pg_log_error("could not open log file \"%s\": %m", outfile);
Expand Down
28 changes: 17 additions & 11 deletions fetools/pg17/pg_basebackup/receivelog.c
Original file line number Diff line number Diff line change
Expand Up @@ -457,8 +457,7 @@ CheckServerVersionForStreaming(PGconn *conn)
bool
ReceiveXlogStream(PGconn *conn, StreamCtl *stream)
{
char query[128];
char slotcmd[128];
PQExpBuffer query;
PGresult *res;
XLogRecPtr stoppos;

Expand All @@ -483,15 +482,13 @@ ReceiveXlogStream(PGconn *conn, StreamCtl *stream)
if (stream->replication_slot != NULL)
{
reportFlushPosition = true;
sprintf(slotcmd, "SLOT \"%s\" ", stream->replication_slot);
}
else
{
if (stream->synchronous)
reportFlushPosition = true;
else
reportFlushPosition = false;
slotcmd[0] = 0;
}

if (stream->sysidentifier != NULL)
Expand Down Expand Up @@ -540,8 +537,10 @@ ReceiveXlogStream(PGconn *conn, StreamCtl *stream)
*/
if (!existsTimeLineHistoryFile(stream))
{
snprintf(query, sizeof(query), "TIMELINE_HISTORY %u", stream->timeline);
res = PQexec(conn, query);
query = createPQExpBuffer();
appendPQExpBuffer(query, "TIMELINE_HISTORY %u", stream->timeline);
res = PQexec(conn, query->data);
destroyPQExpBuffer(query);
if (PQresultStatus(res) != PGRES_TUPLES_OK)
{
/* FIXME: we might send it ok, but get an error */
Expand Down Expand Up @@ -577,11 +576,18 @@ ReceiveXlogStream(PGconn *conn, StreamCtl *stream)
return true;

/* Initiate the replication stream at specified location */
snprintf(query, sizeof(query), "START_REPLICATION %s%X/%X TIMELINE %u",
slotcmd,
LSN_FORMAT_ARGS(stream->startpos),
stream->timeline);
res = PQexec(conn, query);
query = createPQExpBuffer();
appendPQExpBufferStr(query, "START_REPLICATION");
if (stream->replication_slot != NULL)
{
appendPQExpBufferStr(query, " SLOT ");
AppendQuotedIdentifier(query, stream->replication_slot);
}
appendPQExpBuffer(query, " %X/%X TIMELINE %u",
LSN_FORMAT_ARGS(stream->startpos),
stream->timeline);
res = PQexec(conn, query->data);
destroyPQExpBuffer(query);
if (PQresultStatus(res) != PGRES_COPY_BOTH)
{
pg_log_error("could not send replication command \"%s\": %s",
Expand Down
Loading
Loading