diff options
author | Heikki Linnakangas <heikki.linnakangas@iki.fi> | 2015-05-15 18:55:24 +0300 |
---|---|---|
committer | Heikki Linnakangas <heikki.linnakangas@iki.fi> | 2015-05-15 18:55:24 +0300 |
commit | ffd37740ee6fcd434416ec0c5461f7040e0a11de (patch) | |
tree | 8426b73d24330acbe89def851bf639024915c596 /src | |
parent | f6d65f0c7068bab6a9ca55a82f18fd52e8fd1e5e (diff) | |
download | postgresql-ffd37740ee6fcd434416ec0c5461f7040e0a11de.tar.gz postgresql-ffd37740ee6fcd434416ec0c5461f7040e0a11de.zip |
Add archive_mode='always' option.
In 'always' mode, the standby independently archives all files it receives
from the primary.
Original patch by Fujii Masao, docs and review by me.
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/access/transam/xlog.c | 22 | ||||
-rw-r--r-- | src/backend/access/transam/xlogarchive.c | 5 | ||||
-rw-r--r-- | src/backend/postmaster/postmaster.c | 37 | ||||
-rw-r--r-- | src/backend/replication/walreceiver.c | 10 | ||||
-rw-r--r-- | src/backend/utils/misc/guc.c | 21 | ||||
-rw-r--r-- | src/backend/utils/misc/postgresql.conf.sample | 2 | ||||
-rw-r--r-- | src/include/access/xlog.h | 13 |
7 files changed, 83 insertions, 27 deletions
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 5f0551a3cbd..0485bb5201e 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -86,7 +86,7 @@ int min_wal_size = 5; /* 80 MB */ int wal_keep_segments = 0; int XLOGbuffers = -1; int XLogArchiveTimeout = 0; -bool XLogArchiveMode = false; +int XLogArchiveMode = ARCHIVE_MODE_OFF; char *XLogArchiveCommand = NULL; bool EnableHotStandby = false; bool fullPageWrites = true; @@ -140,6 +140,24 @@ const struct config_enum_entry sync_method_options[] = { {NULL, 0, false} }; + +/* + * Although only "on", "off", and "always" are documented, + * we accept all the likely variants of "on" and "off". + */ +const struct config_enum_entry archive_mode_options[] = { + {"always", ARCHIVE_MODE_ALWAYS, false}, + {"on", ARCHIVE_MODE_ON, false}, + {"off", ARCHIVE_MODE_OFF, false}, + {"true", ARCHIVE_MODE_ON, true}, + {"false", ARCHIVE_MODE_OFF, true}, + {"yes", ARCHIVE_MODE_ON, true}, + {"no", ARCHIVE_MODE_OFF, true}, + {"1", ARCHIVE_MODE_ON, true}, + {"0", ARCHIVE_MODE_OFF, true}, + {NULL, 0, false} +}; + /* * Statistics for current checkpoint are collected in this global struct. * Because only the checkpointer or a stand-alone backend can perform @@ -767,7 +785,7 @@ static MemoryContext walDebugCxt = NULL; #endif static void readRecoveryCommandFile(void); -static void exitArchiveRecovery(TimeLineID endTLI, XLogSegNo endLogSegNo); +static void exitArchiveRecovery(TimeLineID endTLI, XLogRecPtr endOfLog); static bool recoveryStopsBefore(XLogReaderState *record); static bool recoveryStopsAfter(XLogReaderState *record); static void recoveryPausesHere(void); diff --git a/src/backend/access/transam/xlogarchive.c b/src/backend/access/transam/xlogarchive.c index f435f65e98b..4c69b738bc1 100644 --- a/src/backend/access/transam/xlogarchive.c +++ b/src/backend/access/transam/xlogarchive.c @@ -480,7 +480,10 @@ KeepFileRestoredFromArchive(char *path, char *xlogfname) * Create .done file forcibly to prevent the restored segment from being * archived again later. */ - XLogArchiveForceDone(xlogfname); + if (XLogArchiveMode != ARCHIVE_MODE_ALWAYS) + XLogArchiveForceDone(xlogfname); + else + XLogArchiveNotify(xlogfname); /* * If the existing file was replaced, since walsenders might have it open, diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index a9f20ac1b44..36440cbdccd 100644 --- a/src/backend/postmaster/postmaster.c +++ b/src/backend/postmaster/postmaster.c @@ -828,9 +828,9 @@ PostmasterMain(int argc, char *argv[]) write_stderr("%s: max_wal_senders must be less than max_connections\n", progname); ExitPostmaster(1); } - if (XLogArchiveMode && wal_level == WAL_LEVEL_MINIMAL) + if (XLogArchiveMode > ARCHIVE_MODE_OFF && wal_level == WAL_LEVEL_MINIMAL) ereport(ERROR, - (errmsg("WAL archival (archive_mode=on) requires wal_level \"archive\", \"hot_standby\", or \"logical\""))); + (errmsg("WAL archival cannot be enabled when wal_level is \"minimal\""))); if (max_wal_senders > 0 && wal_level == WAL_LEVEL_MINIMAL) ereport(ERROR, (errmsg("WAL streaming (max_wal_senders > 0) requires wal_level \"archive\", \"hot_standby\", or \"logical\""))); @@ -1645,13 +1645,21 @@ ServerLoop(void) start_autovac_launcher = false; /* signal processed */ } - /* If we have lost the archiver, try to start a new one */ - if (XLogArchivingActive() && PgArchPID == 0 && pmState == PM_RUN) - PgArchPID = pgarch_start(); - - /* If we have lost the stats collector, try to start a new one */ - if (PgStatPID == 0 && pmState == PM_RUN) - PgStatPID = pgstat_start(); + /* + * If we have lost the archiver, try to start a new one. + * + * If WAL archiving is enabled always, we try to start a new archiver + * even during recovery. + */ + if (PgArchPID == 0 && wal_level >= WAL_LEVEL_ARCHIVE) + { + if ((pmState == PM_RUN && XLogArchiveMode > ARCHIVE_MODE_OFF) || + ((pmState == PM_RECOVERY || pmState == PM_HOT_STANDBY) && + XLogArchiveMode == ARCHIVE_MODE_ALWAYS)) + { + PgArchPID = pgarch_start(); + } + } /* If we need to signal the autovacuum launcher, do so now */ if (avlauncher_needs_signal) @@ -4807,6 +4815,17 @@ sigusr1_handler(SIGNAL_ARGS) Assert(BgWriterPID == 0); BgWriterPID = StartBackgroundWriter(); + /* + * Start the archiver if we're responsible for (re-)archiving received + * files. + */ + Assert(PgArchPID == 0); + if (wal_level >= WAL_LEVEL_ARCHIVE && + XLogArchiveMode == ARCHIVE_MODE_ALWAYS) + { + PgArchPID = pgarch_start(); + } + pmState = PM_RECOVERY; } if (CheckPostmasterSignal(PMSIGNAL_BEGIN_HOT_STANDBY) && diff --git a/src/backend/replication/walreceiver.c b/src/backend/replication/walreceiver.c index 9c7710f0dbd..41e57f24397 100644 --- a/src/backend/replication/walreceiver.c +++ b/src/backend/replication/walreceiver.c @@ -540,7 +540,10 @@ WalReceiverMain(void) * being archived later. */ XLogFileName(xlogfname, recvFileTLI, recvSegNo); - XLogArchiveForceDone(xlogfname); + if (XLogArchiveMode != ARCHIVE_MODE_ALWAYS) + XLogArchiveForceDone(xlogfname); + else + XLogArchiveNotify(xlogfname); } recvFile = -1; @@ -897,7 +900,10 @@ XLogWalRcvWrite(char *buf, Size nbytes, XLogRecPtr recptr) * from being archived later. */ XLogFileName(xlogfname, recvFileTLI, recvSegNo); - XLogArchiveForceDone(xlogfname); + if (XLogArchiveMode != ARCHIVE_MODE_ALWAYS) + XLogArchiveForceDone(xlogfname); + else + XLogArchiveNotify(xlogfname); } recvFile = -1; diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index 222228ae5a7..3038d7c9dda 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -396,6 +396,7 @@ static const struct config_enum_entry row_security_options[] = { * Options for enum values stored in other modules */ extern const struct config_enum_entry wal_level_options[]; +extern const struct config_enum_entry archive_mode_options[]; extern const struct config_enum_entry sync_method_options[]; extern const struct config_enum_entry dynamic_shared_memory_options[]; @@ -1530,16 +1531,6 @@ static struct config_bool ConfigureNamesBool[] = }, { - {"archive_mode", PGC_POSTMASTER, WAL_ARCHIVING, - gettext_noop("Allows archiving of WAL files using archive_command."), - NULL - }, - &XLogArchiveMode, - false, - NULL, NULL, NULL - }, - - { {"hot_standby", PGC_POSTMASTER, REPLICATION_STANDBY, gettext_noop("Allows connections and queries during recovery."), NULL @@ -3552,6 +3543,16 @@ static struct config_enum ConfigureNamesEnum[] = }, { + {"archive_mode", PGC_POSTMASTER, WAL_ARCHIVING, + gettext_noop("Allows archiving of WAL files using archive_command."), + NULL + }, + &XLogArchiveMode, + ARCHIVE_MODE_OFF, archive_mode_options, + NULL, NULL, NULL + }, + + { {"trace_recovery_messages", PGC_SIGHUP, DEVELOPER_OPTIONS, gettext_noop("Enables logging of recovery-related debugging information."), gettext_noop("Each level includes all the levels that follow it. The later" diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample index 110983f1764..06dfc067b03 100644 --- a/src/backend/utils/misc/postgresql.conf.sample +++ b/src/backend/utils/misc/postgresql.conf.sample @@ -206,7 +206,7 @@ # - Archiving - -#archive_mode = off # allows archiving to be done +#archive_mode = off # enables archiving; off, on, or always # (change requires restart) #archive_command = '' # command to use to archive a logfile segment # placeholders: %p = path of file to archive diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h index 961e0506221..9567379f49d 100644 --- a/src/include/access/xlog.h +++ b/src/include/access/xlog.h @@ -98,7 +98,6 @@ extern int wal_keep_segments; extern int XLOGbuffers; extern int XLogArchiveTimeout; extern int wal_retrieve_retry_interval; -extern bool XLogArchiveMode; extern char *XLogArchiveCommand; extern bool EnableHotStandby; extern bool fullPageWrites; @@ -108,6 +107,15 @@ extern bool log_checkpoints; extern int CheckPointSegments; +/* Archive modes */ +typedef enum ArchiveMode +{ + ARCHIVE_MODE_OFF = 0, /* disabled */ + ARCHIVE_MODE_ON, /* enabled while server is running normally */ + ARCHIVE_MODE_ALWAYS /* enabled always (even during recovery) */ +} ArchiveMode; +extern int XLogArchiveMode; + /* WAL levels */ typedef enum WalLevel { @@ -118,7 +126,8 @@ typedef enum WalLevel } WalLevel; extern int wal_level; -#define XLogArchivingActive() (XLogArchiveMode && wal_level >= WAL_LEVEL_ARCHIVE) +#define XLogArchivingActive() \ + (XLogArchiveMode > ARCHIVE_MODE_OFF && wal_level >= WAL_LEVEL_ARCHIVE) #define XLogArchiveCommandSet() (XLogArchiveCommand[0] != '\0') /* |