standby_online_backup_01.patch
application/octet-stream
Filename: standby_online_backup_01.patch
Type: application/octet-stream
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: context
| File | + | − |
|---|---|---|
| src/backend/access/transam/xlog.c | 147 | 4 |
| src/bin/pg_controldata/pg_controldata.c | 6 | 0 |
| src/include/catalog/pg_control.h | 21 | 0 |
diff -rcN postgresql/src/backend/access/transam/xlog.c postgresql_with_patch/src/backend/access/transam/xlog.c
*** postgresql/src/backend/access/transam/xlog.c 2011-06-13 04:29:59.000000000 +0900
--- postgresql_with_patch/src/backend/access/transam/xlog.c 2011-06-14 03:50:03.000000000 +0900
***************
*** 556,561 ****
--- 556,564 ----
static bool updateMinRecoveryPoint = true;
static bool reachedMinRecoveryPoint = false;
+ /* End of backup reached by backup history file */
+ static bool reachedBackuphistStoppoint = false;
+
static bool InRedo = false;
/* Have we launched bgwriter during recovery? */
***************
*** 659,665 ****
static void xlog_outrec(StringInfo buf, XLogRecord *record);
#endif
static void pg_start_backup_callback(int code, Datum arg);
! static bool read_backup_label(XLogRecPtr *checkPointLoc);
static void rm_redo_error_callback(void *arg);
static int get_sync_bit(int method);
--- 662,668 ----
static void xlog_outrec(StringInfo buf, XLogRecord *record);
#endif
static void pg_start_backup_callback(int code, Datum arg);
! static bool read_backup_label(XLogRecPtr *checkPointLoc, XLogRecPtr *backupStartLoc, XLogRecPtr *backupEndLoc);
static void rm_redo_error_callback(void *arg);
static int get_sync_bit(int method);
***************
*** 5989,5994 ****
--- 5992,5999 ----
bool haveBackupLabel = false;
XLogRecPtr RecPtr,
checkPointLoc,
+ backupStartLoc = {0 ,0},
+ backupEndLoc = {0 ,0},
EndOfLog;
uint32 endLogId;
uint32 endLogSeg;
***************
*** 6128,6134 ****
if (StandbyMode)
OwnLatch(&XLogCtl->recoveryWakeupLatch);
! if (read_backup_label(&checkPointLoc))
{
/*
* When a backup_label file is present, we want to roll forward from
--- 6133,6139 ----
if (StandbyMode)
OwnLatch(&XLogCtl->recoveryWakeupLatch);
! if (read_backup_label(&checkPointLoc, &backupStartLoc, &backupEndLoc))
{
/*
* When a backup_label file is present, we want to roll forward from
***************
*** 6165,6170 ****
--- 6170,6185 ----
errhint("If you are not restoring from a backup, try removing the file \"%s/backup_label\".", DataDir)));
wasShutdown = false; /* keep compiler quiet */
}
+
+ /*
+ * Set up values of backup history file to controlfile.
+ */
+ LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
+ ControlFile->backuphistStartPoint = backupStartLoc;
+ ControlFile->backuphistEndPoint = backupEndLoc;
+ UpdateControlFile();
+ LWLockRelease(ControlFileLock);
+
/* set flag to delete it later */
haveBackupLabel = true;
}
***************
*** 6209,6214 ****
--- 6224,6236 ----
}
memcpy(&checkPoint, XLogRecGetData(record), sizeof(CheckPoint));
wasShutdown = (record->xl_info == XLOG_CHECKPOINT_SHUTDOWN);
+
+ /*
+ * Use values of controlfile because backup history file was not
+ * able to be read.
+ */
+ backupStartLoc = ControlFile->backuphistStartPoint;
+ backupEndLoc = ControlFile->backuphistEndPoint;
}
LastRec = RecPtr = checkPointLoc;
***************
*** 6586,6591 ****
--- 6608,6635 ----
/* Pop the error context stack */
error_context_stack = errcontext.previous;
+ /*
+ * Check whether to reach backupEndLoc when backup history
+ * file was read.
+ */
+ if (backupEndLoc.xlogid != 0 || backupEndLoc.xrecoff != 0)
+ {
+ if (XLByteEQ(backupEndLoc, EndRecPtr))
+ {
+ reachedBackuphistStoppoint = true;
+ elog(DEBUG1, "end of backup reached by backup history file");
+
+ LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
+
+ if (XLByteLT(ControlFile->minRecoveryPoint, EndRecPtr))
+ ControlFile->minRecoveryPoint = EndRecPtr;
+ MemSet(&ControlFile->backupStartPoint, 0, sizeof(XLogRecPtr));
+ UpdateControlFile();
+
+ LWLockRelease(ControlFileLock);
+ }
+ }
+
/*
* Update shared recoveryLastRecPtr after this record has been
* replayed.
***************
*** 6945,6951 ****
*/
if (!reachedMinRecoveryPoint &&
XLByteLE(minRecoveryPoint, EndRecPtr) &&
! XLogRecPtrIsInvalid(ControlFile->backupStartPoint))
{
reachedMinRecoveryPoint = true;
ereport(LOG,
--- 6989,6996 ----
*/
if (!reachedMinRecoveryPoint &&
XLByteLE(minRecoveryPoint, EndRecPtr) &&
! (XLogRecPtrIsInvalid(ControlFile->backupStartPoint) ||
! reachedBackuphistStoppoint == true))
{
reachedMinRecoveryPoint = true;
ereport(LOG,
***************
*** 8492,8497 ****
--- 8537,8588 ----
memcpy(&startpoint, XLogRecGetData(record), sizeof(startpoint));
+ /*
+ * Check whether backup history file is correct when it was read.
+ *
+ * When backup-end record reached and backuphistEndPoint did not reach,
+ * check whether backuphistEndPoint is correct.
+ *
+ * When backup-end record reached and backuphistEndPoint reached,
+ * check whether check target, and check whether backuphistEndPoint
+ * and lsn are equal. if not , stop startup process , because if has
+ * already become active hot standby.
+ */
+ if (ControlFile->backuphistEndPoint.xlogid != 0 || ControlFile->backuphistEndPoint.xrecoff != 0)
+ {
+ if (!reachedBackuphistStoppoint)
+ {
+ if (!XLByteEQ(ControlFile->backuphistEndPoint, lsn))
+ ereport(WARNING,
+ (errmsg("backup-end record's location isn't \"STOP WAL LOCATION\" of backup history file")));
+
+ LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
+ MemSet(&ControlFile->backuphistStartPoint, 0, sizeof(XLogRecPtr));
+ MemSet(&ControlFile->backuphistEndPoint, 0, sizeof(XLogRecPtr));
+ UpdateControlFile();
+ LWLockRelease(ControlFileLock);
+ }
+ else
+ {
+ if (XLByteEQ(ControlFile->backuphistStartPoint, startpoint))
+ {
+ if(!XLByteEQ(ControlFile->backuphistEndPoint, lsn))
+ ereport(FATAL,
+ (errmsg("backup-end record's data isn't \"START WAL LOCATION\" of backup history file")));
+ else
+ {
+ reachedBackuphistStoppoint = false;
+
+ LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
+ MemSet(&ControlFile->backuphistStartPoint, 0, sizeof(XLogRecPtr));
+ MemSet(&ControlFile->backuphistEndPoint, 0, sizeof(XLogRecPtr));
+ UpdateControlFile();
+ LWLockRelease(ControlFileLock);
+ }
+ }
+ }
+ }
+
if (XLByteEQ(ControlFile->backupStartPoint, startpoint))
{
/*
***************
*** 9717,9732 ****
* later than the start of the dump, and so if we rely on it as the start
* point, we will fail to restore a consistent database state.
*
* Returns TRUE if a backup_label was found (and fills the checkpoint
* location and its REDO location into *checkPointLoc and RedoStartLSN,
* respectively); returns FALSE if not.
*/
static bool
! read_backup_label(XLogRecPtr *checkPointLoc)
{
char startxlogfilename[MAXFNAMELEN];
TimeLineID tli;
FILE *lfp;
char ch;
/*
--- 9808,9835 ----
* later than the start of the dump, and so if we rely on it as the start
* point, we will fail to restore a consistent database state.
*
+ * We also attempt to retrieve the corresponding backup history file.
+ * If successful, set *backupStartLoc and *backupEndLoc to check to reach
+ * backup end location by values of backup history file. In the future,
+ * it is scheduled to use it to acquire online base backup from the hot
+ * standby.
+ *
* Returns TRUE if a backup_label was found (and fills the checkpoint
* location and its REDO location into *checkPointLoc and RedoStartLSN,
* respectively); returns FALSE if not.
*/
static bool
! read_backup_label(XLogRecPtr *checkPointLoc, XLogRecPtr *backupStartLoc, XLogRecPtr *backupEndLoc)
{
+ char histfilename[MAXFNAMELEN];
+ char histfilepath[MAXPGPATH];
char startxlogfilename[MAXFNAMELEN];
+ char stopxlogfilename[MAXFNAMELEN];
TimeLineID tli;
+ uint32 _logId;
+ uint32 _logSeg;
FILE *lfp;
+ FILE *fp;
char ch;
/*
***************
*** 9766,9771 ****
--- 9869,9914 ----
errmsg("could not read file \"%s\": %m",
BACKUP_LABEL_FILE)));
+ /*
+ * See if backup history file is present.
+ * If label file is not present, this logic doesn't pass.
+ */
+ XLByteToSeg(RedoStartLSN, _logId, _logSeg);
+ BackupHistoryFileName(histfilename, tli, _logId, _logSeg,
+ RedoStartLSN.xrecoff % XLogSegSize);
+ if (InArchiveRecovery)
+ RestoreArchivedFile(histfilepath, histfilename, "RECOVERYHISTORY", 0);
+ else
+ BackupHistoryFilePath(histfilepath, tli, _logId, _logSeg,
+ RedoStartLSN.xrecoff % XLogSegSize);
+
+ fp = AllocateFile(histfilepath, "r");
+ if (fp)
+ {
+ if (fscanf(fp, "START WAL LOCATION: %X/%X (file %08X%16s)%c",
+ &backupStartLoc->xlogid, &backupStartLoc->xrecoff, &tli, startxlogfilename,
+ &ch) != 5 || ch != '\n')
+ ereport(FATAL,
+ (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
+ errmsg("invalid data in file \"%s\"", histfilename)));
+ /* histfilename == START WAL LOCATION*/
+ if (!XLByteEQ(RedoStartLSN, *backupStartLoc))
+ ereport(ERROR,
+ (errmsg("wrong \"START WAL LOCATION\" of backup history file \"%s\"", histfilename)));
+
+ if (fscanf(fp, "STOP WAL LOCATION: %X/%X (file %08X%16s)%c",
+ &backupEndLoc->xlogid, &backupEndLoc->xrecoff, &tli, stopxlogfilename,
+ &ch) != 5 || ch != '\n')
+ ereport(FATAL,
+ (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
+ errmsg("invalid data in file \"%s\"", histfilename)));
+ if (ferror(fp) || FreeFile(fp))
+ ereport(FATAL,
+ (errcode_for_file_access(),
+ errmsg("could not read file \"%s\": %m",
+ histfilepath)));
+ }
+
return true;
}
diff -rcN postgresql/src/bin/pg_controldata/pg_controldata.c postgresql_with_patch/src/bin/pg_controldata/pg_controldata.c
*** postgresql/src/bin/pg_controldata/pg_controldata.c 2011-06-13 04:29:59.000000000 +0900
--- postgresql_with_patch/src/bin/pg_controldata/pg_controldata.c 2011-06-14 00:01:17.000000000 +0900
***************
*** 232,237 ****
--- 232,243 ----
printf(_("Backup start location: %X/%X\n"),
ControlFile.backupStartPoint.xlogid,
ControlFile.backupStartPoint.xrecoff);
+ printf(_("Backup history file's start location: %X/%X\n"),
+ ControlFile.backuphistStartPoint.xlogid,
+ ControlFile.backuphistStartPoint.xrecoff);
+ printf(_("Backup history file's stop location: %X/%X\n"),
+ ControlFile.backuphistEndPoint.xlogid,
+ ControlFile.backuphistEndPoint.xrecoff);
printf(_("Current wal_level setting: %s\n"),
wal_level_str(ControlFile.wal_level));
printf(_("Current max_connections setting: %d\n"),
diff -rcN postgresql/src/include/catalog/pg_control.h postgresql_with_patch/src/include/catalog/pg_control.h
*** postgresql/src/include/catalog/pg_control.h 2011-06-13 04:29:59.000000000 +0900
--- postgresql_with_patch/src/include/catalog/pg_control.h 2011-06-14 14:45:15.000000000 +0900
***************
*** 142,147 ****
--- 142,168 ----
XLogRecPtr backupStartPoint;
/*
+ * Startup process keeps backup history file's "START WAL LOCATION" and
+ * "STOP WAL LOCATION" these two values if it reads backup history file.
+ * It keeps these two values because it is necessary when startup process
+ * begins without reading backup label. In the future, it is scheduled
+ * to use these two values to acquire online base backup from the hot
+ * standby.
+ *
+ * backuphistStartPoint is updated when backup history file is read on
+ * starting up, and backuphistStartPoint is checked with backup-end record.
+ * if backup history file is not read , backuphistStartPoint is zero.
+ * Then, the check by backup history file is not done. When the check is
+ * completed, it becomes zero.
+ *
+ * backuphistEndPoint is updated when backup history file is read on
+ * starting up, and backuphistEndPoint specifies backup end location.
+ * Its update is similar to backuphistStartPoint.
+ */
+ XLogRecPtr backuphistStartPoint;
+ XLogRecPtr backuphistEndPoint;
+
+ /*
* Parameter settings that determine if the WAL can be used for archival
* or hot standby.
*/