diff --git a/src/backend/postmaster/syslogger.c b/src/backend/postmaster/syslogger.c index 5434826..7335659 100644 --- a/src/backend/postmaster/syslogger.c +++ b/src/backend/postmaster/syslogger.c @@ -55,6 +55,16 @@ */ #define READ_BUF_SIZE (2 * PIPE_CHUNK_SIZE) +/* + * Retries of writing LOG_METAINFO_DATAFILE are backed off on failure, but we + * don't want to backoff forever. The backoff is Fibonacci so takes 2 storage + * locations (last, the n-1 value, and next, the n value). Plus a counter for + * how many occasions for retry have been skipped. + */ +#define MAX_METAINFO_BACKOFF 250 +#define INITIAL_LAST_METAINFO_BACKOFF 0 /* fibnocci n-1 value */ +#define INITIAL_NEXT_METAINFO_BACKOFF 1 /* fibnocci n value */ +#define INITIAL_METAINFO_BACKOFF_CNTR 0 /* first retry is immediate */ /* * GUC parameters. Logging_collector cannot be changed after postmaster @@ -87,6 +97,9 @@ NON_EXEC_STATIC pg_time_t first_syslogger_file_time = 0; static char *last_file_name = NULL; static char *last_csv_file_name = NULL; static bool log_metainfo_stale = false; +static int last_metainfo_backoff = 1; /* fibnocci n-1 value */ +static int next_metainfo_backoff = 1; /* fibnocci n value */ +static int metainfo_backoff_cntr = 0; /* first retry is immediate */ /* * Buffers for saving partial messages from different backends. @@ -148,6 +161,7 @@ static void set_next_rotation_time(void); static void sigHupHandler(SIGNAL_ARGS); static void sigUsr1Handler(SIGNAL_ARGS); static void logfile_writename(void); +static void logfile_rewritename(void); /* @@ -307,7 +321,7 @@ SysLoggerMain(int argc, char *argv[]) * filename. */ if (log_metainfo_stale) - logfile_writename(); + logfile_rewritename(); /* * Process any requests or signals received recently. @@ -1487,3 +1501,40 @@ logfile_writename(void) log_metainfo_stale = false; } + +/* + * Increasingly backoff from retrying to write LOG_METAINFO_DATAFILE + * to prevent a busy system from becoming even more busy. + * The Fibonacci sequence is used because it's slope steadily increases + * without being exponential. + */ +static void +logfile_rewritename(void) +{ + if (metainfo_backoff_cntr <= 0) + { /* Done backing off, retry. */ + + logfile_writename(); + + if (log_metainfo_stale) + { + /* Retry failed. Compute next backoff interval. */ + if (next_metainfo_backoff >= MAX_METAINFO_BACKOFF) + { + metainfo_backoff_cntr = MAX_METAINFO_BACKOFF; + } else { + metainfo_backoff_cntr = next_metainfo_backoff; + next_metainfo_backoff = + last_metainfo_backoff + last_metainfo_backoff; + last_metainfo_backoff = metainfo_backoff_cntr; + } + } else { + /* Retry succeeded. Re-initialize backoff counters. */ + last_metainfo_backoff = INITIAL_LAST_METAINFO_BACKOFF; + next_metainfo_backoff = INITIAL_NEXT_METAINFO_BACKOFF; + metainfo_backoff_cntr = INITIAL_METAINFO_BACKOFF_CNTR; + } + } else { + metainfo_backoff_cntr -= 1; + } +}