On Sun, May 15, 2011 at 6:03 PM, Jaime Casanova <ja...@2ndquadrant.com> wrote:
> On Thu, May 5, 2011 at 10:59 AM, Tom Lane <t...@sss.pgh.pa.us> wrote:
>> Magnus Hagander <mag...@hagander.net> writes:
>>>> So even if people don't believe in the rationale behind the patch,
>>>> would allowing it harm anything at this point?
>>
>>> Adding it for the sake of upgrades seems very far fetched.
>>
>>> Adding it for the sake of giving a better error message seems like a
>>> very good idea. But in that case, the client side code to actually
>>> give a better error message should be included from the start, IMHO.
>>
>> What's not apparent to me is how we'll even get to this check; if
>> there's a mismatch, won't the database system identifier comparison
>> fail first in most scenarios?
>>
>
> that's why i didn't propose that to begin with... but thinking on
> that, we can use it to add a message in pg_basebackup, maybe just a
> warning if we are taking a basebackup from an incompatible system...
>
> but for that i will need to add xlog_internal.h and postgres.h to
> pg_basebackup and use the "#define FRONTEND 1" hack we have in
> pg_resetxlog
>

attached, comments?

-- 
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..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);
-- 
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