On Tue, May 24, 2011 at 8:52 PM, Fujii Masao <masao.fu...@gmail.com> wrote:

> +       primary_xlp_magic = atoi(PQgetvalue(res, 0, 2));
>
> You wrongly get the third field (i.e., current xlog location) as the
> WAL version.
> You should call PQgetvalue(res, 0, 3), instead.
>
>> errdetail("Expected 1 tuple with 3 fields, got %d tuples with %d fields.",
>
> You need to change the above message.
>

Fixed.

About you comments on the check... if you read the thread, you will
find that the whole reason for the field is future improvement, but
everyone wanted some use of the field now... so i made a patch to use
it in pg_basebackup before the transfer starts and avoid time and
bandwith waste but Magnus prefer this in walreceiver...

-- 
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..c3f3571 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
*** 122,133 ****
  		PQclear(res);
  		ereport(ERROR,
  				(errmsg("invalid response from primary server"),
! 				 errdetail("Expected 1 tuple with 3 fields, got %d tuples with %d fields.",
  						   ntuples, nfields)));
  	}
  	primary_sysid = PQgetvalue(res, 0, 0);
  	primary_tli = pg_atoi(PQgetvalue(res, 0, 1), 4, 0);
  
  	/*
  	 * Confirm that the system identifier of the primary is the same as ours.
  	 */
--- 124,137 ----
  		PQclear(res);
  		ereport(ERROR,
  				(errmsg("invalid response from primary server"),
! 				 errdetail("Expected 1 tuple with 4 fields, got %d tuples with %d fields.",
  						   ntuples, nfields)));
  	}
  	primary_sysid = PQgetvalue(res, 0, 0);
  	primary_tli = pg_atoi(PQgetvalue(res, 0, 1), 4, 0);
+  	primary_xlp_magic = atoi(PQgetvalue(res, 0, 3));
  
+ 	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