Commit 9b8a7332 authored by Heikki Linnakangas's avatar Heikki Linnakangas

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.
parent a2de4826
<!-- $PostgreSQL: pgsql/doc/src/sgml/backup.sgml,v 2.152 2010/04/20 00:26:06 rhaas Exp $ --> <!-- $PostgreSQL: pgsql/doc/src/sgml/backup.sgml,v 2.153 2010/04/28 16:10:39 heikki Exp $ -->
<chapter id="backup"> <chapter id="backup">
<title>Backup and Restore</title> <title>Backup and Restore</title>
...@@ -689,8 +689,7 @@ archive_command = 'test ! -f /mnt/server/archivedir/%f &amp;&amp; cp %p /mnt/ser ...@@ -689,8 +689,7 @@ archive_command = 'test ! -f /mnt/server/archivedir/%f &amp;&amp; cp %p /mnt/ser
</para> </para>
<para> <para>
When <varname>archive_mode</> is <literal>off</> and <xref When <varname>wal_level</> is <literal>minimal</> some SQL commands
linkend="guc-max-wal-senders"> is zero some SQL commands
are optimized to avoid WAL logging, as described in <xref are optimized to avoid WAL logging, as described in <xref
linkend="populate-pitr">. If archiving or streaming replication were linkend="populate-pitr">. If archiving or streaming replication were
turned on during execution of one of these statements, WAL would not turned on during execution of one of these statements, WAL would not
......
<!-- $PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.270 2010/04/26 10:51:59 rhaas Exp $ --> <!-- $PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.271 2010/04/28 16:10:39 heikki Exp $ -->
<chapter Id="runtime-config"> <chapter Id="runtime-config">
<title>Server Configuration</title> <title>Server Configuration</title>
...@@ -1353,6 +1353,45 @@ SET ENABLE_SEQSCAN TO OFF; ...@@ -1353,6 +1353,45 @@ SET ENABLE_SEQSCAN TO OFF;
<title>Settings</title> <title>Settings</title>
<variablelist> <variablelist>
<varlistentry id="guc-wal-level" xreflabel="wal_level">
<term><varname>wal_level</varname> (<type>enum</type>)</term>
<indexterm>
<primary><varname>wal_level</> configuration parameter</primary>
</indexterm>
<listitem>
<para>
<varname>wal_level</> determines how much information is written
to the WAL. The default value is <literal>minimal</>, which writes
only minimal information needed to recover from a crash or immediate
shutdown. <literal>archive</> adds logging required for WAL archiving,
and <literal>hot_standby</> further adds information required to run
read-only queries on a standby server.
This parameter can only be set at server start.
</para>
<para>
In <literal>minimal</> level, WAL-logging of some bulk operations, like
<command>CREATE INDEX</>, <command>CLUSTER</> and <command>COPY</> on
a table that was created or truncated in the same transaction can be
safely skipped, which can make those operations much faster (see
<xref linkend="populate-pitr">). But minimal WAL does not contain
enough information to reconstruct the data from a base backup and the
WAL logs, so at least <literal>archive</> level must be used to enable
WAL archiving (<xref linkend="guc-archive-mode">) and streaming
replication.
</para>
<para>
In <literal>hot_standby</> level, the same information is logged as
with <literal>archive</>, plus information needed to reconstruct
the status of running transactions from the WAL. To enable read-only
queries on a standby server, <varname>wal_level</> must be set to
<literal>hot_standby</> on the primary. It is thought that there is
little measurable difference in performance from using
<literal>hot_standby</> level over <literal>archive</>, so feedback
is welcome if any production impacts are noticeable.
</para>
</listitem>
</varlistentry>
<varlistentry id="guc-fsync" xreflabel="fsync"> <varlistentry id="guc-fsync" xreflabel="fsync">
<indexterm> <indexterm>
<primary><varname>fsync</> configuration parameter</primary> <primary><varname>fsync</> configuration parameter</primary>
...@@ -1726,7 +1765,9 @@ SET ENABLE_SEQSCAN TO OFF; ...@@ -1726,7 +1765,9 @@ SET ENABLE_SEQSCAN TO OFF;
<varname>archive_mode</> and <varname>archive_command</> are <varname>archive_mode</> and <varname>archive_command</> are
separate variables so that <varname>archive_command</> can be separate variables so that <varname>archive_command</> can be
changed without leaving archiving mode. changed without leaving archiving mode.
This parameter can only be set at server start. This parameter can only be set at server start. <varname>wal_level</>
must be set to <literal>archive</> or <literal>hot_standby</> to
enable <varname>archive_mode</>.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
...@@ -1818,7 +1859,9 @@ SET ENABLE_SEQSCAN TO OFF; ...@@ -1818,7 +1859,9 @@ SET ENABLE_SEQSCAN TO OFF;
Specifies the maximum number of concurrent connections from standby Specifies the maximum number of concurrent connections from standby
servers (i.e., the maximum number of simultaneously running WAL sender servers (i.e., the maximum number of simultaneously running WAL sender
processes). The default is zero. This parameter can only be set at processes). The default is zero. This parameter can only be set at
server start. server start. <varname>wal_level</> must be set to <literal>archive</>
or <literal>hot_standby</> to allow connections from standby
connections.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
...@@ -1884,16 +1927,11 @@ SET ENABLE_SEQSCAN TO OFF; ...@@ -1884,16 +1927,11 @@ SET ENABLE_SEQSCAN TO OFF;
</indexterm> </indexterm>
<listitem> <listitem>
<para> <para>
Parameter has two roles. During recovery, specifies whether or not Specifies whether or not you can connect and run queries during
you can connect and run queries to enable <xref linkend="hot-standby">. recovery, for <xref linkend="hot-standby">. The default value is
During normal running, specifies whether additional information is written <literal>on</literal>.
to WAL to allow recovery connections on a standby server that reads This parameter can only be set at server start. It only has effect
WAL data generated by this server. The default value is during archive recovery or in standby mode.
<literal>on</literal>. It is thought that there is little
measurable difference in performance from using this feature, so
feedback is welcome if any production impacts are noticeable.
It is likely that this parameter will be removed in later releases.
This parameter can only be set at server start.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
......
<!-- $PostgreSQL: pgsql/doc/src/sgml/high-availability.sgml,v 1.63 2010/04/26 19:09:25 momjian Exp $ --> <!-- $PostgreSQL: pgsql/doc/src/sgml/high-availability.sgml,v 1.64 2010/04/28 16:10:40 heikki Exp $ -->
<chapter id="high-availability"> <chapter id="high-availability">
<title>High Availability, Load Balancing, and Replication</title> <title>High Availability, Load Balancing, and Replication</title>
...@@ -1593,9 +1593,9 @@ LOG: database system is ready to accept read only connections ...@@ -1593,9 +1593,9 @@ LOG: database system is ready to accept read only connections
</programlisting> </programlisting>
Consistency information is recorded once per checkpoint on the primary, as long Consistency information is recorded once per checkpoint on the primary, as long
as <varname>recovery_connections</> is enabled on the primary. It is not possible as <varname>wal_level</> is set to <literal>hot_standby</> on the primary. It is not possible
to enable recovery connections on the standby when reading WAL written during the to enable recovery connections on the standby when reading WAL written during the
period that <varname>recovery_connections</> was disabled on the primary. period that <varname>wal_level</> was not set to <literal>hot_standby</> on the primary.
Reaching a consistent state can also be delayed in the presence Reaching a consistent state can also be delayed in the presence
of both of these conditions: of both of these conditions:
...@@ -1842,7 +1842,7 @@ LOG: database system is ready to accept read only connections ...@@ -1842,7 +1842,7 @@ LOG: database system is ready to accept read only connections
</para> </para>
<para> <para>
On the primary, parameters <varname>recovery_connections</> and On the primary, parameters <varname>wal_level</> and
<varname>vacuum_defer_cleanup_age</> can be used. <varname>vacuum_defer_cleanup_age</> can be used.
<varname>max_standby_delay</> has no effect if set on the primary. <varname>max_standby_delay</> has no effect if set on the primary.
</para> </para>
......
<!-- $PostgreSQL: pgsql/doc/src/sgml/perform.sgml,v 1.76 2010/04/20 00:26:06 rhaas Exp $ --> <!-- $PostgreSQL: pgsql/doc/src/sgml/perform.sgml,v 1.77 2010/04/28 16:10:40 heikki Exp $ -->
<chapter id="performance-tips"> <chapter id="performance-tips">
<title>Performance Tips</title> <title>Performance Tips</title>
...@@ -835,10 +835,9 @@ SELECT * FROM x, y, a, b, c WHERE something AND somethingelse; ...@@ -835,10 +835,9 @@ SELECT * FROM x, y, a, b, c WHERE something AND somethingelse;
<command>TRUNCATE</command> command. In such cases no WAL <command>TRUNCATE</command> command. In such cases no WAL
needs to be written, because in case of an error, the files needs to be written, because in case of an error, the files
containing the newly loaded data will be removed anyway. containing the newly loaded data will be removed anyway.
However, this consideration does not apply when However, this consideration only applies when
<xref linkend="guc-archive-mode"> is on or streaming replication <xref linkend="guc-wal-level"> is <literal>minimal</> as all commands
is allowed (i.e., <xref linkend="guc-max-wal-senders"> is more must write WAL otherwise.
than or equal to one), as all commands must write WAL in that case.
</para> </para>
</sect2> </sect2>
...@@ -910,29 +909,27 @@ SELECT * FROM x, y, a, b, c WHERE something AND somethingelse; ...@@ -910,29 +909,27 @@ SELECT * FROM x, y, a, b, c WHERE something AND somethingelse;
</sect2> </sect2>
<sect2 id="populate-pitr"> <sect2 id="populate-pitr">
<title>Turn off <varname>archive_mode</varname> and streaming replication</title> <title>Disable WAL archival and streaming replication</title>
<para> <para>
When loading large amounts of data into an installation that uses When loading large amounts of data into an installation that uses
WAL archiving or streaming replication, you might want to disable WAL archiving or streaming replication, it might be faster to take a
archiving (turn off the <xref linkend="guc-archive-mode"> new base backup after the load has completed than to process a large
configuration variable) and replication (zero the amount of incremental WAL data. You might want to disable archiving
<xref linkend="guc-max-wal-senders"> configuration variable) and streaming replication while loading, by setting
while loading. It might be <xref linkend="guc-wal-level"> to <literal>minimal</>,
faster to take a new base backup after the load has completed <xref linkend="guc-archive-mode"> <literal>off</>, and
than to process a large amount of incremental WAL data. <xref linkend="guc-max-wal-senders"> to zero).
But note that changing either of these variables requires But note that changing these settings requires a server restart.
a server restart.
</para> </para>
<para> <para>
Aside from avoiding the time for the archiver or WAL sender to Aside from avoiding the time for the archiver or WAL sender to
process the WAL data, process the WAL data,
doing this will actually make certain commands faster, because they doing this will actually make certain commands faster, because they
are designed not to write WAL at all if <varname>archive_mode</varname> are designed not to write WAL at all if <varname>wal_level</varname>
is off and <varname>max_wal_senders</varname> is zero. (They can is <literal>minimal</>. (They can guarantee crash safety more cheaply
guarantee crash safety more cheaply by doing an by doing an <function>fsync</> at the end than by writing WAL.)
<function>fsync</> at the end than by writing WAL.)
This applies to the following commands: This applies to the following commands:
<itemizedlist> <itemizedlist>
<listitem> <listitem>
...@@ -1014,10 +1011,12 @@ SELECT * FROM x, y, a, b, c WHERE something AND somethingelse; ...@@ -1014,10 +1011,12 @@ SELECT * FROM x, y, a, b, c WHERE something AND somethingelse;
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
If using WAL archiving, consider disabling it during the restore. If using WAL archiving or streaming replication, consider disabling
To do that, turn off <varname>archive_mode</varname> before loading the them during the restore. To do that, set <varname>arcive_mode</> off,
dump script, and afterwards turn it back on <varname>wal_level</varname> to <literal>minimal</>, and
and take a fresh base backup. <varname>max_wal_senders</> zero before loading the dump script,
and afterwards set them back to the right values and take a fresh
base backup.
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
......
...@@ -96,7 +96,7 @@ ...@@ -96,7 +96,7 @@
* Portions Copyright (c) 1994-5, Regents of the University of California * Portions Copyright (c) 1994-5, Regents of the University of California
* *
* IDENTIFICATION * 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) ...@@ -278,16 +278,6 @@ end_heap_rewrite(RewriteState state)
(char *) state->rs_buffer, true); (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 * If the rel isn't temp, must fsync before commit. We use heap_sync to
* ensure that the toast table gets fsync'd too. * ensure that the toast table gets fsync'd too.
......
...@@ -59,7 +59,7 @@ ...@@ -59,7 +59,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * 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) ...@@ -215,19 +215,6 @@ _bt_leafbuild(BTSpool *btspool, BTSpool *btspool2)
*/ */
wstate.btws_use_wal = XLogIsNeeded() && !wstate.index->rd_istemp; 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 */ /* reserve the metapage */
wstate.btws_pages_alloced = BTREE_METAPAGE + 1; wstate.btws_pages_alloced = BTREE_METAPAGE + 1;
wstate.btws_pages_written = 0; wstate.btws_pages_written = 0;
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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; ...@@ -76,6 +76,7 @@ int MaxStandbyDelay = 30;
bool fullPageWrites = true; bool fullPageWrites = true;
bool log_checkpoints = false; bool log_checkpoints = false;
int sync_method = DEFAULT_SYNC_METHOD; int sync_method = DEFAULT_SYNC_METHOD;
int wal_level = WAL_LEVEL_MINIMAL;
#ifdef WAL_DEBUG #ifdef WAL_DEBUG
bool XLOG_DEBUG = false; bool XLOG_DEBUG = false;
...@@ -97,6 +98,13 @@ bool XLOG_DEBUG = false; ...@@ -97,6 +98,13 @@ bool XLOG_DEBUG = false;
/* /*
* GUC support * 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[] = { const struct config_enum_entry sync_method_options[] = {
{"fsync", SYNC_METHOD_FSYNC, false}, {"fsync", SYNC_METHOD_FSYNC, false},
#ifdef HAVE_FSYNC_WRITETHROUGH #ifdef HAVE_FSYNC_WRITETHROUGH
...@@ -500,6 +508,18 @@ static bool reachedMinRecoveryPoint = false; ...@@ -500,6 +508,18 @@ static bool reachedMinRecoveryPoint = false;
static bool InRedo = 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. * Flags set by interrupt handlers for later service in the redo loop.
*/ */
...@@ -522,7 +542,8 @@ static void readRecoveryCommandFile(void); ...@@ -522,7 +542,8 @@ static void readRecoveryCommandFile(void);
static void exitArchiveRecovery(TimeLineID endTLI, static void exitArchiveRecovery(TimeLineID endTLI,
uint32 endLogId, uint32 endLogSeg); uint32 endLogId, uint32 endLogSeg);
static bool recoveryStopsHere(XLogRecord *record, bool *includeThis); 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 LocalSetXLogInsertAllowed(void);
static void CheckPointGuts(XLogRecPtr checkPointRedo, int flags); static void CheckPointGuts(XLogRecPtr checkPointRedo, int flags);
...@@ -4922,6 +4943,13 @@ BootStrapXLOG(void) ...@@ -4922,6 +4943,13 @@ BootStrapXLOG(void)
ControlFile->time = checkPoint.time; ControlFile->time = checkPoint.time;
ControlFile->checkPoint = checkPoint.redo; ControlFile->checkPoint = checkPoint.redo;
ControlFile->checkPointCopy = checkPoint; 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() */ /* some additional ControlFile fields are set in WriteControlFile() */
WriteControlFile(); WriteControlFile();
...@@ -5539,17 +5567,18 @@ GetLatestXLogTime(void) ...@@ -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, \ ereport(ERROR, \
(errmsg("recovery connections cannot continue because " \ (errmsg("recovery connections cannot continue because " \
"%s = %u is a lower setting than on WAL source server (value was %u)", \ "%s = %u is a lower setting than on WAL source server (value was %u)", \
param_name, \ param_name, \
currValue, \ currValue, \
checkpointValue))); \ minValue))); \
} }
/* /*
...@@ -5557,21 +5586,37 @@ GetLatestXLogTime(void) ...@@ -5557,21 +5586,37 @@ GetLatestXLogTime(void)
* for various aspects of recovery operation. * for various aspects of recovery operation.
*/ */
static void static void
CheckRequiredParameterValues(CheckPoint checkPoint) CheckRequiredParameterValues(void)
{ {
/* We ignore autovacuum_max_workers when we make this test. */ /*
RecoveryRequiresIntParameter("max_connections", * For archive recovery, the WAL must be generated with at least
MaxConnections, checkPoint.MaxConnections); * '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); * For Hot Standby, the WAL must be generated with 'hot_standby' mode,
RecoveryRequiresIntParameter("max_locks_per_xact", * and we must have at least as many backend slots as the primary.
max_locks_per_xact, checkPoint.max_locks_per_xact); */
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) /* We ignore autovacuum_max_workers when we make this test. */
ereport(ERROR, RecoveryRequiresIntParameter("max_connections",
(errmsg("recovery connections cannot start because the recovery_connections " MaxConnections, ControlFile->MaxConnections);
"parameter is disabled on the WAL source server"))); 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) ...@@ -5904,6 +5949,9 @@ StartupXLOG(void)
BACKUP_LABEL_FILE, BACKUP_LABEL_OLD))); 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 * Initialize recovery connections, if enabled. We won't let backends
* in yet, not until we've reached the min recovery point specified in * in yet, not until we've reached the min recovery point specified in
...@@ -5915,8 +5963,6 @@ StartupXLOG(void) ...@@ -5915,8 +5963,6 @@ StartupXLOG(void)
TransactionId *xids; TransactionId *xids;
int nxids; int nxids;
CheckRequiredParameterValues(checkPoint);
ereport(DEBUG1, ereport(DEBUG1,
(errmsg("initializing recovery connections"))); (errmsg("initializing recovery connections")));
...@@ -6400,6 +6446,13 @@ StartupXLOG(void) ...@@ -6400,6 +6446,13 @@ StartupXLOG(void)
readRecordBufSize = 0; 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 * 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 * probably atomic in itself, we use the info_lck here to ensure that
...@@ -6998,12 +7051,6 @@ CreateCheckPoint(int flags) ...@@ -6998,12 +7051,6 @@ CreateCheckPoint(int flags)
MemSet(&checkPoint, 0, sizeof(checkPoint)); MemSet(&checkPoint, 0, sizeof(checkPoint));
checkPoint.time = (pg_time_t) time(NULL); 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 * We must hold WALInsertLock while examining insert state to determine
* the checkpoint REDO pointer. * the checkpoint REDO pointer.
...@@ -7647,28 +7694,49 @@ RequestXLogSwitch(void) ...@@ -7647,28 +7694,49 @@ RequestXLogSwitch(void)
} }
/* /*
* Write an XLOG UNLOGGED record, indicating that some operation was * Check if any of the GUC parameters that are critical for hot standby
* performed on data that we fsync()'d directly to disk, skipping * have changed, and update the value in pg_control file if necessary.
* 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.
*/ */
void static void
XLogReportUnloggedStatement(char *reason) 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; xlrec.MaxConnections = MaxConnections;
rdata.data = reason; xlrec.max_prepared_xacts = max_prepared_xacts;
rdata.len = strlen(reason) + 1; xlrec.max_locks_per_xact = max_locks_per_xact;
rdata.next = NULL; xlrec.wal_level = wal_level;
rdata.buffer = InvalidBuffer;
rdata.data = (char *) &xlrec;
rdata.len = sizeof(xlrec);
rdata.next = NULL;
XLogInsert(RM_XLOG_ID, XLOG_PARAMETER_CHANGE, &rdata);
}
XLogInsert(RM_XLOG_ID, XLOG_UNLOGGED, &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) ...@@ -7709,10 +7777,6 @@ xlog_redo(XLogRecPtr lsn, XLogRecord *record)
checkPoint.nextMultiOffset); checkPoint.nextMultiOffset);
SetTransactionIdLimit(checkPoint.oldestXid, checkPoint.oldestXidDB); 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 * If we see a shutdown checkpoint while waiting for an
* end-of-backup record, the backup was cancelled and the * end-of-backup record, the backup was cancelled and the
...@@ -7844,18 +7908,21 @@ xlog_redo(XLogRecPtr lsn, XLogRecord *record) ...@@ -7844,18 +7908,21 @@ xlog_redo(XLogRecPtr lsn, XLogRecord *record)
LWLockRelease(ControlFileLock); LWLockRelease(ControlFileLock);
} }
} }
else if (info == XLOG_UNLOGGED) else if (info == XLOG_PARAMETER_CHANGE)
{ {
if (InArchiveRecovery) xl_parameter_change xlrec;
{
/* /* Update our copy of the parameters in pg_control */
* Note: We don't print the reason string from the record, because memcpy(&xlrec, XLogRecGetData(record), sizeof(xl_parameter_change));
* that gets added as a line using xlog_desc()
*/ ControlFile->MaxConnections = xlrec.MaxConnections;
ereport(WARNING, ControlFile->max_prepared_xacts = xlrec.max_prepared_xacts;
(errmsg("unlogged operation performed, data may be missing"), ControlFile->max_locks_per_xact = xlrec.max_locks_per_xact;
errhint("This can happen if you temporarily disable archive_mode without taking a new base backup."))); 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) ...@@ -7906,11 +7973,30 @@ xlog_desc(StringInfo buf, uint8 xl_info, char *rec)
appendStringInfo(buf, "backup end: %X/%X", appendStringInfo(buf, "backup end: %X/%X",
startpoint.xlogid, startpoint.xrecoff); 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;
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, "unlogged operation: %s", reason); 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 else
appendStringInfo(buf, "UNKNOWN"); appendStringInfo(buf, "UNKNOWN");
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* *
* *
* IDENTIFICATION * 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, ...@@ -787,23 +787,6 @@ copy_heap_data(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex,
*/ */
use_wal = XLogIsNeeded() && !NewHeap->rd_istemp; 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 */ /* use_wal off requires smgr_targblock be initially invalid */
Assert(RelationGetTargetBlock(NewHeap) == InvalidBlockNumber); Assert(RelationGetTargetBlock(NewHeap) == InvalidBlockNumber);
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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) ...@@ -2223,14 +2223,7 @@ CopyFrom(CopyState cstate)
* indexes since those use WAL anyway) * indexes since those use WAL anyway)
*/ */
if (hi_options & HEAP_INSERT_SKIP_WAL) 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); heap_sync(cstate->rel);
}
} }
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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) ...@@ -3272,14 +3272,7 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap)
/* If we skipped writing WAL, then we need to sync the heap. */ /* If we skipped writing WAL, then we need to sync the heap. */
if (hi_options & HEAP_INSERT_SKIP_WAL) 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_sync(newrel);
}
heap_close(newrel, NoLock); heap_close(newrel, NoLock);
} }
...@@ -7021,20 +7014,6 @@ ATExecSetTableSpace(Oid tableOid, Oid newTableSpace) ...@@ -7021,20 +7014,6 @@ ATExecSetTableSpace(Oid tableOid, Oid newTableSpace)
heap_close(pg_class, RowExclusiveLock); 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); relation_close(rel, NoLock);
/* Make sure the reltablespace change is visible */ /* Make sure the reltablespace change is visible */
...@@ -7063,10 +7042,6 @@ copy_relation_data(SMgrRelation src, SMgrRelation dst, ...@@ -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 * We need to log the copied data in WAL iff WAL archiving/streaming is
* enabled AND it's not a temp rel. * 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; use_wal = XLogIsNeeded() && !istemp;
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
* *
* *
* IDENTIFICATION * 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) ...@@ -2241,14 +2241,7 @@ CloseIntoRel(QueryDesc *queryDesc)
/* If we skipped using WAL, must heap_sync before commit */ /* If we skipped using WAL, must heap_sync before commit */
if (myState->hi_options & HEAP_INSERT_SKIP_WAL) 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); heap_sync(myState->rel);
}
/* close rel, but keep lock until commit */ /* close rel, but keep lock until commit */
heap_close(myState->rel, NoLock); heap_close(myState->rel, NoLock);
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
* *
* *
* IDENTIFICATION * 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 * NOTES
* *
...@@ -728,6 +728,12 @@ PostmasterMain(int argc, char *argv[]) ...@@ -728,6 +728,12 @@ PostmasterMain(int argc, char *argv[])
write_stderr("%s: superuser_reserved_connections must be less than max_connections\n", progname); write_stderr("%s: superuser_reserved_connections must be less than max_connections\n", progname);
ExitPostmaster(1); 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. * Other one-time internal sanity checks can go here, if they are fast.
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
* *
* *
* IDENTIFICATION * 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) ...@@ -253,6 +253,24 @@ WalSndHandshake(void)
{ {
StringInfoData buf; 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 */ /* Send a CopyOutResponse message, and start streaming */
pq_beginmessage(&buf, 'H'); pq_beginmessage(&buf, 'H');
pq_sendbyte(&buf, 0); pq_sendbyte(&buf, 0);
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * 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 ...@@ -256,7 +256,7 @@ ResolveRecoveryConflictWithSnapshot(TransactionId latestRemovedXid, RelFileNode
*/ */
if (!TransactionIdIsValid(latestRemovedXid)) if (!TransactionIdIsValid(latestRemovedXid))
{ {
elog(DEBUG1, "Invalid latestremovexXid reported, using latestcompletedxid instead"); elog(DEBUG1, "invalid latestremovexXid reported, using latestcompletedxid instead");
LWLockAcquire(ProcArrayLock, LW_SHARED); LWLockAcquire(ProcArrayLock, LW_SHARED);
latestRemovedXid = ShmemVariableCache->latestCompletedXid; latestRemovedXid = ShmemVariableCache->latestCompletedXid;
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
* Written by Peter Eisentraut <peter_e@gmx.net>. * Written by Peter Eisentraut <peter_e@gmx.net>.
* *
* IDENTIFICATION * 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[] = { ...@@ -340,6 +340,7 @@ static const struct config_enum_entry constraint_exclusion_options[] = {
/* /*
* Options for enum values stored in other modules * 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[]; extern const struct config_enum_entry sync_method_options[];
/* /*
...@@ -2784,6 +2785,15 @@ static struct config_enum ConfigureNamesEnum[] = ...@@ -2784,6 +2785,15 @@ static struct config_enum ConfigureNamesEnum[] =
TRACK_FUNC_OFF, track_function_options, NULL, NULL 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, {"wal_sync_method", PGC_SIGHUP, WAL_SETTINGS,
gettext_noop("Selects the method used for forcing WAL updates to disk."), gettext_noop("Selects the method used for forcing WAL updates to disk."),
...@@ -7862,7 +7872,7 @@ pg_timezone_abbrev_initialize(void) ...@@ -7862,7 +7872,7 @@ pg_timezone_abbrev_initialize(void)
static const char * static const char *
show_archive_command(void) show_archive_command(void)
{ {
if (XLogArchiveMode) if (XLogArchivingActive())
return XLogArchiveCommand; return XLogArchiveCommand;
else else
return "(disabled)"; return "(disabled)";
......
...@@ -150,6 +150,7 @@ ...@@ -150,6 +150,7 @@
# - Settings - # - Settings -
#wal_level = minimal # minimal, archive, or hot_standby
#fsync = on # turns forced synchronization on or off #fsync = on # turns forced synchronization on or off
#synchronous_commit = on # immediate fsync at commit #synchronous_commit = on # immediate fsync at commit
#wal_sync_method = fsync # the default is the first option #wal_sync_method = fsync # the default is the first option
......
...@@ -6,15 +6,16 @@ ...@@ -6,15 +6,16 @@
* copyright (c) Oliver Elphick <olly@lfix.co.uk>, 2001; * copyright (c) Oliver Elphick <olly@lfix.co.uk>, 2001;
* licence: BSD * 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 <unistd.h>
#include <time.h> #include <time.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <fcntl.h> #include <fcntl.h>
#include "access/xlog.h"
#include "catalog/pg_control.h" #include "catalog/pg_control.h"
...@@ -60,6 +61,21 @@ dbState(DBState state) ...@@ -60,6 +61,21 @@ dbState(DBState state)
return _("unrecognized status code"); 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 int
main(int argc, char *argv[]) main(int argc, char *argv[])
...@@ -206,6 +222,14 @@ main(int argc, char *argv[]) ...@@ -206,6 +222,14 @@ main(int argc, char *argv[])
printf(_("Backup start location: %X/%X\n"), printf(_("Backup start location: %X/%X\n"),
ControlFile.backupStartPoint.xlogid, ControlFile.backupStartPoint.xlogid,
ControlFile.backupStartPoint.xrecoff); 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"), printf(_("Maximum data alignment: %u\n"),
ControlFile.maxAlign); ControlFile.maxAlign);
/* we don't print floatFormat since can't say much useful about it */ /* we don't print floatFormat since can't say much useful about it */
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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) ...@@ -628,6 +628,15 @@ RewriteControlFile(void)
ControlFile.backupStartPoint.xlogid = 0; ControlFile.backupStartPoint.xlogid = 0;
ControlFile.backupStartPoint.xrecoff = 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. */ /* Now we can force the recorded xlog seg size to the right thing. */
ControlFile.xlog_seg_size = XLogSegSize; ControlFile.xlog_seg_size = XLogSegSize;
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 #ifndef XLOG_H
#define XLOG_H #define XLOG_H
...@@ -195,24 +195,26 @@ extern int XLogArchiveTimeout; ...@@ -195,24 +195,26 @@ extern int XLogArchiveTimeout;
extern bool log_checkpoints; extern bool log_checkpoints;
extern bool XLogRequestRecoveryConnections; extern bool XLogRequestRecoveryConnections;
extern int MaxStandbyDelay; 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') #define XLogArchiveCommandSet() (XLogArchiveCommand[0] != '\0')
/* /*
* This is in walsender.c, but declared here so that we don't need to include * Is WAL-logging necessary for archival or log-shipping, or can we skip
* walsender.h in all files that check XLogIsNeeded() * 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? */ /* 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 #ifdef WAL_DEBUG
extern bool XLOG_DEBUG; extern bool XLOG_DEBUG;
...@@ -293,7 +295,6 @@ extern void InitXLOGAccess(void); ...@@ -293,7 +295,6 @@ extern void InitXLOGAccess(void);
extern void CreateCheckPoint(int flags); extern void CreateCheckPoint(int flags);
extern bool CreateRestartPoint(int flags); extern bool CreateRestartPoint(int flags);
extern void XLogPutNextOid(Oid nextOid); extern void XLogPutNextOid(Oid nextOid);
extern void XLogReportUnloggedStatement(char *reason);
extern XLogRecPtr GetRedoRecPtr(void); extern XLogRecPtr GetRedoRecPtr(void);
extern XLogRecPtr GetInsertRecPtr(void); extern XLogRecPtr GetInsertRecPtr(void);
extern XLogRecPtr GetWriteRecPtr(void); extern XLogRecPtr GetWriteRecPtr(void);
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 #ifndef XLOG_INTERNAL_H
#define XLOG_INTERNAL_H #define XLOG_INTERNAL_H
...@@ -71,7 +71,7 @@ typedef struct XLogContRecord ...@@ -71,7 +71,7 @@ typedef struct XLogContRecord
/* /*
* Each page of XLOG file has a header like this: * 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 typedef struct XLogPageHeaderData
{ {
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 @@ ...@@ -21,7 +21,7 @@
/* Version identifier for this pg_control format */ /* 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 * Body of CheckPoint XLOG records. This is declared here because we keep
...@@ -41,12 +41,6 @@ typedef struct CheckPoint ...@@ -41,12 +41,6 @@ typedef struct CheckPoint
Oid oldestXidDB; /* database with minimum datfrozenxid */ Oid oldestXidDB; /* database with minimum datfrozenxid */
pg_time_t time; /* time stamp of checkpoint */ 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 * Oldest XID still running. This is only needed to initialize hot standby
* mode from an online checkpoint, so we only bother calculating this for * mode from an online checkpoint, so we only bother calculating this for
...@@ -63,7 +57,7 @@ typedef struct CheckPoint ...@@ -63,7 +57,7 @@ typedef struct CheckPoint
#define XLOG_NEXTOID 0x30 #define XLOG_NEXTOID 0x30
#define XLOG_SWITCH 0x40 #define XLOG_SWITCH 0x40
#define XLOG_BACKUP_END 0x50 #define XLOG_BACKUP_END 0x50
#define XLOG_UNLOGGED 0x60 #define XLOG_PARAMETER_CHANGE 0x60
/* System status indicator */ /* System status indicator */
...@@ -141,6 +135,15 @@ typedef struct ControlFileData ...@@ -141,6 +135,15 @@ typedef struct ControlFileData
XLogRecPtr minRecoveryPoint; XLogRecPtr minRecoveryPoint;
XLogRecPtr backupStartPoint; 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 * This data is used to check for hardware-architecture compatibility of
* the database and the backend executable. We need not check endianness * the database and the backend executable. We need not check endianness
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* *
* Portions Copyright (c) 2010-2010, PostgreSQL Global Development Group * 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; ...@@ -39,6 +39,7 @@ extern bool am_walsender;
/* user-settable parameters */ /* user-settable parameters */
extern int WalSndDelay; extern int WalSndDelay;
extern int max_wal_senders;
extern int WalSenderMain(void); extern int WalSenderMain(void);
extern void WalSndSignals(void); extern void WalSndSignals(void);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment