diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index 6b45299a16dbc40129eb2c64dd1a59f12459ccd4..3c683210d4b414585efbd27543e3e9dc3f577506 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1,5 +1,5 @@ <!-- -$PostgreSQL: pgsql/doc/src/sgml/runtime.sgml,v 1.335 2005/07/02 19:16:36 momjian Exp $ +$PostgreSQL: pgsql/doc/src/sgml/runtime.sgml,v 1.336 2005/07/05 23:18:09 momjian Exp $ --> <chapter Id="runtime"> @@ -1660,7 +1660,9 @@ SET ENABLE_SEQSCAN TO OFF; <para> This option can only be set at server start or in the - <filename>postgresql.conf</filename> file. + <filename>postgresql.conf</filename> file. If this option + is <literal>off</>, consider also turning off + <varname>guc-full-page-writes</>. </para> </listitem> </varlistentry> @@ -1687,6 +1689,37 @@ SET ENABLE_SEQSCAN TO OFF; </listitem> </varlistentry> + <varlistentry id="guc-full-page-writes" xreflabel="full_page_writes"> + <indexterm> + <primary><varname>full_page_writes</> configuration parameter</primary> + </indexterm> + <term><varname>full_page_writes</varname> (<type>boolean</type>)</term> + <listitem> + <para> + A page write in process during an operating system crash might + be only partially written to disk, leading to an on-disk page + that contains a mix of old and new data. During recovery, the + row changes stored in WAL are not enough to completely restore + the page. + </para> + + <para> + When this option is on, the <productname>PostgreSQL</> server + writes full pages to WAL when they first modified after a checkpoint + so full recovery is possible. Turning this option off might lead + to a corrupt system after an operating system crash because + uncorrected partial pages might contain inconsistent or corrupt + data. The risks are less but similar to <varname>fsync</>. + </para> + + <para> + This option can only be set at server start or in the + <filename>postgresql.conf</filename> file. The default is + <literal>on</>. + </para> + </listitem> + </varlistentry> + <varlistentry id="guc-wal-buffers" xreflabel="wal_buffers"> <term><varname>wal_buffers</varname> (<type>integer</type>)</term> <indexterm> diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index d42aa93c547318e0690bbe0743df325803bf707e..86e1e6878b8dcb62d39e163fa49a1a008660258f 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.206 2005/07/04 04:51:44 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.207 2005/07/05 23:18:09 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -103,6 +103,7 @@ int XLOGbuffers = 8; char *XLogArchiveCommand = NULL; char *XLOG_sync_method = NULL; const char XLOG_sync_method_default[] = DEFAULT_SYNC_METHOD_STR; +bool fullPageWrites = true; #ifdef WAL_DEBUG bool XLOG_DEBUG = false; @@ -594,7 +595,9 @@ begin:; { /* OK, put it in this slot */ dtbuf[i] = rdt->buffer; - if (XLogCheckBuffer(rdt, &(dtbuf_lsn[i]), &(dtbuf_xlg[i]))) + /* If fsync is off, no need to backup pages. */ + if (fullPageWrites && + XLogCheckBuffer(rdt, &(dtbuf_lsn[i]), &(dtbuf_xlg[i]))) { dtbuf_bkp[i] = true; rdt->data = NULL; diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index 0ea335770c330552164b3e112cda41ddcef780cf..ca59f6755b4d8f3966acbcdafd1a8583d2d00088 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -10,7 +10,7 @@ * Written by Peter Eisentraut <peter_e@gmx.net>. * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.272 2005/07/04 04:51:51 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.273 2005/07/05 23:18:10 momjian Exp $ * *-------------------------------------------------------------------- */ @@ -83,6 +83,7 @@ extern DLLIMPORT bool check_function_bodies; extern int CommitDelay; extern int CommitSiblings; extern char *default_tablespace; +extern bool fullPageWrites; static const char *assign_log_destination(const char *value, bool doit, GucSource source); @@ -482,6 +483,18 @@ static struct config_bool ConfigureNamesBool[] = &zero_damaged_pages, false, NULL, NULL }, + { + {"full_page_writes", PGC_SIGHUP, WAL_SETTINGS, + gettext_noop("Writes full pages to WAL when first modified after a checkpoint."), + gettext_noop("A page write in process during an operating system crash might be " + "only partially written to disk. During recovery, the row changes" + "stored in WAL are not enough to recover. This option writes " + "pages when first modified after a checkpoint to WAL so full recovery " + "is possible.") + }, + &fullPageWrites, + true, NULL, NULL + }, { {"silent_mode", PGC_POSTMASTER, LOGGING_WHEN, gettext_noop("Runs the server silently."), diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample index 4e7c9207ddc130b57c7a5c357e9872d0a2023dca..193b0303b38c070d7cd5224df094431067a579db 100644 --- a/src/backend/utils/misc/postgresql.conf.sample +++ b/src/backend/utils/misc/postgresql.conf.sample @@ -121,6 +121,7 @@ #wal_sync_method = fsync # the default varies across platforms: # fsync, fdatasync, fsync_writethrough, # open_sync, open_datasync +#full_page_writes = on # recover from partial page writes #wal_buffers = 8 # min 4, 8KB each #commit_delay = 0 # range 0-100000, in microseconds #commit_siblings = 5 # range 1-1000