Attached patch adds some more "metadata" to walsender results:
* Adds the current xlog insert location as a third column in IDENTIFY_SYSTEM
* Adds a resultset at the start of a base backup that contains the
start xlog location (as returned by do_pg_start_backup)
* Adds a resultset at the end of a base backup that contains the end
xlog location (as returned by do_pg_stop_backup)
These are all information that's interesting for the "log receiver"
version of pg_basebackup (the changes to BASE_BACKUP) and the
pg_streamrecv program (the IDENTIFY_SYSTEM) once integrated.
I still haven't had the time to clean up those programs enough to
submit as a patch yet (it has progressed past that early post from a
month ago or so, but isn't done yet), but I wanted to make sure that
the backend parts gets reviewed and added as soon as possible. And
they're also quite trivial. That way if I don't find time to clean up
the streaming mode receiver in time for 9.1, it can be maintained
outside of the main tree until 9.2 - but the small backend changes
would still be required.
--
Magnus Hagander
Me: http://www.hagander.net/
Work: http://www.redpill-linpro.com/
diff --git a/doc/src/sgml/protocol.sgml b/doc/src/sgml/protocol.sgml
index 73c05ed..5e9b5d4 100644
--- a/doc/src/sgml/protocol.sgml
+++ b/doc/src/sgml/protocol.sgml
@@ -1315,7 +1315,7 @@ The commands accepted in walsender mode are:
<listitem>
<para>
Requests the server to identify itself. Server replies with a result
- set of a single row, containing two fields:
+ set of a single row, containing three fields:
</para>
<para>
@@ -1344,6 +1344,19 @@ The commands accepted in walsender mode are:
</para>
</listitem>
</varlistentry>
+
+ <varlistentry>
+ <term>
+ xlogpos
+ </term>
+ <listitem>
+ <para>
+ Current xlog write location. Useful to get a known location in the
+ transaction log where streaming can start.
+ </para>
+ </listitem>
+ </varlistentry>
+
</variablelist>
</para>
</listitem>
@@ -1520,15 +1533,16 @@ The commands accepted in walsender mode are:
</variablelist>
</para>
<para>
- When the backup is started, the server will first send a header in
- ordinary result set format, followed by one or more CopyResponse
- results, one for PGDATA and one for each additional tablespace other
- than <literal>pg_default</> and <literal>pg_global</>. The data in
- the CopyResponse results will be a tar format (using ustar00
- extensions) dump of the tablespace contents.
+ When the backup is started, the server will first send two
+ ordinary result sets, followed by one or more CopyResponse
+ results.
+ </para>
+ <para>
+ The first ordinary result set contains the starting position of the
+ backup, given in XLogRecPtr format as a single column in a single row.
</para>
<para>
- The header is an ordinary resultset with one row for each tablespace.
+ The second ordinary result set has one row for each tablespace.
The fields in this row are:
<variablelist>
<varlistentry>
@@ -1561,6 +1575,15 @@ The commands accepted in walsender mode are:
</variablelist>
</para>
<para>
+ After the two regular result set, one or more CopyResponse results
+ will be sent, one for PGDATA and one for each additional tablespace other
+ than <literal>pg_default</> and <literal>pg_global</>. The data in
+ the CopyResponse results will be a tar format (using ustar00
+ extensions) dump of the tablespace contents. After the tar data is
+ complete, a final ordinary result set will be sent.
+ </para>
+
+ <para>
The tar archive for the data directory and each tablespace will contain
all files in the directories, regardless of whether they are
<productname>PostgreSQL</> files or other files added to the same
@@ -1583,6 +1606,11 @@ The commands accepted in walsender mode are:
Owner, group and file mode are set if the underlying filesystem on
the server supports it.
</para>
+ <para>
+ Once all tablespaces have been sent, a final regular result set will
+ be sent. This result set contains the end position of the
+ backup, given in XLogRecPtr format as a single column in a single row.
+ </para>
</listitem>
</varlistentry>
</variablelist>
diff --git a/src/backend/replication/basebackup.c b/src/backend/replication/basebackup.c
index 29284a6..840d577 100644
--- a/src/backend/replication/basebackup.c
+++ b/src/backend/replication/basebackup.c
@@ -52,6 +52,7 @@ static void SendBackupHeader(List *tablespaces);
static void base_backup_cleanup(int code, Datum arg);
static void perform_base_backup(basebackup_options *opt, DIR *tblspcdir);
static void parse_basebackup_options(List *options, basebackup_options *opt);
+static void SendXlogRecPtrResult(XLogRecPtr ptr);
/*
* Size of each block sent into the tar stream for larger files.
@@ -92,6 +93,7 @@ perform_base_backup(basebackup_options *opt, DIR *tblspcdir)
char *labelfile;
startptr = do_pg_start_backup(opt->label, opt->fastcheckpoint, &labelfile);
+ SendXlogRecPtrResult(startptr);
PG_ENSURE_ERROR_CLEANUP(base_backup_cleanup, (Datum) 0);
{
@@ -239,6 +241,7 @@ perform_base_backup(basebackup_options *opt, DIR *tblspcdir)
/* Send CopyDone message for the last tar file */
pq_putemptymessage('c');
}
+ SendXlogRecPtrResult(endptr);
}
/*
@@ -432,6 +435,42 @@ SendBackupHeader(List *tablespaces)
}
/*
+ * Send a single resultset containing just a single
+ * XlogRecPtr record (in text format)
+ */
+static void
+SendXlogRecPtrResult(XLogRecPtr ptr)
+{
+ StringInfoData buf;
+ char str[MAXFNAMELEN];
+
+ snprintf(str, sizeof(str), "%X/%X", ptr.xlogid, ptr.xrecoff);
+
+ pq_beginmessage(&buf, 'T'); /* RowDescription */
+ pq_sendint(&buf, 1, 2); /* 1 field */
+
+ /* Field header */
+ pq_sendstring(&buf, "recptr");
+ pq_sendint(&buf, 0, 4); /* table oid */
+ pq_sendint(&buf, 0, 2); /* attnum */
+ pq_sendint(&buf, TEXTOID, 4); /* type oid */
+ pq_sendint(&buf, -1, 2);
+ pq_sendint(&buf, 0, 4);
+ pq_sendint(&buf, 0, 2);
+ pq_endmessage(&buf);
+
+ /* Data row */
+ pq_beginmessage(&buf, 'D');
+ pq_sendint(&buf, 1, 2); /* number of columns */
+ pq_sendint(&buf, strlen(str), 4); /* length */
+ pq_sendbytes(&buf, str, strlen(str));
+ pq_endmessage(&buf);
+
+ /* Send a CommandComplete message */
+ pq_puttextmessage('C', "SELECT");
+}
+
+/*
* Inject a file with given name and content in the output tar stream.
*/
static void
diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c
index f70458e..78963c1 100644
--- a/src/backend/replication/walsender.c
+++ b/src/backend/replication/walsender.c
@@ -258,19 +258,26 @@ IdentifySystem(void)
StringInfoData buf;
char sysid[32];
char tli[11];
+ char xpos[MAXFNAMELEN];
+ XLogRecPtr logptr;
/*
- * Reply with a result set with one row, two columns. First col is system
- * ID, and second is timeline ID
+ * 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,
GetSystemIdentifier());
snprintf(tli, sizeof(tli), "%u", ThisTimeLineID);
+ logptr = GetInsertRecPtr();
+
+ snprintf(xpos, sizeof(xpos), "%X/%X",
+ logptr.xlogid, logptr.xrecoff);
+
/* Send a RowDescription message */
pq_beginmessage(&buf, 'T');
- pq_sendint(&buf, 2, 2); /* 2 fields */
+ pq_sendint(&buf, 3, 2); /* 3 fields */
/* first field */
pq_sendstring(&buf, "systemid"); /* col name */
@@ -289,15 +296,27 @@ IdentifySystem(void)
pq_sendint(&buf, 4, 2); /* typlen */
pq_sendint(&buf, 0, 4); /* typmod */
pq_sendint(&buf, 0, 2); /* format code */
+
+ /* third field */
+ pq_sendstring(&buf, "xlogpos");
+ pq_sendint(&buf, 0, 4);
+ pq_sendint(&buf, 0, 2);
+ pq_sendint(&buf, TEXTOID, 4);
+ 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, 2, 2); /* # of columns */
+ 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);
/* Send CommandComplete and ReadyForQuery messages */
--
Sent via pgsql-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers