From d025e57adf6f018e615cca113294bf4c3133ebe6 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Mon, 11 Feb 2019 11:07:40 +0100 Subject: [PATCH] wal_insert_delay configuration settings --- doc/src/sgml/config.sgml | 52 +++++++++++++++++++ src/backend/access/transam/xlog.c | 19 +++++++ src/backend/utils/misc/guc.c | 32 ++++++++++++ src/backend/utils/misc/postgresql.conf.sample | 4 ++ src/include/access/xlog.h | 3 ++ 5 files changed, 110 insertions(+) diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index 7e208a4b81..a4a1525453 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -2829,6 +2829,58 @@ Settings + + wal_insert_delay_enabled (boolean) + + wal_insert_delay_enabled configuration parameter + + + + + When this setting is turned on, a session sleeps a time of after WAL data of size at least has been generated. The default + is off. + + + + The purpose of this setting is to slow down maintenance operations, in + particular to avoid that maintenance operations cause replication lag + by writing WAL too quickly. It is not sensible to enable this setting + globally. + + + + + + wal_insert_delay (integer) + + wal_insert_delay configuration parameter + + + + + Sets the length of the sleep described under . The default is 100 + milliseconds (but the overall feature is off by default). + + + + + + wal_insert_delay_size (integer) + + wal_insert_delay_size configuration parameter + + + + + Sets the size of WAL inserted to trigger the sleep described under + . The default is 1 MB + (but the overall feature is off by default). + + + diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index a9f3272849..3298e258c7 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -100,6 +100,9 @@ int wal_level = WAL_LEVEL_MINIMAL; int CommitDelay = 0; /* precommit delay in microseconds */ int CommitSiblings = 5; /* # concurrent xacts needed to sleep */ int wal_retrieve_retry_interval = 5000; +bool wal_insert_delay_enabled = false; +int wal_insert_delay; +int wal_insert_delay_size; #ifdef WAL_DEBUG bool XLOG_DEBUG = false; @@ -1220,6 +1223,22 @@ XLogInsertRecord(XLogRecData *rdata, } #endif + /* + * Delay if requested + */ + if (wal_insert_delay_enabled) + { + static int64 wal_insert_balance = 0; + + wal_insert_balance += (EndPos - StartPos); + + while (wal_insert_balance > wal_insert_delay_size) + { + pg_usleep(wal_insert_delay * 1000L); + wal_insert_balance -= wal_insert_delay_size; + } + } + /* * Update our global variables */ diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index ea5444c6f1..ef8b1fd0e2 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -1176,6 +1176,16 @@ static struct config_bool ConfigureNamesBool[] = NULL, NULL, NULL }, + { + {"wal_insert_delay_enabled", PGC_USERSET, WAL_SETTINGS, + gettext_noop("Sleeps after inserting a certain amount of WAL."), + NULL + }, + &wal_insert_delay_enabled, + false, + NULL, NULL, NULL + }, + { {"log_checkpoints", PGC_SIGHUP, LOGGING_WHAT, gettext_noop("Logs each checkpoint."), @@ -2079,6 +2089,28 @@ static struct config_int ConfigureNamesInt[] = NULL, NULL, NULL }, + { + {"wal_insert_delay", PGC_USERSET, WAL_SETTINGS, + gettext_noop("Sets the sleep time after inserting a certain amount of WAL."), + NULL, + GUC_UNIT_MS + }, + &wal_insert_delay, + 100, 0, INT_MAX, + NULL, NULL, NULL + }, + + { + {"wal_insert_delay_size", PGC_USERSET, WAL_SETTINGS, + gettext_noop("Sets the amount of WAL after which to sleep."), + NULL, + GUC_UNIT_BYTE + }, + &wal_insert_delay_size, + 1024 * 1024, 0, INT_MAX, + NULL, NULL, NULL + }, + { {"max_connections", PGC_POSTMASTER, CONN_AUTH_SETTINGS, gettext_noop("Sets the maximum number of concurrent connections."), diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample index ad6c436f93..62d75da3c7 100644 --- a/src/backend/utils/misc/postgresql.conf.sample +++ b/src/backend/utils/misc/postgresql.conf.sample @@ -214,6 +214,10 @@ #commit_delay = 0 # range 0-100000, in microseconds #commit_siblings = 5 # range 1-1000 +#wal_insert_delay_enabled = off +#wal_insert_delay = 100ms +#wal_insert_delay_size = 1MB + # - Checkpoints - #checkpoint_timeout = 5min # range 30s-1d diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h index f90a6a9139..c66a77b18e 100644 --- a/src/include/access/xlog.h +++ b/src/include/access/xlog.h @@ -127,6 +127,9 @@ extern int recoveryTargetAction; extern int recovery_min_apply_delay; extern char *PrimaryConnInfo; extern char *PrimarySlotName; +extern bool wal_insert_delay_enabled; +extern int wal_insert_delay; +extern int wal_insert_delay_size; /* indirectly set via GUC system */ extern TransactionId recoveryTargetXid; -- 2.20.1