identify_system_xlogversion_v2.patch
text/x-patch
Filename: identify_system_xlogversion_v2.patch
Type: text/x-patch
Part: 0
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 v2
| File | + | − |
|---|---|---|
| doc/src/sgml/protocol.sgml | 0 | 0 |
| src/backend/replication/libpqwalreceiver/libpqwalreceiver.c | 0 | 0 |
| src/backend/replication/walsender.c | 0 | 0 |
| src/bin/pg_basebackup/pg_basebackup.c | 0 | 0 |
diff --git a/doc/src/sgml/protocol.sgml b/doc/src/sgml/protocol.sgml
index 6be5a14..2235c7f 100644
*** a/doc/src/sgml/protocol.sgml
--- b/doc/src/sgml/protocol.sgml
*************** The commands accepted in walsender mode
*** 1315,1321 ****
<listitem>
<para>
Requests the server to identify itself. Server replies with a result
! set of a single row, containing three fields:
</para>
<para>
--- 1315,1321 ----
<listitem>
<para>
Requests the server to identify itself. Server replies with a result
! set of a single row, containing four fields:
</para>
<para>
*************** The commands accepted in walsender mode
*** 1356,1361 ****
--- 1356,1372 ----
</para>
</listitem>
</varlistentry>
+
+ <varlistentry>
+ <term>
+ xlogversion
+ </term>
+ <listitem>
+ <para>
+ Current version of xlog page format.
+ </para>
+ </listitem>
+ </varlistentry>
</variablelist>
</para>
diff --git a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
index 0831b1b..7e7354b 100644
*** a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
--- b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
*************** libpqrcv_connect(char *conninfo, XLogRec
*** 114,120 ****
"the primary server: %s",
PQerrorMessage(streamConn))));
}
! if (PQnfields(res) != 3 || PQntuples(res) != 1)
{
int ntuples = PQntuples(res);
int nfields = PQnfields(res);
--- 114,120 ----
"the primary server: %s",
PQerrorMessage(streamConn))));
}
! if (PQnfields(res) != 4 || PQntuples(res) != 1)
{
int ntuples = PQntuples(res);
int nfields = PQnfields(res);
diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c
index 470e6d1..392cf94 100644
*** a/src/backend/replication/walsender.c
--- b/src/backend/replication/walsender.c
*************** IdentifySystem(void)
*** 279,289 ****
char sysid[32];
char tli[11];
char xpos[MAXFNAMELEN];
XLogRecPtr logptr;
/*
! * Reply with a result set with one row, three columns. First col is
! * system ID, second is timeline ID, and third is current xlog location.
*/
snprintf(sysid, sizeof(sysid), UINT64_FORMAT,
--- 279,291 ----
char sysid[32];
char tli[11];
char xpos[MAXFNAMELEN];
+ char xlp_magic[7];
XLogRecPtr logptr;
/*
! * Reply with a result set with one row, four columns. First col is
! * system ID, second is timeline ID, third is current xlog location
! * and fourth is XLOG_PAGE_MAGIC (WAL version)
*/
snprintf(sysid, sizeof(sysid), UINT64_FORMAT,
*************** IdentifySystem(void)
*** 295,303 ****
snprintf(xpos, sizeof(xpos), "%X/%X",
logptr.xlogid, logptr.xrecoff);
/* Send a RowDescription message */
pq_beginmessage(&buf, 'T');
! pq_sendint(&buf, 3, 2); /* 3 fields */
/* first field */
pq_sendstring(&buf, "systemid"); /* col name */
--- 297,307 ----
snprintf(xpos, sizeof(xpos), "%X/%X",
logptr.xlogid, logptr.xrecoff);
+ snprintf(xlp_magic, sizeof(xlp_magic), "%u", XLOG_PAGE_MAGIC);
+
/* Send a RowDescription message */
pq_beginmessage(&buf, 'T');
! pq_sendint(&buf, 4, 2); /* 4 fields */
/* first field */
pq_sendstring(&buf, "systemid"); /* col name */
*************** IdentifySystem(void)
*** 325,341 ****
pq_sendint(&buf, -1, 2);
pq_sendint(&buf, 0, 4);
pq_sendint(&buf, 0, 2);
pq_endmessage(&buf);
/* Send a DataRow message */
pq_beginmessage(&buf, 'D');
! pq_sendint(&buf, 3, 2); /* # of columns */
pq_sendint(&buf, strlen(sysid), 4); /* col1 len */
pq_sendbytes(&buf, (char *) &sysid, strlen(sysid));
pq_sendint(&buf, strlen(tli), 4); /* col2 len */
pq_sendbytes(&buf, (char *) tli, strlen(tli));
pq_sendint(&buf, strlen(xpos), 4); /* col3 len */
pq_sendbytes(&buf, (char *) xpos, strlen(xpos));
pq_endmessage(&buf);
--- 329,357 ----
pq_sendint(&buf, -1, 2);
pq_sendint(&buf, 0, 4);
pq_sendint(&buf, 0, 2);
+
+ /* fourth field */
+ pq_sendstring(&buf, "xlogversion");
+ pq_sendint(&buf, 0, 4);
+ pq_sendint(&buf, 0, 2);
+ pq_sendint(&buf, INT4OID, 4);
+ pq_sendint(&buf, 4, 2);
+ pq_sendint(&buf, 0, 4);
+ pq_sendint(&buf, 0, 2);
+
pq_endmessage(&buf);
/* Send a DataRow message */
pq_beginmessage(&buf, 'D');
! pq_sendint(&buf, 4, 2); /* # of columns */
pq_sendint(&buf, strlen(sysid), 4); /* col1 len */
pq_sendbytes(&buf, (char *) &sysid, strlen(sysid));
pq_sendint(&buf, strlen(tli), 4); /* col2 len */
pq_sendbytes(&buf, (char *) tli, strlen(tli));
pq_sendint(&buf, strlen(xpos), 4); /* col3 len */
pq_sendbytes(&buf, (char *) xpos, strlen(xpos));
+ pq_sendint(&buf, strlen(xlp_magic), 4); /* col4 len */
+ pq_sendbytes(&buf, (char *) xlp_magic, strlen(xlp_magic));
pq_endmessage(&buf);
diff --git a/src/bin/pg_basebackup/pg_basebackup.c b/src/bin/pg_basebackup/pg_basebackup.c
index 3feb3ee..7228edc 100644
*** a/src/bin/pg_basebackup/pg_basebackup.c
--- b/src/bin/pg_basebackup/pg_basebackup.c
***************
*** 11,17 ****
*-------------------------------------------------------------------------
*/
! #include "postgres_fe.h"
#include "libpq-fe.h"
#include <unistd.h>
--- 11,24 ----
*-------------------------------------------------------------------------
*/
! /*
! * We have to use postgres.h not postgres_fe.h here, because there's so much
! * backend-only stuff in the XLOG include files we need. But we need a
! * frontend-ish environment otherwise. Hence this ugly hack.
! */
! #define FRONTEND 1
!
! #include "postgres.h"
#include "libpq-fe.h"
#include <unistd.h>
***************
*** 24,29 ****
--- 31,38 ----
#include "getopt_long.h"
+ #include "access/xlog_internal.h"
+
/* Global options */
static const char *progname;
*************** static void
*** 756,761 ****
--- 765,771 ----
BaseBackup(void)
{
PGresult *res;
+ uint16 xlp_magic;
char current_path[MAXPGPATH];
char escaped_label[MAXPGPATH];
int i;
*************** BaseBackup(void)
*** 768,773 ****
--- 778,809 ----
conn = GetConnection();
/*
+ * Run IDENFITY_SYSTEM so we can get the XLOG_PAGE_MAGIC
+ */
+ res = PQexec(conn, "IDENTIFY_SYSTEM");
+ if (PQresultStatus(res) != PGRES_TUPLES_OK)
+ {
+ fprintf(stderr, _("%s: could not identify system: %s\n"),
+ progname, PQerrorMessage(conn));
+ disconnect_and_exit(1);
+ }
+ if (PQnfields(res) != 4 || PQntuples(res) != 1)
+ {
+ fprintf(stderr, _("%s: could not identify system, got %i rows with %i fields.\n"),
+ progname, PQntuples(res), PQnfields(res));
+ disconnect_and_exit(1);
+ }
+ xlp_magic = atoi(PQgetvalue(res, 0, 2));
+ PQclear(res);
+
+ if (xlp_magic != XLOG_PAGE_MAGIC)
+ {
+ fprintf(stderr, _("%s: could not identify system: XLOG pages are incompatible.\n"),
+ progname);
+ disconnect_and_exit(1);
+ }
+
+ /*
* Start the actual backup
*/
PQescapeStringConn(conn, escaped_label, label, sizeof(escaped_label), &i);