*** a/doc/src/sgml/config.sgml --- b/doc/src/sgml/config.sgml *************** *** 2121,2126 **** SET ENABLE_SEQSCAN TO OFF; --- 2121,2140 ---- + + replication_timeout_server (integer) + + replication_timeout_server configuration parameter + + + + If the primary server does not receive a reply from a standby server + within replication_timeout_server seconds then the + primary will terminate the replication connection. + + + + *** a/src/backend/replication/walsender.c --- b/src/backend/replication/walsender.c *************** *** 73,78 **** bool am_walsender = false; /* Am I a walsender process ? */ --- 73,80 ---- /* User-settable parameters for walsender */ int max_wal_senders = 0; /* the maximum number of concurrent walsenders */ int WalSndDelay = 200; /* max sleep time between some actions */ + int replication_timeout_server; /* If the receiver takes too long, time + * out and die after this duration */ /* * These variables are used similarly to openLogFile/Id/Seg/Off, *************** *** 89,94 **** static uint32 sendOff = 0; --- 91,99 ---- */ static XLogRecPtr sentPtr = {0, 0}; + /* Remembers the last time the standby has notified the primary of progress */ + static TimestampTz last_reply_timestamp; + /* Flags set by signal handlers for later service in main loop */ static volatile sig_atomic_t got_SIGHUP = false; volatile sig_atomic_t walsender_shutdown_requested = false; *************** *** 250,255 **** WalSndHandshake(void) --- 255,265 ---- errmsg("invalid standby handshake message type %d", firstchar))); } } + + /* + * Initialize our timeout checking mechanism. + */ + last_reply_timestamp = GetCurrentTimestamp(); } /* *************** *** 618,632 **** WalSndLoop(void) break; if (caughtup && !got_SIGHUP && !walsender_ready_to_stop && !walsender_shutdown_requested) { ! /* ! * XXX: We don't really need the periodic wakeups anymore, ! * WaitLatchOrSocket should reliably wake up as soon as ! * something interesting happens. ! */ /* Sleep */ ! WaitLatchOrSocket(&MyWalSnd->latch, MyProcPort->sock, ! WalSndDelay * 1000L); } } else --- 628,649 ---- break; if (caughtup && !got_SIGHUP && !walsender_ready_to_stop && !walsender_shutdown_requested) { ! long timeout; ! ! if (replication_timeout_server == -1) ! timeout = -1L; ! else ! timeout = 1000000L * replication_timeout_server; /* Sleep */ ! if (WaitLatchOrSocket(&MyWalSnd->latch, MyProcPort->sock, ! timeout) == 0) ! { ! ereport(LOG, ! (errmsg("streaming replication timeout after %d s", ! replication_timeout_server))); ! break; ! } } } else *** a/src/backend/utils/misc/guc.c --- b/src/backend/utils/misc/guc.c *************** *** 1484,1489 **** static struct config_int ConfigureNamesInt[] = --- 1484,1499 ---- }, { + {"replication_timeout_server", PGC_SIGHUP, WAL_SETTINGS, + gettext_noop("Replication connection will timeout after this duration."), + NULL, + GUC_UNIT_S + }, + &replication_timeout_server, + 30, -1, INT_MAX, NULL, NULL + }, + + { {"temp_buffers", PGC_USERSET, RESOURCES_MEM, gettext_noop("Sets the maximum number of temporary buffers used by each session."), NULL, *************** *** 1828,1843 **** static struct config_int ConfigureNamesInt[] = }, { - {"wal_sender_delay", PGC_SIGHUP, WAL_REPLICATION, - gettext_noop("WAL sender sleep time between WAL replications."), - NULL, - GUC_UNIT_MS - }, - &WalSndDelay, - 200, 1, 10000, NULL, NULL - }, - - { {"commit_delay", PGC_USERSET, WAL_SETTINGS, gettext_noop("Sets the delay in microseconds between transaction commit and " "flushing WAL to disk."), --- 1838,1843 ---- *** a/src/backend/utils/misc/postgresql.conf.sample --- b/src/backend/utils/misc/postgresql.conf.sample *************** *** 203,208 **** --- 203,209 ---- # when reading streaming WAL; # -1 allows indefinite delay #wal_receiver_status_interval = 10s # replies at least this often, 0 disables + #replication_timeout_server = 120 # -1 means wait forever #------------------------------------------------------------------------------ *** a/src/include/replication/walsender.h --- b/src/include/replication/walsender.h *************** *** 68,75 **** extern volatile sig_atomic_t walsender_shutdown_requested; extern volatile sig_atomic_t walsender_ready_to_stop; /* user-settable parameters */ - extern int WalSndDelay; extern int max_wal_senders; extern int WalSenderMain(void); extern void WalSndSignals(void); --- 68,75 ---- extern volatile sig_atomic_t walsender_ready_to_stop; /* user-settable parameters */ extern int max_wal_senders; + extern int replication_timeout_server; extern int WalSenderMain(void); extern void WalSndSignals(void);