1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-30 11:03:19 +03:00

Introduce wal_level GUC to explicitly control if information needed for

archival or hot standby should be WAL-logged, instead of deducing that from
other options like archive_mode. This replaces recovery_connections GUC in
the primary, where it now has no effect, but it's still used in the standby
to enable/disable hot standby.

Remove the WAL-logging of "unlogged operations", like creating an index
without WAL-logging and fsyncing it at the end. Instead, we keep a copy of
the wal_mode setting and the settings that affect how much shared memory a
hot standby server needs to track master transactions (max_connections,
max_prepared_xacts, max_locks_per_xact) in pg_control. Whenever the settings
change, at server restart, write a WAL record noting the new settings and
update pg_control. This allows us to notice the change in those settings in
the standby at the right moment, they used to be included in checkpoint
records, but that meant that a changed value was not reflected in the
standby until the first checkpoint after the change.

Bump PG_CONTROL_VERSION and XLOG_PAGE_MAGIC. Whack XLOG_PAGE_MAGIC back to
the sequence it used to follow, before hot standby and subsequent patches
changed it to 0x9003.
This commit is contained in:
Heikki Linnakangas
2010-04-28 16:10:43 +00:00
parent a2de4826e9
commit 9b8a73326e
22 changed files with 340 additions and 224 deletions

View File

