Hi,
I prepared a patch which adds a timestamp into a XLOG_BACKUP_END
WAL-record. This functionality is needed in practice when we have to
determine a recovery time of specific backup.
This code developed in compatibility with WAL segments, which do not
have a timestamp in a XLOG_BACKUP_END record.
--
Andrey Lepikhov
Postgres Professional:
https://postgrespro.com
The Russian Postgres Company
>From 8852a64156e7726bae11c1904b142c9b157cf654 Mon Sep 17 00:00:00 2001
From: "Andrey V. Lepikhov" <a.lepik...@postgrespro.ru>
Date: Mon, 9 Jul 2018 10:57:10 +0500
Subject: [PATCH] BACKUP_END timestamp addition
---
src/backend/access/rmgrdesc/xlogdesc.c | 14 +++++++++++++-
src/backend/access/transam/xlog.c | 7 +++++--
src/include/access/xlog_internal.h | 7 +++++++
3 files changed, 25 insertions(+), 3 deletions(-)
diff --git a/src/backend/access/rmgrdesc/xlogdesc.c b/src/backend/access/rmgrdesc/xlogdesc.c
index 00741c7..5a0d61a 100644
--- a/src/backend/access/rmgrdesc/xlogdesc.c
+++ b/src/backend/access/rmgrdesc/xlogdesc.c
@@ -87,7 +87,19 @@ xlog_desc(StringInfo buf, XLogReaderState *record)
XLogRecPtr startpoint;
memcpy(&startpoint, rec, sizeof(XLogRecPtr));
- appendStringInfo(buf, "%X/%X",
+ /* Check for the format of WAL-record with timestamp */
+ if (XLogRecGetDataLen(record) >= sizeof(xl_backup_end))
+ {
+ TimestampTz timestamp;
+
+ memcpy(×tamp, &((xl_backup_end *)rec)->timestamp, sizeof(TimestampTz));
+ appendStringInfo(buf, "%X/%X; timestamp: %s",
+ (uint32) (startpoint >> 32), (uint32) startpoint,
+ timestamptz_to_str(timestamp));
+ }
+ else
+ /* WAL-record not have a timestamp */
+ appendStringInfo(buf, "%X/%X; <no timestamp>",
(uint32) (startpoint >> 32), (uint32) startpoint);
}
else if (info == XLOG_PARAMETER_CHANGE)
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 44017d3..12a5eb6 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -9950,7 +9950,7 @@ xlog_redo(XLogReaderState *record)
{
XLogRecPtr startpoint;
- memcpy(&startpoint, XLogRecGetData(record), sizeof(startpoint));
+ memcpy(&startpoint, &((xl_backup_end *)XLogRecGetData(record))->startpoint, sizeof(startpoint));
if (ControlFile->backupStartPoint == startpoint)
{
@@ -11069,11 +11069,14 @@ do_pg_stop_backup(char *labelfile, bool waitforarchive, TimeLineID *stoptli_p)
}
else
{
+ xl_backup_end xlrec;
/*
* Write the backup-end xlog record
*/
XLogBeginInsert();
- XLogRegisterData((char *) (&startpoint), sizeof(startpoint));
+ xlrec.startpoint = startpoint;
+ xlrec.timestamp = GetCurrentTimestamp();
+ XLogRegisterData((char *) (&xlrec), sizeof(xl_backup_end));
stoppoint = XLogInsert(RM_XLOG_ID, XLOG_BACKUP_END);
stoptli = ThisTimeLineID;
diff --git a/src/include/access/xlog_internal.h b/src/include/access/xlog_internal.h
index 7c76683..8c5d851 100644
--- a/src/include/access/xlog_internal.h
+++ b/src/include/access/xlog_internal.h
@@ -233,6 +233,13 @@ typedef struct xl_parameter_change
bool track_commit_timestamp;
} xl_parameter_change;
+/* BACKUP_END WAL record main data structure */
+typedef struct xl_backup_end
+{
+ XLogRecPtr startpoint;
+ TimestampTz timestamp;
+} xl_backup_end;
+
/* logs restore point */
typedef struct xl_restore_point
{
--
2.7.4