mirror of
https://github.com/postgres/postgres.git
synced 2025-07-28 23:42:10 +03:00
Report progress of startup operations that take a long time.
Users sometimes get concerned whe they start the server and it emits a few messages and then doesn't emit any more messages for a long time. Generally, what's happening is either that the system is taking a long time to apply WAL, or it's taking a long time to reset unlogged relations, or it's taking a long time to fsync the data directory, but it's not easy to tell which is the case. To fix that, add a new 'log_startup_progress_interval' setting, by default 10s. When an operation that is known to be potentially long-running takes more than this amount of time, we'll log a status update each time this interval elapses. To avoid undesirable log chatter, don't log anything about WAL replay when in standby mode. Nitin Jadhav and Robert Haas, reviewed by Amul Sul, Bharath Rupireddy, Justin Pryzby, Michael Paquier, and Álvaro Herrera. Discussion: https://postgr.es/m/CA+TgmoaHQrgDFOBwgY16XCoMtXxsrVGFB2jNCvb7-ubuEe1MGg@mail.gmail.com Discussion: https://postgr.es/m/CAMm1aWaHF7VE69572_OLQ+MgpT5RUiUDgF1x5RrtkJBLdpRj3Q@mail.gmail.com
This commit is contained in:
@ -59,6 +59,22 @@ static volatile sig_atomic_t promote_signaled = false;
|
||||
*/
|
||||
static volatile sig_atomic_t in_restore_command = false;
|
||||
|
||||
/*
|
||||
* Time at which the most recent startup operation started.
|
||||
*/
|
||||
static TimestampTz startup_progress_phase_start_time;
|
||||
|
||||
/*
|
||||
* Indicates whether the startup progress interval mentioned by the user is
|
||||
* elapsed or not. TRUE if timeout occurred, FALSE otherwise.
|
||||
*/
|
||||
static volatile sig_atomic_t startup_progress_timer_expired = false;
|
||||
|
||||
/*
|
||||
* Time between progress updates for long-running startup operations.
|
||||
*/
|
||||
int log_startup_progress_interval = 10000; /* 10 sec */
|
||||
|
||||
/* Signal handlers */
|
||||
static void StartupProcTriggerHandler(SIGNAL_ARGS);
|
||||
static void StartupProcSigHupHandler(SIGNAL_ARGS);
|
||||
@ -282,3 +298,58 @@ ResetPromoteSignaled(void)
|
||||
{
|
||||
promote_signaled = false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set a flag indicating that it's time to log a progress report.
|
||||
*/
|
||||
void
|
||||
startup_progress_timeout_handler(void)
|
||||
{
|
||||
startup_progress_timer_expired = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the start timestamp of the current operation and enable the timeout.
|
||||
*/
|
||||
void
|
||||
begin_startup_progress_phase(void)
|
||||
{
|
||||
TimestampTz fin_time;
|
||||
|
||||
/* Feature is disabled. */
|
||||
if (log_startup_progress_interval == 0)
|
||||
return;
|
||||
|
||||
startup_progress_phase_start_time = GetCurrentTimestamp();
|
||||
fin_time = TimestampTzPlusMilliseconds(startup_progress_phase_start_time,
|
||||
log_startup_progress_interval);
|
||||
enable_timeout_every(STARTUP_PROGRESS_TIMEOUT, fin_time,
|
||||
log_startup_progress_interval);
|
||||
}
|
||||
|
||||
/*
|
||||
* Report whether startup progress timeout has occurred. Reset the timer flag
|
||||
* if it did, set the elapsed time to the out parameters and return true,
|
||||
* otherwise return false.
|
||||
*/
|
||||
bool
|
||||
has_startup_progress_timeout_expired(long *secs, int *usecs)
|
||||
{
|
||||
long seconds;
|
||||
int useconds;
|
||||
TimestampTz now;
|
||||
|
||||
/* No timeout has occurred. */
|
||||
if (!startup_progress_timer_expired)
|
||||
return false;
|
||||
|
||||
/* Calculate the elapsed time. */
|
||||
now = GetCurrentTimestamp();
|
||||
TimestampDifference(startup_progress_phase_start_time, now, &seconds, &useconds);
|
||||
|
||||
*secs = seconds;
|
||||
*usecs = useconds;
|
||||
startup_progress_timer_expired = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
Reference in New Issue
Block a user