@ -96,7 +96,7 @@
* Portions Copyright (c) 1994-5, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/heap/rewriteheap.c,v 1.21 2010/02/26 02:00:33 momjian Exp $
* $PostgreSQL: pgsql/src/backend/access/heap/rewriteheap.c,v 1.22 2010/04/28 16:10:40 heikki Exp $
*
*-------------------------------------------------------------------------
*/
@ -278,16 +278,6 @@ end_heap_rewrite(RewriteState state)
(char *) state->rs_buffer, true);
}
/* Write an XLOG UNLOGGED record if WAL-logging was skipped */
if (!state->rs_use_wal && !state->rs_new_rel->rd_istemp)
{
char reason[NAMEDATALEN + 30];
snprintf(reason, sizeof(reason), "heap rewrite on \"%s\"",
RelationGetRelationName(state->rs_new_rel));
XLogReportUnloggedStatement(reason);
}
/*
* If the rel isn't temp, must fsync before commit. We use heap_sync to
* ensure that the toast table gets fsync'd too.

View File

@ -59,7 +59,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/nbtree/nbtsort.c,v 1.124 2010/02/26 02:00:34 momjian Exp $
* $PostgreSQL: pgsql/src/backend/access/nbtree/nbtsort.c,v 1.125 2010/04/28 16:10:40 heikki Exp $
*
*-------------------------------------------------------------------------
*/
@ -215,19 +215,6 @@ _bt_leafbuild(BTSpool *btspool, BTSpool *btspool2)
*/
wstate.btws_use_wal = XLogIsNeeded() && !wstate.index->rd_istemp;
/*
* Write an XLOG UNLOGGED record if WAL-logging was skipped because WAL
* archiving is not enabled.
*/
if (!wstate.btws_use_wal && !wstate.index->rd_istemp)
{
char reason[NAMEDATALEN + 20];
snprintf(reason, sizeof(reason), "b-tree build on \"%s\"",
RelationGetRelationName(wstate.index));
XLogReportUnloggedStatement(reason);
}
/* reserve the metapage */
wstate.btws_pages_alloced = BTREE_METAPAGE + 1;
wstate.btws_pages_written = 0;

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.404 2010/04/27 09:25:18 heikki Exp $
* $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.405 2010/04/28 16:10:40 heikki Exp $
*
*-------------------------------------------------------------------------
*/
@ -76,6 +76,7 @@ int MaxStandbyDelay = 30;
bool fullPageWrites = true;
bool log_checkpoints = false;
int sync_method = DEFAULT_SYNC_METHOD;
int wal_level = WAL_LEVEL_MINIMAL;
#ifdef WAL_DEBUG
bool XLOG_DEBUG = false;
@ -97,6 +98,13 @@ bool XLOG_DEBUG = false;
/*
* GUC support
*/
const struct config_enum_entry wal_level_options[] = {
{"minimal", WAL_LEVEL_MINIMAL, false},
{"archive", WAL_LEVEL_ARCHIVE, false},
{"hot_standby", WAL_LEVEL_HOT_STANDBY, false},
{NULL, 0, false}
};
const struct config_enum_entry sync_method_options[] = {
{"fsync", SYNC_METHOD_FSYNC, false},
#ifdef HAVE_FSYNC_WRITETHROUGH
@ -500,6 +508,18 @@ static bool reachedMinRecoveryPoint = false;
static bool InRedo = false;
/*
* Information logged when we detect a change in one of the parameters
* important for Hot Standby.
*/
typedef struct xl_parameter_change
{
int MaxConnections;
int max_prepared_xacts;
int max_locks_per_xact;
int wal_level;
} xl_parameter_change;
/*
* Flags set by interrupt handlers for later service in the redo loop.
*/
@ -522,7 +542,8 @@ static void readRecoveryCommandFile(void);
static void exitArchiveRecovery(TimeLineID endTLI,
uint32 endLogId, uint32 endLogSeg);
static bool recoveryStopsHere(XLogRecord *record, bool *includeThis);
static void CheckRequiredParameterValues(CheckPoint checkPoint);
static void CheckRequiredParameterValues(void);
static void XLogReportParameters(void);
static void LocalSetXLogInsertAllowed(void);
static void CheckPointGuts(XLogRecPtr checkPointRedo, int flags);
@ -4922,6 +4943,13 @@ BootStrapXLOG(void)
ControlFile->time = checkPoint.time;
ControlFile->checkPoint = checkPoint.redo;
ControlFile->checkPointCopy = checkPoint;
/* Set important parameter values for use when replaying WAL */
ControlFile->MaxConnections = MaxConnections;
ControlFile->max_prepared_xacts = max_prepared_xacts;
ControlFile->max_locks_per_xact = max_locks_per_xact;
ControlFile->wal_level = wal_level;
/* some additional ControlFile fields are set in WriteControlFile() */
WriteControlFile();
@ -5539,17 +5567,18 @@ GetLatestXLogTime(void)
}
/*
* Note that text field supplied is a parameter name and does not require translation
* Note that text field supplied is a parameter name and does not require
* translation
*/
#define RecoveryRequiresIntParameter(param_name, currValue, checkpointValue) \
#define RecoveryRequiresIntParameter(param_name, currValue, minValue) \
{ \
if (currValue < checkpointValue) \
if (currValue < minValue) \
ereport(ERROR, \
(errmsg("recovery connections cannot continue because " \
"%s = %u is a lower setting than on WAL source server (value was %u)", \
param_name, \
currValue, \
checkpointValue))); \
minValue))); \
}
/*
@ -5557,21 +5586,37 @@ GetLatestXLogTime(void)
* for various aspects of recovery operation.
*/
static void
CheckRequiredParameterValues(CheckPoint checkPoint)
CheckRequiredParameterValues(void)
{
/* We ignore autovacuum_max_workers when we make this test. */
RecoveryRequiresIntParameter("max_connections",
MaxConnections, checkPoint.MaxConnections);
/*
* For archive recovery, the WAL must be generated with at least
* 'archive' wal_level.
*/
if (InArchiveRecovery && ControlFile->wal_level == WAL_LEVEL_MINIMAL)
{
ereport(WARNING,
(errmsg("WAL was generated with wal_level='minimal', data may be missing"),
errhint("This happens if you temporarily set wal_level='minimal' without taking a new base backup.")));
}
RecoveryRequiresIntParameter("max_prepared_xacts",
max_prepared_xacts, checkPoint.max_prepared_xacts);
RecoveryRequiresIntParameter("max_locks_per_xact",
max_locks_per_xact, checkPoint.max_locks_per_xact);
/*
* For Hot Standby, the WAL must be generated with 'hot_standby' mode,
* and we must have at least as many backend slots as the primary.
*/
if (InArchiveRecovery && XLogRequestRecoveryConnections)
{
if (ControlFile->wal_level < WAL_LEVEL_HOT_STANDBY)
ereport(ERROR,
(errmsg("recovery connections cannot start because wal_level was not set to 'hot_standby' on the WAL source server")));
if (!checkPoint.XLogStandbyInfoMode)
ereport(ERROR,
(errmsg("recovery connections cannot start because the recovery_connections "
"parameter is disabled on the WAL source server")));
/* We ignore autovacuum_max_workers when we make this test. */
RecoveryRequiresIntParameter("max_connections",
MaxConnections, ControlFile->MaxConnections);
RecoveryRequiresIntParameter("max_prepared_xacts",
max_prepared_xacts, ControlFile->max_prepared_xacts);
RecoveryRequiresIntParameter("max_locks_per_xact",
max_locks_per_xact, ControlFile->max_locks_per_xact);
}
}
/*
@ -5904,6 +5949,9 @@ StartupXLOG(void)
BACKUP_LABEL_FILE, BACKUP_LABEL_OLD)));
}
/* Check that the GUCs used to generate the WAL allow recovery */
CheckRequiredParameterValues();
/*
* Initialize recovery connections, if enabled. We won't let backends
* in yet, not until we've reached the min recovery point specified in
@ -5915,8 +5963,6 @@ StartupXLOG(void)
TransactionId *xids;
int nxids;
CheckRequiredParameterValues(checkPoint);
ereport(DEBUG1,
(errmsg("initializing recovery connections")));
@ -6400,6 +6446,13 @@ StartupXLOG(void)
readRecordBufSize = 0;
}
/*
* If any of the critical GUCs have changed, log them before we allow
* backends to write WAL.
*/
LocalSetXLogInsertAllowed();
XLogReportParameters();
/*
* All done. Allow backends to write WAL. (Although the bool flag is
* probably atomic in itself, we use the info_lck here to ensure that
@ -6998,12 +7051,6 @@ CreateCheckPoint(int flags)
MemSet(&checkPoint, 0, sizeof(checkPoint));
checkPoint.time = (pg_time_t) time(NULL);
/* Set important parameter values for use when replaying WAL */
checkPoint.MaxConnections = MaxConnections;
checkPoint.max_prepared_xacts = max_prepared_xacts;
checkPoint.max_locks_per_xact = max_locks_per_xact;
checkPoint.XLogStandbyInfoMode = XLogStandbyInfoActive();
/*
* We must hold WALInsertLock while examining insert state to determine
* the checkpoint REDO pointer.
@ -7647,28 +7694,49 @@ RequestXLogSwitch(void)
}
/*
* Write an XLOG UNLOGGED record, indicating that some operation was
* performed on data that we fsync()'d directly to disk, skipping
* WAL-logging.
*
* Such operations screw up archive recovery, so we complain if we see
* these records during archive recovery. That shouldn't happen in a
* correctly configured server, but you can induce it by temporarily
* disabling archiving and restarting, so it's good to at least get a
* warning of silent data loss in such cases. These records serve no
* other purpose and are simply ignored during crash recovery.
* 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
XLogReportUnloggedStatement(char *reason)
static void
XLogReportParameters(void)
{
XLogRecData rdata;
if (wal_level != ControlFile->wal_level ||
MaxConnections != ControlFile->MaxConnections ||
max_prepared_xacts != ControlFile->max_prepared_xacts ||
max_locks_per_xact != max_locks_per_xact)
{
/*
* The change in number of backend slots doesn't need to be
* WAL-logged if archiving is not enabled, as you can't start
* archive recovery with wal_level='minimal' anyway. We don't
* really care about the 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;
rdata.buffer = InvalidBuffer;
rdata.data = reason;
rdata.len = strlen(reason) + 1;
rdata.next = NULL;
xlrec.MaxConnections = MaxConnections;
xlrec.max_prepared_xacts = max_prepared_xacts;
xlrec.max_locks_per_xact = max_locks_per_xact;
xlrec.wal_level = wal_level;
XLogInsert(RM_XLOG_ID, XLOG_UNLOGGED, &rdata);
rdata.buffer = InvalidBuffer;
rdata.data = (char *) &xlrec;
rdata.len = sizeof(xlrec);
rdata.next = NULL;
XLogInsert(RM_XLOG_ID, XLOG_PARAMETER_CHANGE, &rdata);
}
ControlFile->MaxConnections = MaxConnections;
ControlFile->max_prepared_xacts = max_prepared_xacts;
ControlFile->max_locks_per_xact = max_locks_per_xact;
ControlFile->wal_level = wal_level;
UpdateControlFile();
}
}
/*
@ -7709,10 +7777,6 @@ xlog_redo(XLogRecPtr lsn, XLogRecord *record)
checkPoint.nextMultiOffset);
SetTransactionIdLimit(checkPoint.oldestXid, checkPoint.oldestXidDB);
/* Check to see if any changes to max_connections give problems */
if (standbyState != STANDBY_DISABLED)
CheckRequiredParameterValues(checkPoint);
/*
* If we see a shutdown checkpoint while waiting for an
* end-of-backup record, the backup was cancelled and the
@ -7844,18 +7908,21 @@ xlog_redo(XLogRecPtr lsn, XLogRecord *record)
LWLockRelease(ControlFileLock);
}
}
else if (info == XLOG_UNLOGGED)
else if (info == XLOG_PARAMETER_CHANGE)
{
if (InArchiveRecovery)
{
/*
* Note: We don't print the reason string from the record, because
* that gets added as a line using xlog_desc()
*/
ereport(WARNING,
(errmsg("unlogged operation performed, data may be missing"),
errhint("This can happen if you temporarily disable archive_mode without taking a new base backup.")));
}
xl_parameter_change xlrec;
/* Update our copy of the parameters in pg_control */
memcpy(&xlrec, XLogRecGetData(record), sizeof(xl_parameter_change));
ControlFile->MaxConnections = xlrec.MaxConnections;
ControlFile->max_prepared_xacts = xlrec.max_prepared_xacts;
ControlFile->max_locks_per_xact = xlrec.max_locks_per_xact;
ControlFile->wal_level = xlrec.wal_level;
UpdateControlFile();
/* Check to see if any changes to max_connections give problems */
CheckRequiredParameterValues();
}
}
@ -7906,11 +7973,30 @@ xlog_desc(StringInfo buf, uint8 xl_info, char *rec)
appendStringInfo(buf, "backup end: %X/%X",
startpoint.xlogid, startpoint.xrecoff);
}
else if (info == XLOG_UNLOGGED)
else if (info == XLOG_PARAMETER_CHANGE)
{
char *reason = rec;
xl_parameter_change xlrec;
const char *wal_level_str;
const struct config_enum_entry *entry;
appendStringInfo(buf, "unlogged operation: %s", reason);
memcpy(&xlrec, rec, sizeof(xl_parameter_change));
/* Find a string representation for wal_level */
wal_level_str = "?";
for (entry = wal_level_options; entry->name; entry++)
{
if (entry->val == xlrec.wal_level)
{
wal_level_str = entry->name;
break;
}
}
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");

View File

@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/cluster.c,v 1.202 2010/02/26 02:00:37 momjian Exp $
* $PostgreSQL: pgsql/src/backend/commands/cluster.c,v 1.203 2010/04/28 16:10:41 heikki Exp $
*
*-------------------------------------------------------------------------
*/
@ -787,23 +787,6 @@ copy_heap_data(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex,
*/
use_wal = XLogIsNeeded() && !NewHeap->rd_istemp;
/*
* Write an XLOG UNLOGGED record if WAL-logging was skipped because WAL
* archiving is not enabled.
*/
if (!use_wal && !NewHeap->rd_istemp)
{
char reason[NAMEDATALEN + 32];
if (OldIndex != NULL)
snprintf(reason, sizeof(reason), "CLUSTER on \"%s\"",
RelationGetRelationName(NewHeap));
else
snprintf(reason, sizeof(reason), "VACUUM FULL on \"%s\"",
RelationGetRelationName(NewHeap));
XLogReportUnloggedStatement(reason);
}
/* use_wal off requires smgr_targblock be initially invalid */
Assert(RelationGetTargetBlock(NewHeap) == InvalidBlockNumber);

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/copy.c,v 1.326 2010/02/26 02:00:38 momjian Exp $
* $PostgreSQL: pgsql/src/backend/commands/copy.c,v 1.327 2010/04/28 16:10:41 heikki Exp $
*
*-------------------------------------------------------------------------
*/
@ -2223,14 +2223,7 @@ CopyFrom(CopyState cstate)
* indexes since those use WAL anyway)
*/
if (hi_options & HEAP_INSERT_SKIP_WAL)
{
char reason[NAMEDATALEN + 30];
snprintf(reason, sizeof(reason), "COPY FROM on \"%s\"",
RelationGetRelationName(cstate->rel));
XLogReportUnloggedStatement(reason);
heap_sync(cstate->rel);
}
}

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.329 2010/03/20 00:43:42 rhaas Exp $
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.330 2010/04/28 16:10:41 heikki Exp $
*
*-------------------------------------------------------------------------
*/
@ -3272,14 +3272,7 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap)
/* If we skipped writing WAL, then we need to sync the heap. */
if (hi_options & HEAP_INSERT_SKIP_WAL)
{
char reason[NAMEDATALEN + 30];
snprintf(reason, sizeof(reason), "table rewrite on \"%s\"",
RelationGetRelationName(newrel));
XLogReportUnloggedStatement(reason);
heap_sync(newrel);
}
heap_close(newrel, NoLock);
}
@ -7021,20 +7014,6 @@ ATExecSetTableSpace(Oid tableOid, Oid newTableSpace)
heap_close(pg_class, RowExclusiveLock);
/*
* Write an XLOG UNLOGGED record if WAL-logging was skipped because WAL
* archiving is not enabled.
*/
if (!XLogIsNeeded() && !rel->rd_istemp)
{
char reason[NAMEDATALEN + 40];
snprintf(reason, sizeof(reason), "ALTER TABLE SET TABLESPACE on \"%s\"",
RelationGetRelationName(rel));
XLogReportUnloggedStatement(reason);
}
relation_close(rel, NoLock);
/* Make sure the reltablespace change is visible */
@ -7063,10 +7042,6 @@ copy_relation_data(SMgrRelation src, SMgrRelation dst,
/*
* We need to log the copied data in WAL iff WAL archiving/streaming is
* enabled AND it's not a temp rel.
*
* Note: If you change the conditions here, update the conditions in
* ATExecSetTableSpace() for when an XLOG UNLOGGED record is written to
* match.
*/
use_wal = XLogIsNeeded() && !istemp;

View File

@ -26,7 +26,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.348 2010/02/26 02:00:41 momjian Exp $
* $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.349 2010/04/28 16:10:42 heikki Exp $
*
*-------------------------------------------------------------------------
*/
@ -2241,14 +2241,7 @@ CloseIntoRel(QueryDesc *queryDesc)
/* If we skipped using WAL, must heap_sync before commit */
if (myState->hi_options & HEAP_INSERT_SKIP_WAL)
{
char reason[NAMEDATALEN + 30];
snprintf(reason, sizeof(reason), "SELECT INTO on \"%s\"",
RelationGetRelationName(myState->rel));
XLogReportUnloggedStatement(reason);
heap_sync(myState->rel);
}
/* close rel, but keep lock until commit */
heap_close(myState->rel, NoLock);

View File

@ -37,7 +37,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.605 2010/04/08 01:39:37 rhaas Exp $
* $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.606 2010/04/28 16:10:42 heikki Exp $
*
* NOTES
*
@ -728,6 +728,12 @@ PostmasterMain(int argc, char *argv[])
write_stderr("%s: superuser_reserved_connections must be less than max_connections\n", progname);
ExitPostmaster(1);
}
if (XLogArchiveMode && wal_level == WAL_LEVEL_MINIMAL)
ereport(ERROR,
(errmsg("WAL archival (archive_mode='on') requires wal_level 'archive' or 'hot_standby'")));
if (max_wal_senders > 0 && wal_level == WAL_LEVEL_MINIMAL)
ereport(ERROR,
(errmsg("WAL streaming (max_wal_senders > 0) requires wal_level 'archive' or 'hot_standby")));
/*
* Other one-time internal sanity checks can go here, if they are fast.

View File

@ -30,7 +30,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/replication/walsender.c,v 1.17 2010/04/21 00:51:56 tgl Exp $
* $PostgreSQL: pgsql/src/backend/replication/walsender.c,v 1.18 2010/04/28 16:10:42 heikki Exp $
*
*-------------------------------------------------------------------------
*/
@ -253,6 +253,24 @@ WalSndHandshake(void)
{
StringInfoData buf;
/*
* Check that we're logging enough information in the
* WAL for log-shipping.
*
* NOTE: This only checks the current value of
* wal_level. Even if the current setting is not
* 'minimal', there can be old WAL in the pg_xlog
* directory that was created with 'minimal'.
* So this is not bulletproof, the purpose is
* just to give a user-friendly error message that
* hints how to configure the system correctly.
*/
if (wal_level == WAL_LEVEL_MINIMAL)
ereport(FATAL,
(errcode(ERRCODE_CANNOT_CONNECT_NOW),
errmsg("standby connections not allowed because wal_level='minimal'")));
/* Send a CopyOutResponse message, and start streaming */
pq_beginmessage(&buf, 'H');
pq_sendbyte(&buf, 0);

View File

@ -11,7 +11,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/storage/ipc/standby.c,v 1.19 2010/04/23 23:21:44 rhaas Exp $
* $PostgreSQL: pgsql/src/backend/storage/ipc/standby.c,v 1.20 2010/04/28 16:10:42 heikki Exp $
*
*-------------------------------------------------------------------------
*/
@ -256,7 +256,7 @@ ResolveRecoveryConflictWithSnapshot(TransactionId latestRemovedXid, RelFileNode
*/
if (!TransactionIdIsValid(latestRemovedXid))
{
elog(DEBUG1, "Invalid latestremovexXid reported, using latestcompletedxid instead");
elog(DEBUG1, "invalid latestremovexXid reported, using latestcompletedxid instead");
LWLockAcquire(ProcArrayLock, LW_SHARED);
latestRemovedXid = ShmemVariableCache->latestCompletedXid;

View File

@ -10,7 +10,7 @@
* Written by Peter Eisentraut <peter_e@gmx.net>.
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.551 2010/04/22 19:40:03 petere Exp $
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.552 2010/04/28 16:10:42 heikki Exp $
*
*--------------------------------------------------------------------
*/
@ -340,6 +340,7 @@ static const struct config_enum_entry constraint_exclusion_options[] = {
/*
* Options for enum values stored in other modules
*/
extern const struct config_enum_entry wal_level_options[];
extern const struct config_enum_entry sync_method_options[];
/*
@ -2784,6 +2785,15 @@ static struct config_enum ConfigureNamesEnum[] =
TRACK_FUNC_OFF, track_function_options, NULL, NULL
},
{
{"wal_level", PGC_POSTMASTER, WAL_SETTINGS,
gettext_noop("Set the level of information written to the WAL."),
NULL
},
&wal_level,
WAL_LEVEL_MINIMAL, wal_level_options, NULL
},
{
{"wal_sync_method", PGC_SIGHUP, WAL_SETTINGS,
gettext_noop("Selects the method used for forcing WAL updates to disk."),
@ -7862,7 +7872,7 @@ pg_timezone_abbrev_initialize(void)
static const char *
show_archive_command(void)
{
if (XLogArchiveMode)
if (XLogArchivingActive())
return XLogArchiveCommand;
else
return "(disabled)";

View File

@ -150,6 +150,7 @@
# - Settings -
#wal_level = minimal # minimal, archive, or hot_standby
#fsync = on # turns forced synchronization on or off
#synchronous_commit = on # immediate fsync at commit
#wal_sync_method = fsync # the default is the first option

View File

@ -6,15 +6,16 @@
* copyright (c) Oliver Elphick <olly@lfix.co.uk>, 2001;
* licence: BSD
*
* $PostgreSQL: pgsql/src/bin/pg_controldata/pg_controldata.c,v 1.46 2010/01/04 12:50:49 heikki Exp $
* $PostgreSQL: pgsql/src/bin/pg_controldata/pg_controldata.c,v 1.47 2010/04/28 16:10:43 heikki Exp $
*/
#include "postgres_fe.h"
#include "postgres.h"
#include <unistd.h>
#include <time.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "access/xlog.h"
#include "catalog/pg_control.h"
@ -60,6 +61,21 @@ dbState(DBState state)
return _("unrecognized status code");
}
static const char *
wal_level_str(WalLevel wal_level)
{
switch (wal_level)
{
case WAL_LEVEL_MINIMAL:
return "minimal";
case WAL_LEVEL_ARCHIVE:
return "archive";
case WAL_LEVEL_HOT_STANDBY:
return "hot_standby";
}
return _("unrecognized wal_level");
}
int
main(int argc, char *argv[])
@ -206,6 +222,14 @@ main(int argc, char *argv[])
printf(_("Backup start location: %X/%X\n"),
ControlFile.backupStartPoint.xlogid,
ControlFile.backupStartPoint.xrecoff);
printf(_("Last wal_level setting: %s\n"),
wal_level_str(ControlFile.wal_level));
printf(_("Last max_connections setting: %d\n"),
ControlFile.MaxConnections);
printf(_("Last max_prepared_xacts setting: %d\n"),
ControlFile.max_prepared_xacts);
printf(_("Last max_locks_per_xact setting: %d\n"),
ControlFile.max_locks_per_xact);
printf(_("Maximum data alignment: %u\n"),
ControlFile.maxAlign);
/* we don't print floatFormat since can't say much useful about it */

View File

@ -23,7 +23,7 @@
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/bin/pg_resetxlog/pg_resetxlog.c,v 1.78 2010/02/26 02:01:17 momjian Exp $
* $PostgreSQL: pgsql/src/bin/pg_resetxlog/pg_resetxlog.c,v 1.79 2010/04/28 16:10:43 heikki Exp $
*
*-------------------------------------------------------------------------
*/
@ -628,6 +628,15 @@ RewriteControlFile(void)
ControlFile.backupStartPoint.xlogid = 0;
ControlFile.backupStartPoint.xrecoff = 0;
/*
* Use the defaults for max_* settings. The values don't matter
* as long as wal_level='minimal'.
*/
ControlFile.MaxConnections = 100;
ControlFile.max_prepared_xacts = 0;
ControlFile.max_locks_per_xact = 64;
ControlFile.wal_level = WAL_LEVEL_MINIMAL;
/* Now we can force the recorded xlog seg size to the right thing. */
ControlFile.xlog_seg_size = XLogSegSize;

View File

@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/access/xlog.h,v 1.109 2010/04/20 11:15:06 rhaas Exp $
* $PostgreSQL: pgsql/src/include/access/xlog.h,v 1.110 2010/04/28 16:10:43 heikki Exp $
*/
#ifndef XLOG_H
#define XLOG_H
@ -195,24 +195,26 @@ extern int XLogArchiveTimeout;
extern bool log_checkpoints;
extern bool XLogRequestRecoveryConnections;
extern int MaxStandbyDelay;
/* WAL levels */
typedef enum WalLevel
{
WAL_LEVEL_MINIMAL = 0,
WAL_LEVEL_ARCHIVE,
WAL_LEVEL_HOT_STANDBY
} WalLevel;
extern int wal_level;
#define XLogArchivingActive() (XLogArchiveMode)
#define XLogArchivingActive() (XLogArchiveMode && wal_level >= WAL_LEVEL_ARCHIVE)
#define XLogArchiveCommandSet() (XLogArchiveCommand[0] != '\0')
/*
* This is in walsender.c, but declared here so that we don't need to include
* walsender.h in all files that check XLogIsNeeded()
* Is WAL-logging necessary for archival or log-shipping, or can we skip
* WAL-logging if we fsync() the data before committing instead?
*/
extern int max_wal_senders;
/*
* Is WAL-logging necessary? We need to log an XLOG record iff either
* WAL archiving is enabled or XLOG streaming is allowed.
*/
#define XLogIsNeeded() (XLogArchivingActive() || (max_wal_senders > 0))
#define XLogIsNeeded() (wal_level >= WAL_LEVEL_ARCHIVE)
/* Do we need to WAL-log information required only for Hot Standby? */
#define XLogStandbyInfoActive() (XLogRequestRecoveryConnections && XLogIsNeeded())
#define XLogStandbyInfoActive() (wal_level >= WAL_LEVEL_HOT_STANDBY)
#ifdef WAL_DEBUG
extern bool XLOG_DEBUG;
@ -293,7 +295,6 @@ extern void InitXLOGAccess(void);
extern void CreateCheckPoint(int flags);
extern bool CreateRestartPoint(int flags);
extern void XLogPutNextOid(Oid nextOid);
extern void XLogReportUnloggedStatement(char *reason);
extern XLogRecPtr GetRedoRecPtr(void);
extern XLogRecPtr GetInsertRecPtr(void);
extern XLogRecPtr GetWriteRecPtr(void);

View File

@ -11,7 +11,7 @@
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/access/xlog_internal.h,v 1.32 2010/04/12 10:40:43 heikki Exp $
* $PostgreSQL: pgsql/src/include/access/xlog_internal.h,v 1.33 2010/04/28 16:10:43 heikki Exp $
*/
#ifndef XLOG_INTERNAL_H
#define XLOG_INTERNAL_H
@ -71,7 +71,7 @@ typedef struct XLogContRecord
/*
* Each page of XLOG file has a header like this:
*/
#define XLOG_PAGE_MAGIC 0x9003 /* can be used as WAL version indicator */
#define XLOG_PAGE_MAGIC 0xD064 /* can be used as WAL version indicator */
typedef struct XLogPageHeaderData
{

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/catalog/pg_control.h,v 1.53 2010/04/23 20:21:31 sriggs Exp $
* $PostgreSQL: pgsql/src/include/catalog/pg_control.h,v 1.54 2010/04/28 16:10:43 heikki Exp $
*
*-------------------------------------------------------------------------
*/
@ -21,7 +21,7 @@
/* Version identifier for this pg_control format */
#define PG_CONTROL_VERSION 901
#define PG_CONTROL_VERSION 902
/*
* Body of CheckPoint XLOG records. This is declared here because we keep
@ -41,12 +41,6 @@ typedef struct CheckPoint
Oid oldestXidDB; /* database with minimum datfrozenxid */
pg_time_t time; /* time stamp of checkpoint */
/* Important parameter settings at time of shutdown checkpoints */
int MaxConnections;
int max_prepared_xacts;
int max_locks_per_xact;
bool XLogStandbyInfoMode;
/*
* Oldest XID still running. This is only needed to initialize hot standby
* mode from an online checkpoint, so we only bother calculating this for
@ -63,7 +57,7 @@ typedef struct CheckPoint
#define XLOG_NEXTOID 0x30
#define XLOG_SWITCH 0x40
#define XLOG_BACKUP_END 0x50
#define XLOG_UNLOGGED 0x60
#define XLOG_PARAMETER_CHANGE 0x60
/* System status indicator */
@ -141,6 +135,15 @@ typedef struct ControlFileData
XLogRecPtr minRecoveryPoint;
XLogRecPtr backupStartPoint;
/*
* Parameter settings that determine if the WAL can be used for archival
* or hot standby.
*/
int wal_level;
int MaxConnections;
int max_prepared_xacts;
int max_locks_per_xact;
/*
* This data is used to check for hardware-architecture compatibility of
* the database and the backend executable. We need not check endianness

View File

@ -5,7 +5,7 @@
*
* Portions Copyright (c) 2010-2010, PostgreSQL Global Development Group
*
* $PostgreSQL: pgsql/src/include/replication/walsender.h,v 1.2 2010/02/26 02:01:27 momjian Exp $
* $PostgreSQL: pgsql/src/include/replication/walsender.h,v 1.3 2010/04/28 16:10:43 heikki Exp $
*
*-------------------------------------------------------------------------
*/
@ -39,6 +39,7 @@ extern bool am_walsender;
/* user-settable parameters */
extern int WalSndDelay;
extern int max_wal_senders;
extern int WalSenderMain(void);
extern void WalSndSignals(void);