On Fri, May 20, 2011 at 12:50 PM, Magnus Hagander <mag...@hagander.net> 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 (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to