On Fri, May 20, 2011 at 12:50 PM, Magnus Hagander <[email protected]> wrote:
>
> Yes. It might be useful to note it, and then ust make an override
> flag. My pointm, though, was that doing it for walreceiver is more
> important and a more logical first step.
>
ok, patch attached.
--
Jaime Casanova www.2ndQuadrant.com
Professional PostgreSQL: Soporte y capacitación de PostgreSQL
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..ca39654 100644
*** a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
--- b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
***************
*** 21,26 ****
--- 21,27 ----
#include "libpq-fe.h"
#include "access/xlog.h"
+ #include "access/xlog_internal.h"
#include "miscadmin.h"
#include "replication/walreceiver.h"
#include "utils/builtins.h"
*************** libpqrcv_connect(char *conninfo, XLogRec
*** 83,88 ****
--- 84,90 ----
char standby_sysid[32];
TimeLineID primary_tli;
TimeLineID standby_tli;
+ uint16 primary_xlp_magic;
PGresult *res;
char cmd[64];
*************** 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);
--- 116,122 ----
"the primary server: %s",
PQerrorMessage(streamConn))));
}
! if (PQnfields(res) != 4 || PQntuples(res) != 1)
{
int ntuples = PQntuples(res);
int nfields = PQnfields(res);
*************** libpqrcv_connect(char *conninfo, XLogRec
*** 127,133 ****
--- 129,137 ----
}
primary_sysid = PQgetvalue(res, 0, 0);
primary_tli = pg_atoi(PQgetvalue(res, 0, 1), 4, 0);
+ primary_xlp_magic = atoi(PQgetvalue(res, 0, 2));
+ PQclear(res);
/*
* Confirm that the system identifier of the primary is the same as ours.
*/
*************** libpqrcv_connect(char *conninfo, XLogRec
*** 135,141 ****
GetSystemIdentifier());
if (strcmp(primary_sysid, standby_sysid) != 0)
{
- PQclear(res);
ereport(ERROR,
(errmsg("database system identifier differs between the primary and standby"),
errdetail("The primary's identifier is %s, the standby's identifier is %s.",
--- 139,144 ----
*************** libpqrcv_connect(char *conninfo, XLogRec
*** 147,159 ****
* recovery target timeline.
*/
standby_tli = GetRecoveryTargetTLI();
- PQclear(res);
if (primary_tli != standby_tli)
ereport(ERROR,
(errmsg("timeline %u of the primary does not match recovery target timeline %u",
primary_tli, standby_tli)));
ThisTimeLineID = primary_tli;
/* Start streaming from the point requested by startup process */
snprintf(cmd, sizeof(cmd), "START_REPLICATION %X/%X",
startpoint.xlogid, startpoint.xrecoff);
--- 150,171 ----
* recovery target timeline.
*/
standby_tli = GetRecoveryTargetTLI();
if (primary_tli != standby_tli)
ereport(ERROR,
(errmsg("timeline %u of the primary does not match recovery target timeline %u",
primary_tli, standby_tli)));
ThisTimeLineID = primary_tli;
+ /*
+ * Check that the primary has a compatible XLOG_PAGE_MAGIC
+ */
+ if (primary_xlp_magic != XLOG_PAGE_MAGIC)
+ {
+ ereport(ERROR,
+ (errmsg("XLOG pages are not compatible between primary and standby"),
+ errhint("Verify PostgreSQL versions on both, primary and standby.")));
+ }
+
/* Start streaming from the point requested by startup process */
snprintf(cmd, sizeof(cmd), "START_REPLICATION %X/%X",
startpoint.xlogid, startpoint.xrecoff);
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);
--
Sent via pgsql-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers