standby_online_backup_09base-02fpw.patch
application/octet-stream
Filename: standby_online_backup_09base-02fpw.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 | 74 | 10 |
| src/backend/postmaster/walwriter.c | 12 | 0 |
| src/include/access/xlog.h | 1 | 0 |
diff -rcN postgresql_with_9fujii_patch/src/backend/access/transam/xlog.c postgresql_with_patch/src/backend/access/transam/xlog.c
*** postgresql_with_9fujii_patch/src/backend/access/transam/xlog.c 2011-10-06 06:06:19.000000000 +0900
--- postgresql_with_patch/src/backend/access/transam/xlog.c 2011-10-11 14:58:50.000000000 +0900
***************
*** 364,369 ****
--- 364,372 ----
bool exclusiveBackup;
int nonExclusiveBackups;
XLogRecPtr lastBackupStart;
+
+ /* the startup or the walwriter is logged to its own FPW */
+ bool fullPageWrites;
} XLogCtlInsert;
/*
***************
*** 453,458 ****
--- 456,464 ----
bool recoveryPause;
slock_t info_lck; /* locks shared variables shown above */
+
+ /* latest LSN that has recovered a WAL which fpw is 'off' */
+ XLogRecPtr lastFpwDisabledLSN;
} XLogCtlData;
static XLogCtlData *XLogCtl = NULL;
***************
*** 574,579 ****
--- 580,586 ----
int max_prepared_xacts;
int max_locks_per_xact;
int wal_level;
+ bool fullPageWrites;
} xl_parameter_change;
/* logs restore point */
***************
*** 612,618 ****
static void SetLatestXTime(TimestampTz xtime);
static TimestampTz GetLatestXTime(void);
static void CheckRequiredParameterValues(void);
- static void XLogReportParameters(void);
static void LocalSetXLogInsertAllowed(void);
static void CheckPointGuts(XLogRecPtr checkPointRedo, int flags);
static void KeepLogSeg(XLogRecPtr recptr, uint32 *logId, uint32 *logSeg);
--- 619,624 ----
***************
*** 763,769 ****
* don't yet have the insert lock, forcePageWrites could change under us,
* but we'll recheck it once we have the lock.
*/
! doPageWrites = fullPageWrites || Insert->forcePageWrites;
INIT_CRC32(rdata_crc);
len = 0;
--- 769,775 ----
* don't yet have the insert lock, forcePageWrites could change under us,
* but we'll recheck it once we have the lock.
*/
! doPageWrites = Insert->fullPageWrites || Insert->forcePageWrites;
INIT_CRC32(rdata_crc);
len = 0;
***************
*** 909,915 ****
* just turned off, we could recompute the record without full pages, but
* we choose not to bother.)
*/
! if (Insert->forcePageWrites && !doPageWrites)
{
/* Oops, must redo it with full-page data */
LWLockRelease(WALInsertLock);
--- 915,921 ----
* just turned off, we could recompute the record without full pages, but
* we choose not to bother.)
*/
! if ((Insert->fullPageWrites || Insert->forcePageWrites) && !doPageWrites)
{
/* Oops, must redo it with full-page data */
LWLockRelease(WALInsertLock);
***************
*** 6865,6870 ****
--- 6871,6886 ----
/* Pre-scan prepared transactions to find out the range of XIDs present */
oldestActiveXID = PrescanPreparedTransactions(NULL, NULL);
+ /*
+ * The startup updates FPW in shaerd-memory after REDO. However, it must
+ * perform before writing the WAL of the CHECKPOINT. The reason is that
+ * it uses a value of fpw in shared-memory when it writes a WAL of its
+ * CHECKPOTNT.
+ */
+ LWLockAcquire(WALInsertLock, LW_EXCLUSIVE);
+ XLogCtl->Insert.fullPageWrites = fullPageWrites;
+ LWLockRelease(WALInsertLock);
+
if (InRecovery)
{
int rmid;
***************
*** 6998,7004 ****
* backends to write WAL.
*/
LocalSetXLogInsertAllowed();
! XLogReportParameters();
/*
* All done. Allow backends to write WAL. (Although the bool flag is
--- 7014,7020 ----
* backends to write WAL.
*/
LocalSetXLogInsertAllowed();
! XLogReportParameters(true);
/*
* All done. Allow backends to write WAL. (Although the bool flag is
***************
*** 7856,7862 ****
--- 7872,7881 ----
* Update checkPoint.nextXid since we have a later value
*/
if (!shutdown && XLogStandbyInfoActive())
+ {
LogStandbySnapshot(&checkPoint.oldestActiveXid, &checkPoint.nextXid);
+ XLogReportParameters(false);
+ }
else
checkPoint.oldestActiveXid = InvalidTransactionId;
***************
*** 8381,8393 ****
* Check if any of the GUC parameters that are critical for hot standby
* have changed, and update the value in pg_control file if necessary.
*/
! static void
! XLogReportParameters(void)
{
if (wal_level != ControlFile->wal_level ||
MaxConnections != ControlFile->MaxConnections ||
max_prepared_xacts != ControlFile->max_prepared_xacts ||
! max_locks_per_xact != ControlFile->max_locks_per_xact)
{
/*
* The change in number of backend slots doesn't need to be WAL-logged
--- 8400,8422 ----
* Check if any of the GUC parameters that are critical for hot standby
* have changed, and update the value in pg_control file if necessary.
*/
! void
! XLogReportParameters(bool fpw_manager)
{
+ bool fpw = fullPageWrites;
+
+ if (!fpw_manager)
+ {
+ LWLockAcquire(WALInsertLock, LW_EXCLUSIVE);
+ fpw = XLogCtl->Insert.fullPageWrites;
+ LWLockRelease(WALInsertLock);
+ }
+
if (wal_level != ControlFile->wal_level ||
MaxConnections != ControlFile->MaxConnections ||
max_prepared_xacts != ControlFile->max_prepared_xacts ||
! max_locks_per_xact != ControlFile->max_locks_per_xact ||
! !fpw)
{
/*
* The change in number of backend slots doesn't need to be WAL-logged
***************
*** 8396,8402 ****
* values in pg_control either if wal_level=minimal, but seems better
* to keep them up-to-date to avoid confusion.
*/
! if (wal_level != ControlFile->wal_level || XLogIsNeeded())
{
XLogRecData rdata;
xl_parameter_change xlrec;
--- 8425,8431 ----
* values in pg_control either if wal_level=minimal, but seems better
* to keep them up-to-date to avoid confusion.
*/
! if (wal_level != ControlFile->wal_level || XLogIsNeeded() || !fpw)
{
XLogRecData rdata;
xl_parameter_change xlrec;
***************
*** 8405,8410 ****
--- 8434,8440 ----
xlrec.max_prepared_xacts = max_prepared_xacts;
xlrec.max_locks_per_xact = max_locks_per_xact;
xlrec.wal_level = wal_level;
+ xlrec.fullPageWrites = fpw;
rdata.buffer = InvalidBuffer;
rdata.data = (char *) &xlrec;
***************
*** 8420,8425 ****
--- 8450,8463 ----
ControlFile->wal_level = wal_level;
UpdateControlFile();
}
+
+ /* update own fpw in shared-memory when it has managed fpw */
+ if (fpw_manager)
+ {
+ LWLockAcquire(WALInsertLock, LW_EXCLUSIVE);
+ XLogCtl->Insert.fullPageWrites = fullPageWrites;
+ LWLockRelease(WALInsertLock);
+ }
}
/*
***************
*** 8604,8609 ****
--- 8642,8650 ----
}
else if (info == XLOG_PARAMETER_CHANGE)
{
+ /* use volatile pointer to prevent code rearrangement */
+ volatile XLogCtlData *xlogctl = XLogCtl;
+
xl_parameter_change xlrec;
/* Update our copy of the parameters in pg_control */
***************
*** 8633,8638 ****
--- 8674,8687 ----
UpdateControlFile();
LWLockRelease(ControlFileLock);
+ /* record the LSN when FPW is false on master */
+ if (!xlrec.fullPageWrites)
+ {
+ SpinLockAcquire(&xlogctl->info_lck);
+ xlogctl->lastFpwDisabledLSN = lsn;
+ SpinLockRelease(&xlogctl->info_lck);
+ }
+
/* Check to see if any changes to max_connections give problems */
CheckRequiredParameterValues();
}
***************
*** 8711,8721 ****
}
}
! appendStringInfo(buf, "parameter change: max_connections=%d max_prepared_xacts=%d max_locks_per_xact=%d wal_level=%s",
xlrec.MaxConnections,
xlrec.max_prepared_xacts,
xlrec.max_locks_per_xact,
! wal_level_str);
}
else
appendStringInfo(buf, "UNKNOWN");
--- 8760,8771 ----
}
}
! appendStringInfo(buf, "parameter change: max_connections=%d max_prepared_xacts=%d max_locks_per_xact=%d wal_level=%s full_page_writes=%s",
xlrec.MaxConnections,
xlrec.max_prepared_xacts,
xlrec.max_locks_per_xact,
! wal_level_str,
! xlrec.fullPageWrites ? "true" : "false");
}
else
appendStringInfo(buf, "UNKNOWN");
***************
*** 9089,9094 ****
--- 9139,9152 ----
gotUniqueStartpoint = true;
} while (!gotUniqueStartpoint);
+ /*
+ * check whether the master's FPW is 'off' since latest CHECKPOINT.
+ */
+ if (recovery_in_progress && XLByteLE(startpoint, XLogCtl->lastFpwDisabledLSN))
+ ereport(ERROR,
+ (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
+ errmsg("full_page_writes on master is set invalid at least once since latest checkpoint")));
+
XLByteToSeg(startpoint, _logId, _logSeg);
XLogFileName(xlogfilename, ThisTimeLineID, _logId, _logSeg);
***************
*** 9372,9377 ****
--- 9430,9441 ----
"though pg_start_backup() was executed during recovery"),
errhint("The database backup will not be usable.")));
+ /* check whether the master's FPW is 'off' since pg_start_backup. */
+ if (recovery_in_progress && XLByteLE(startpoint, XLogCtl->lastFpwDisabledLSN))
+ ereport(ERROR,
+ (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
+ errmsg("full_page_writes on master is set invalid at least once during online backup")));
+
/*
* During recovery, we don't write an end-of-backup record. We can
* assume that pg_control was backed up just before pg_stop_backup()
diff -rcN postgresql_with_9fujii_patch/src/backend/postmaster/walwriter.c postgresql_with_patch/src/backend/postmaster/walwriter.c
*** postgresql_with_9fujii_patch/src/backend/postmaster/walwriter.c 2011-10-06 06:05:45.000000000 +0900
--- postgresql_with_patch/src/backend/postmaster/walwriter.c 2011-10-11 14:53:58.000000000 +0900
***************
*** 216,221 ****
--- 216,227 ----
PG_SETMASK(&UnBlockSig);
/*
+ * After the startup process, the walwriter manages the FPW. Because
+ * the walwriter may have not received a SIGHUP then, it updates the FPW.
+ */
+ XLogReportParameters(true);
+
+ /*
* Loop forever
*/
for (;;)
***************
*** 236,241 ****
--- 242,253 ----
{
got_SIGHUP = false;
ProcessConfigFile(PGC_SIGHUP);
+
+ /*
+ * The walwriter manages the FPW. When the walwriter has received
+ * a SIGHUP, it updates the FPW.
+ */
+ XLogReportParameters(true);
}
if (shutdown_requested)
{
diff -rcN postgresql_with_9fujii_patch/src/include/access/xlog.h postgresql_with_patch/src/include/access/xlog.h
*** postgresql_with_9fujii_patch/src/include/access/xlog.h 2011-10-06 06:05:45.000000000 +0900
--- postgresql_with_patch/src/include/access/xlog.h 2011-10-11 14:53:58.000000000 +0900
***************
*** 306,311 ****
--- 306,312 ----
extern bool CreateRestartPoint(int flags);
extern void XLogPutNextOid(Oid nextOid);
extern XLogRecPtr XLogRestorePoint(const char *rpName);
+ extern void XLogReportParameters(bool fpw_manager);
extern XLogRecPtr GetRedoRecPtr(void);
extern XLogRecPtr GetInsertRecPtr(void);
extern XLogRecPtr GetFlushRecPtr(void);