PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
checkpointer.c File Reference
#include "postgres.h"
#include <signal.h>
#include <sys/time.h>
#include <unistd.h>
#include "access/xlog.h"
#include "access/xlog_internal.h"
#include "libpq/pqsignal.h"
#include "miscadmin.h"
#include "pgstat.h"
#include "postmaster/bgwriter.h"
#include "replication/syncrep.h"
#include "storage/bufmgr.h"
#include "storage/condition_variable.h"
#include "storage/fd.h"
#include "storage/ipc.h"
#include "storage/lwlock.h"
#include "storage/proc.h"
#include "storage/shmem.h"
#include "storage/smgr.h"
#include "storage/spin.h"
#include "utils/guc.h"
#include "utils/memutils.h"
#include "utils/resowner.h"
Include dependency graph for checkpointer.c:

Go to the source code of this file.

Data Structures

struct  CheckpointerRequest
 
struct  CheckpointerShmemStruct
 

Macros

#define WRITES_PER_ABSORB   1000
 

Functions

static void CheckArchiveTimeout (void)
 
static bool IsCheckpointOnSchedule (double progress)
 
static bool ImmediateCheckpointRequested (void)
 
static bool CompactCheckpointerRequestQueue (void)
 
static void UpdateSharedMemoryConfig (void)
 
static void chkpt_quickdie (SIGNAL_ARGS)
 
static void ChkptSigHupHandler (SIGNAL_ARGS)
 
static void ReqCheckpointHandler (SIGNAL_ARGS)
 
static void chkpt_sigusr1_handler (SIGNAL_ARGS)
 
static void ReqShutdownHandler (SIGNAL_ARGS)
 
void CheckpointerMain (void)
 
void CheckpointWriteDelay (int flags, double progress)
 
Size CheckpointerShmemSize (void)
 
void CheckpointerShmemInit (void)
 
void RequestCheckpoint (int flags)
 
bool ForwardFsyncRequest (RelFileNode rnode, ForkNumber forknum, BlockNumber segno)
 
void AbsorbFsyncRequests (void)
 
bool FirstCallSinceLastCheckpoint (void)
 

Variables

static CheckpointerShmemStructCheckpointerShmem
 
int CheckPointTimeout = 300
 
int CheckPointWarning = 30
 
double CheckPointCompletionTarget = 0.5
 
static volatile sig_atomic_t got_SIGHUP = false
 
static volatile sig_atomic_t checkpoint_requested = false
 
static volatile sig_atomic_t shutdown_requested = false
 
static bool ckpt_active = false
 
static pg_time_t ckpt_start_time
 
static XLogRecPtr ckpt_start_recptr
 
static double ckpt_cached_elapsed
 
static pg_time_t last_checkpoint_time
 
static pg_time_t last_xlog_switch_time
 

Macro Definition Documentation

#define WRITES_PER_ABSORB   1000

Definition at line 140 of file checkpointer.c.

Referenced by CheckpointWriteDelay().

Function Documentation

void AbsorbFsyncRequests ( void  )

Definition at line 1302 of file checkpointer.c.

References AmCheckpointerProcess, BgWriterStats, END_CRIT_SECTION, CheckpointerRequest::forknum, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), PgStat_MsgBgWriter::m_buf_fsync_backend, PgStat_MsgBgWriter::m_buf_written_backend, NULL, CheckpointerShmemStruct::num_backend_fsync, CheckpointerShmemStruct::num_backend_writes, CheckpointerShmemStruct::num_requests, palloc(), pfree(), RememberFsyncRequest(), CheckpointerShmemStruct::requests, CheckpointerRequest::rnode, CheckpointerRequest::segno, and START_CRIT_SECTION.

Referenced by CheckpointerMain(), CheckpointWriteDelay(), mdpostckpt(), and mdsync().

1303 {
1304  CheckpointerRequest *requests = NULL;
1305  CheckpointerRequest *request;
1306  int n;
1307 
1308  if (!AmCheckpointerProcess())
1309  return;
1310 
1311  LWLockAcquire(CheckpointerCommLock, LW_EXCLUSIVE);
1312 
1313  /* Transfer stats counts into pending pgstats message */
1316 
1319 
1320  /*
1321  * We try to avoid holding the lock for a long time by copying the request
1322  * array, and processing the requests after releasing the lock.
1323  *
1324  * Once we have cleared the requests from shared memory, we have to PANIC
1325  * if we then fail to absorb them (eg, because our hashtable runs out of
1326  * memory). This is because the system cannot run safely if we are unable
1327  * to fsync what we have been told to fsync. Fortunately, the hashtable
1328  * is so small that the problem is quite unlikely to arise in practice.
1329  */
1331  if (n > 0)
1332  {
1333  requests = (CheckpointerRequest *) palloc(n * sizeof(CheckpointerRequest));
1334  memcpy(requests, CheckpointerShmem->requests, n * sizeof(CheckpointerRequest));
1335  }
1336 
1338 
1340 
1341  LWLockRelease(CheckpointerCommLock);
1342 
1343  for (request = requests; n > 0; request++, n--)
1344  RememberFsyncRequest(request->rnode, request->forknum, request->segno);
1345 
1346  END_CRIT_SECTION();
1347 
1348  if (requests)
1349  pfree(requests);
1350 }
void RememberFsyncRequest(RelFileNode rnode, ForkNumber forknum, BlockNumber segno)
Definition: md.c:1514
PgStat_Counter m_buf_fsync_backend
Definition: pgstat.h:419
#define END_CRIT_SECTION()
Definition: miscadmin.h:133
PgStat_MsgBgWriter BgWriterStats
Definition: pgstat.c:143
CheckpointerRequest requests[FLEXIBLE_ARRAY_MEMBER]
Definition: checkpointer.c:134
#define START_CRIT_SECTION()
Definition: miscadmin.h:131
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1715
void pfree(void *pointer)
Definition: mcxt.c:950
#define AmCheckpointerProcess()
Definition: miscadmin.h:408
static CheckpointerShmemStruct * CheckpointerShmem
Definition: checkpointer.c:137
#define NULL
Definition: c.h:229
PgStat_Counter m_buf_written_backend
Definition: pgstat.h:418
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1111
void * palloc(Size size)
Definition: mcxt.c:849
static void CheckArchiveTimeout ( void  )
static

Definition at line 585 of file checkpointer.c.

References DEBUG1, elog, GetLastImportantRecPtr(), GetLastSegSwitchData(), last_xlog_switch_time, Max, now(), NULL, RecoveryInProgress(), RequestXLogSwitch(), XLogArchiveTimeout, and XLogSegSize.

Referenced by CheckpointerMain(), and CheckpointWriteDelay().

586 {
587  pg_time_t now;
588  pg_time_t last_time;
589  XLogRecPtr last_switch_lsn;
590 
592  return;
593 
594  now = (pg_time_t) time(NULL);
595 
596  /* First we do a quick check using possibly-stale local state. */
597  if ((int) (now - last_xlog_switch_time) < XLogArchiveTimeout)
598  return;
599 
600  /*
601  * Update local state ... note that last_xlog_switch_time is the last time
602  * a switch was performed *or requested*.
603  */
604  last_time = GetLastSegSwitchData(&last_switch_lsn);
605 
607 
608  /* Now we can do the real checks */
609  if ((int) (now - last_xlog_switch_time) >= XLogArchiveTimeout)
610  {
611  /*
612  * Switch segment only when "important" WAL has been logged since the
613  * last segment switch (last_switch_lsn points to end of segment
614  * switch occurred in).
615  */
616  if (GetLastImportantRecPtr() > last_switch_lsn)
617  {
618  XLogRecPtr switchpoint;
619 
620  /* mark switch as unimportant, avoids triggering checkpoints */
621  switchpoint = RequestXLogSwitch(true);
622 
623  /*
624  * If the returned pointer points exactly to a segment boundary,
625  * assume nothing happened.
626  */
627  if ((switchpoint % XLogSegSize) != 0)
628  elog(DEBUG1, "write-ahead log switch forced (archive_timeout=%d)",
630  }
631 
632  /*
633  * Update state in any case, so we don't retry constantly when the
634  * system is idle.
635  */
637  }
638 }
XLogRecPtr GetLastImportantRecPtr(void)
Definition: xlog.c:8245
#define XLogSegSize
Definition: xlog_internal.h:92
XLogRecPtr RequestXLogSwitch(bool mark_unimportant)
Definition: xlog.c:9411
#define DEBUG1
Definition: elog.h:25
int64 pg_time_t
Definition: pgtime.h:23
pg_time_t GetLastSegSwitchData(XLogRecPtr *lastSwitchLSN)
Definition: xlog.c:8274
int XLogArchiveTimeout
Definition: xlog.c:93
bool RecoveryInProgress(void)
Definition: xlog.c:7878
static pg_time_t last_xlog_switch_time
Definition: checkpointer.c:167
#define Max(x, y)
Definition: c.h:801
#define NULL
Definition: c.h:229
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define elog
Definition: elog.h:219
Datum now(PG_FUNCTION_ARGS)
Definition: timestamp.c:1534
void CheckpointerMain ( void  )

Definition at line 193 of file checkpointer.c.

References AbortBufferIO(), AbsorbFsyncRequests(), ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate(), AtEOXact_Buffers(), AtEOXact_Files(), AtEOXact_HashTables(), AtEOXact_SMgr(), BgWriterStats, BlockSig, CheckArchiveTimeout(), CHECKPOINT_CAUSE_TIME, CHECKPOINT_CAUSE_XLOG, CHECKPOINT_END_OF_RECOVERY, checkpoint_requested, CheckpointerShmemStruct::checkpointer_pid, PROC_HDR::checkpointerLatch, CheckPointTimeout, CheckPointWarning, chkpt_quickdie(), chkpt_sigusr1_handler(), ChkptSigHupHandler(), ckpt_active, ckpt_cached_elapsed, CheckpointerShmemStruct::ckpt_done, CheckpointerShmemStruct::ckpt_failed, CheckpointerShmemStruct::ckpt_flags, CheckpointerShmemStruct::ckpt_lck, ckpt_start_recptr, ckpt_start_time, CheckpointerShmemStruct::ckpt_started, ConditionVariableCancelSleep(), CreateCheckPoint(), CreateRestartPoint(), CurrentResourceOwner, EmitErrorReport(), ereport, errhint(), errmsg_plural(), error_context_stack, ExitOnAnyError, FlushErrorState(), GetInsertRecPtr(), GetXLogReplayRecPtr(), got_SIGHUP, HOLD_INTERRUPTS, last_checkpoint_time, last_xlog_switch_time, LOG, LWLockReleaseAll(), PgStat_MsgBgWriter::m_requested_checkpoints, PgStat_MsgBgWriter::m_timed_checkpoints, MemoryContextResetAndDeleteChildren, MemoryContextSwitchTo(), Min, MyLatch, MyProc, MyProcPid, now(), NULL, PG_exception_stack, PG_SETMASK, pg_usleep(), PGC_SIGHUP, pgstat_report_wait_end(), pgstat_send_bgwriter(), pqsignal(), proc_exit(), ProcessConfigFile(), ProcGlobal, PGPROC::procLatch, RecoveryInProgress(), ReqCheckpointHandler(), ReqShutdownHandler(), ResetLatch(), RESOURCE_RELEASE_BEFORE_LOCKS, ResourceOwnerCreate(), ResourceOwnerRelease(), RESUME_INTERRUPTS, shutdown_requested, ShutdownXLOG(), SIG_DFL, SIG_IGN, SIGALRM, SIGCHLD, SIGCONT, SIGHUP, SIGPIPE, SIGQUIT, SIGTTIN, SIGTTOU, SIGUSR1, SIGUSR2, SIGWINCH, smgrcloseall(), SpinLockAcquire, SpinLockRelease, TopMemoryContext, UnBlockSig, UnlockBuffers(), UpdateSharedMemoryConfig(), WAIT_EVENT_CHECKPOINTER_MAIN, WaitLatch(), WL_LATCH_SET, WL_POSTMASTER_DEATH, WL_TIMEOUT, and XLogArchiveTimeout.

Referenced by AuxiliaryProcessMain().

194 {
195  sigjmp_buf local_sigjmp_buf;
196  MemoryContext checkpointer_context;
197 
199 
200  /*
201  * Properly accept or ignore signals the postmaster might send us
202  *
203  * Note: we deliberately ignore SIGTERM, because during a standard Unix
204  * system shutdown cycle, init will SIGTERM all processes at once. We
205  * want to wait for the backends to exit, whereupon the postmaster will
206  * tell us it's okay to shut down (via SIGUSR2).
207  */
208  pqsignal(SIGHUP, ChkptSigHupHandler); /* set flag to read config file */
209  pqsignal(SIGINT, ReqCheckpointHandler); /* request checkpoint */
210  pqsignal(SIGTERM, SIG_IGN); /* ignore SIGTERM */
211  pqsignal(SIGQUIT, chkpt_quickdie); /* hard crash time */
215  pqsignal(SIGUSR2, ReqShutdownHandler); /* request shutdown */
216 
217  /*
218  * Reset some signals that are accepted by postmaster but not here
219  */
225 
226  /* We allow SIGQUIT (quickdie) at all times */
227  sigdelset(&BlockSig, SIGQUIT);
228 
229  /*
230  * Initialize so that first time-driven event happens at the correct time.
231  */
233 
234  /*
235  * Create a resource owner to keep track of our resources (currently only
236  * buffer pins).
237  */
238  CurrentResourceOwner = ResourceOwnerCreate(NULL, "Checkpointer");
239 
240  /*
241  * Create a memory context that we will do all our work in. We do this so
242  * that we can reset the context during error recovery and thereby avoid
243  * possible memory leaks. Formerly this code just ran in
244  * TopMemoryContext, but resetting that would be a really bad idea.
245  */
246  checkpointer_context = AllocSetContextCreate(TopMemoryContext,
247  "Checkpointer",
249  MemoryContextSwitchTo(checkpointer_context);
250 
251  /*
252  * If an exception is encountered, processing resumes here.
253  *
254  * See notes in postgres.c about the design of this coding.
255  */
256  if (sigsetjmp(local_sigjmp_buf, 1) != 0)
257  {
258  /* Since not using PG_TRY, must reset error stack by hand */
260 
261  /* Prevent interrupts while cleaning up */
262  HOLD_INTERRUPTS();
263 
264  /* Report the error to the server log */
265  EmitErrorReport();
266 
267  /*
268  * These operations are really just a minimal subset of
269  * AbortTransaction(). We don't have very many resources to worry
270  * about in checkpointer, but we do have LWLocks, buffers, and temp
271  * files.
272  */
276  AbortBufferIO();
277  UnlockBuffers();
278  /* buffer pins are released here: */
281  false, true);
282  /* we needn't bother with the other ResourceOwnerRelease phases */
283  AtEOXact_Buffers(false);
284  AtEOXact_SMgr();
285  AtEOXact_Files();
286  AtEOXact_HashTables(false);
287 
288  /* Warn any waiting backends that the checkpoint failed. */
289  if (ckpt_active)
290  {
295 
296  ckpt_active = false;
297  }
298 
299  /*
300  * Now return to normal top-level context and clear ErrorContext for
301  * next time.
302  */
303  MemoryContextSwitchTo(checkpointer_context);
304  FlushErrorState();
305 
306  /* Flush any leaked data in the top-level context */
307  MemoryContextResetAndDeleteChildren(checkpointer_context);
308 
309  /* Now we can allow interrupts again */
311 
312  /*
313  * Sleep at least 1 second after any error. A write error is likely
314  * to be repeated, and we don't want to be filling the error logs as
315  * fast as we can.
316  */
317  pg_usleep(1000000L);
318 
319  /*
320  * Close all open files after any error. This is helpful on Windows,
321  * where holding deleted files open causes various strange errors.
322  * It's not clear we need it elsewhere, but shouldn't hurt.
323  */
324  smgrcloseall();
325  }
326 
327  /* We can now handle ereport(ERROR) */
328  PG_exception_stack = &local_sigjmp_buf;
329 
330  /*
331  * Unblock signals (they were blocked when the postmaster forked us)
332  */
334 
335  /*
336  * Ensure all shared memory values are set correctly for the config. Doing
337  * this here ensures no race conditions from other concurrent updaters.
338  */
340 
341  /*
342  * Advertise our latch that backends can use to wake us up while we're
343  * sleeping.
344  */
346 
347  /*
348  * Loop forever
349  */
350  for (;;)
351  {
352  bool do_checkpoint = false;
353  int flags = 0;
354  pg_time_t now;
355  int elapsed_secs;
356  int cur_timeout;
357  int rc;
358 
359  /* Clear any already-pending wakeups */
361 
362  /*
363  * Process any requests or signals received recently.
364  */
366 
367  if (got_SIGHUP)
368  {
369  got_SIGHUP = false;
371 
372  /*
373  * Checkpointer is the last process to shut down, so we ask it to
374  * hold the keys for a range of other tasks required most of which
375  * have nothing to do with checkpointing at all.
376  *
377  * For various reasons, some config values can change dynamically
378  * so the primary copy of them is held in shared memory to make
379  * sure all backends see the same value. We make Checkpointer
380  * responsible for updating the shared memory copy if the
381  * parameter setting changes because of SIGHUP.
382  */
384  }
386  {
387  checkpoint_requested = false;
388  do_checkpoint = true;
390  }
391  if (shutdown_requested)
392  {
393  /*
394  * From here on, elog(ERROR) should end with exit(1), not send
395  * control back to the sigsetjmp block above
396  */
397  ExitOnAnyError = true;
398  /* Close down the database */
399  ShutdownXLOG(0, 0);
400  /* Normal exit from the checkpointer is here */
401  proc_exit(0); /* done */
402  }
403 
404  /*
405  * Force a checkpoint if too much time has elapsed since the last one.
406  * Note that we count a timed checkpoint in stats only when this
407  * occurs without an external request, but we set the CAUSE_TIME flag
408  * bit even if there is also an external request.
409  */
410  now = (pg_time_t) time(NULL);
411  elapsed_secs = now - last_checkpoint_time;
412  if (elapsed_secs >= CheckPointTimeout)
413  {
414  if (!do_checkpoint)
416  do_checkpoint = true;
417  flags |= CHECKPOINT_CAUSE_TIME;
418  }
419 
420  /*
421  * Do a checkpoint if requested.
422  */
423  if (do_checkpoint)
424  {
425  bool ckpt_performed = false;
426  bool do_restartpoint;
427 
428  /*
429  * Check if we should perform a checkpoint or a restartpoint. As a
430  * side-effect, RecoveryInProgress() initializes TimeLineID if
431  * it's not set yet.
432  */
433  do_restartpoint = RecoveryInProgress();
434 
435  /*
436  * Atomically fetch the request flags to figure out what kind of a
437  * checkpoint we should perform, and increase the started-counter
438  * to acknowledge that we've started a new checkpoint.
439  */
441  flags |= CheckpointerShmem->ckpt_flags;
445 
446  /*
447  * The end-of-recovery checkpoint is a real checkpoint that's
448  * performed while we're still in recovery.
449  */
450  if (flags & CHECKPOINT_END_OF_RECOVERY)
451  do_restartpoint = false;
452 
453  /*
454  * We will warn if (a) too soon since last checkpoint (whatever
455  * caused it) and (b) somebody set the CHECKPOINT_CAUSE_XLOG flag
456  * since the last checkpoint start. Note in particular that this
457  * implementation will not generate warnings caused by
458  * CheckPointTimeout < CheckPointWarning.
459  */
460  if (!do_restartpoint &&
461  (flags & CHECKPOINT_CAUSE_XLOG) &&
462  elapsed_secs < CheckPointWarning)
463  ereport(LOG,
464  (errmsg_plural("checkpoints are occurring too frequently (%d second apart)",
465  "checkpoints are occurring too frequently (%d seconds apart)",
466  elapsed_secs,
467  elapsed_secs),
468  errhint("Consider increasing the configuration parameter \"max_wal_size\".")));
469 
470  /*
471  * Initialize checkpointer-private variables used during
472  * checkpoint.
473  */
474  ckpt_active = true;
475  if (do_restartpoint)
477  else
481 
482  /*
483  * Do the checkpoint.
484  */
485  if (!do_restartpoint)
486  {
487  CreateCheckPoint(flags);
488  ckpt_performed = true;
489  }
490  else
491  ckpt_performed = CreateRestartPoint(flags);
492 
493  /*
494  * After any checkpoint, close all smgr files. This is so we
495  * won't hang onto smgr references to deleted files indefinitely.
496  */
497  smgrcloseall();
498 
499  /*
500  * Indicate checkpoint completion to any waiting backends.
501  */
505 
506  if (ckpt_performed)
507  {
508  /*
509  * Note we record the checkpoint start time not end time as
510  * last_checkpoint_time. This is so that time-driven
511  * checkpoints happen at a predictable spacing.
512  */
513  last_checkpoint_time = now;
514  }
515  else
516  {
517  /*
518  * We were not able to perform the restartpoint (checkpoints
519  * throw an ERROR in case of error). Most likely because we
520  * have not received any new checkpoint WAL records since the
521  * last restartpoint. Try again in 15 s.
522  */
523  last_checkpoint_time = now - CheckPointTimeout + 15;
524  }
525 
526  ckpt_active = false;
527  }
528 
529  /* Check for archive_timeout and switch xlog files if necessary. */
531 
532  /*
533  * Send off activity statistics to the stats collector. (The reason
534  * why we re-use bgwriter-related code for this is that the bgwriter
535  * and checkpointer used to be just one process. It's probably not
536  * worth the trouble to split the stats support into two independent
537  * stats message types.)
538  */
540 
541  /*
542  * Sleep until we are signaled or it's time for another checkpoint or
543  * xlog file switch.
544  */
545  now = (pg_time_t) time(NULL);
546  elapsed_secs = now - last_checkpoint_time;
547  if (elapsed_secs >= CheckPointTimeout)
548  continue; /* no sleep for us ... */
549  cur_timeout = CheckPointTimeout - elapsed_secs;
551  {
552  elapsed_secs = now - last_xlog_switch_time;
553  if (elapsed_secs >= XLogArchiveTimeout)
554  continue; /* no sleep for us ... */
555  cur_timeout = Min(cur_timeout, XLogArchiveTimeout - elapsed_secs);
556  }
557 
558  rc = WaitLatch(MyLatch,
560  cur_timeout * 1000L /* convert to ms */ ,
562 
563  /*
564  * Emergency bailout if postmaster has died. This is to avoid the
565  * necessity for manual cleanup of all postmaster children.
566  */
567  if (rc & WL_POSTMASTER_DEATH)
568  exit(1);
569  }
570 }
#define SIGUSR1
Definition: win32.h:202
XLogRecPtr GetInsertRecPtr(void)
Definition: xlog.c:8211
int MyProcPid
Definition: globals.c:39
int errhint(const char *fmt,...)
Definition: elog.c:987
#define SIGCONT
Definition: win32.h:197
int64 pg_time_t
Definition: pgtime.h:23
#define WL_TIMEOUT
Definition: latch.h:127
void ProcessConfigFile(GucContext context)
static void ReqCheckpointHandler(SIGNAL_ARGS)
Definition: checkpointer.c:862
int XLogArchiveTimeout
Definition: xlog.c:93
int errmsg_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...)
Definition: elog.c:850
void CreateCheckPoint(int flags)
Definition: xlog.c:8533
PGPROC * MyProc
Definition: proc.c:67
PgStat_Counter m_timed_checkpoints
Definition: pgstat.h:413
#define SIGWINCH
Definition: win32.h:201
void AtEOXact_Buffers(bool isCommit)
Definition: bufmgr.c:2415
ResourceOwner CurrentResourceOwner
Definition: resowner.c:138
#define Min(x, y)
Definition: c.h:807
bool CreateRestartPoint(int flags)
Definition: xlog.c:9080
#define SIGTTIN
Definition: win32.h:199
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
PgStat_MsgBgWriter BgWriterStats
Definition: pgstat.c:143
int CheckPointWarning
Definition: checkpointer.c:146
void proc_exit(int code)
Definition: ipc.c:99
PROC_HDR * ProcGlobal
Definition: proc.c:80
void ResetLatch(volatile Latch *latch)
Definition: latch.c:497
#define LOG
Definition: elog.h:26
bool RecoveryInProgress(void)
Definition: xlog.c:7878
#define SIGQUIT
Definition: win32.h:189
void FlushErrorState(void)
Definition: elog.c:1587
#define PG_SETMASK(mask)
Definition: pqsignal.h:19
Latch procLatch
Definition: proc.h:103
void smgrcloseall(void)
Definition: smgr.c:326
#define RESUME_INTERRUPTS()
Definition: miscadmin.h:117
ErrorContextCallback * error_context_stack
Definition: elog.c:88
#define CHECKPOINT_CAUSE_XLOG
Definition: xlog.h:185
PgStat_Counter m_requested_checkpoints
Definition: pgstat.h:414
#define SpinLockAcquire(lock)
Definition: spin.h:62
void pg_usleep(long microsec)
Definition: signal.c:53
void AtEOXact_SMgr(void)
Definition: smgr.c:798
int WaitLatch(volatile Latch *latch, int wakeEvents, long timeout, uint32 wait_event_info)
Definition: latch.c:336
#define SIG_IGN
Definition: win32.h:185
void ConditionVariableCancelSleep(void)
void AtEOXact_Files(void)
Definition: fd.c:2617
XLogRecPtr GetXLogReplayRecPtr(TimeLineID *replayTLI)
Definition: xlog.c:11098
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:165
static void ChkptSigHupHandler(SIGNAL_ARGS)
Definition: checkpointer.c:850
int CheckPointTimeout
Definition: checkpointer.c:145
#define CHECKPOINT_END_OF_RECOVERY
Definition: xlog.h:176
sigset_t UnBlockSig
Definition: pqsignal.c:22
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1235
#define ereport(elevel, rest)
Definition: elog.h:122
MemoryContext TopMemoryContext
Definition: mcxt.c:43
Definition: guc.h:72
static CheckpointerShmemStruct * CheckpointerShmem
Definition: checkpointer.c:137
void ShutdownXLOG(int code, Datum arg)
Definition: xlog.c:8326
void UnlockBuffers(void)
Definition: bufmgr.c:3518
#define MemoryContextResetAndDeleteChildren(ctx)
Definition: memutils.h:67
#define SpinLockRelease(lock)
Definition: spin.h:64
bool ExitOnAnyError
Definition: globals.c:105
static void UpdateSharedMemoryConfig(void)
sigset_t BlockSig
Definition: pqsignal.c:22
#define WL_POSTMASTER_DEATH
Definition: latch.h:128
MemoryContext AllocSetContextCreate(MemoryContext parent, const char *name, Size minContextSize, Size initBlockSize, Size maxBlockSize)
Definition: aset.c:322
static void chkpt_quickdie(SIGNAL_ARGS)
Definition: checkpointer.c:823
void EmitErrorReport(void)
Definition: elog.c:1446
static pg_time_t last_xlog_switch_time
Definition: checkpointer.c:167
void pgstat_send_bgwriter(void)
Definition: pgstat.c:4151
#define SIGPIPE
Definition: win32.h:193
#define SIGHUP
Definition: win32.h:188
#define SIG_DFL
Definition: win32.h:183
static bool ckpt_active
Definition: checkpointer.c:159
static pg_time_t ckpt_start_time
Definition: checkpointer.c:162
static volatile sig_atomic_t got_SIGHUP
Definition: checkpointer.c:152
pqsigfunc pqsignal(int signum, pqsigfunc handler)
Definition: signal.c:168
static XLogRecPtr ckpt_start_recptr
Definition: checkpointer.c:163
Latch * checkpointerLatch
Definition: proc.h:248
#define NULL
Definition: c.h:229
void ResourceOwnerRelease(ResourceOwner owner, ResourceReleasePhase phase, bool isCommit, bool isTopLevel)
Definition: resowner.c:471
static void ReqShutdownHandler(SIGNAL_ARGS)
Definition: checkpointer.c:885
void AbortBufferIO(void)
Definition: bufmgr.c:3974
sigjmp_buf * PG_exception_stack
Definition: elog.c:90
static volatile sig_atomic_t checkpoint_requested
Definition: checkpointer.c:153
#define SIGTTOU
Definition: win32.h:200
static double ckpt_cached_elapsed
Definition: checkpointer.c:164
static void CheckArchiveTimeout(void)
Definition: checkpointer.c:585
#define HOLD_INTERRUPTS()
Definition: miscadmin.h:115
#define CHECKPOINT_CAUSE_TIME
Definition: xlog.h:186
struct Latch * MyLatch
Definition: globals.c:52
void LWLockReleaseAll(void)
Definition: lwlock.c:1814
void AbsorbFsyncRequests(void)
void AtEOXact_HashTables(bool isCommit)
Definition: dynahash.c:1830
#define SIGCHLD
Definition: win32.h:198
static void chkpt_sigusr1_handler(SIGNAL_ARGS)
Definition: checkpointer.c:874
static pg_time_t last_checkpoint_time
Definition: checkpointer.c:166
#define WL_LATCH_SET
Definition: latch.h:124
#define SIGALRM
Definition: win32.h:194
Datum now(PG_FUNCTION_ARGS)
Definition: timestamp.c:1534
#define SIGUSR2
Definition: win32.h:203
static volatile sig_atomic_t shutdown_requested
Definition: checkpointer.c:154
ResourceOwner ResourceOwnerCreate(ResourceOwner parent, const char *name)
Definition: resowner.c:416
void CheckpointerShmemInit ( void  )

Definition at line 925 of file checkpointer.c.

References CheckpointerShmemSize(), CheckpointerShmemStruct::ckpt_lck, CheckpointerShmemStruct::max_requests, MemSet, NBuffers, ShmemInitStruct(), and SpinLockInit.

Referenced by CreateSharedMemoryAndSemaphores().

926 {
927  Size size = CheckpointerShmemSize();
928  bool found;
929 
931  ShmemInitStruct("Checkpointer Data",
932  size,
933  &found);
934 
935  if (!found)
936  {
937  /*
938  * First time through, so initialize. Note that we zero the whole
939  * requests array; this is so that CompactCheckpointerRequestQueue can
940  * assume that any pad bytes in the request structs are zeroes.
941  */
942  MemSet(CheckpointerShmem, 0, size);
945  }
946 }
#define SpinLockInit(lock)
Definition: spin.h:60
#define MemSet(start, val, len)
Definition: c.h:858
void * ShmemInitStruct(const char *name, Size size, bool *foundPtr)
Definition: shmem.c:372
static CheckpointerShmemStruct * CheckpointerShmem
Definition: checkpointer.c:137
Size CheckpointerShmemSize(void)
Definition: checkpointer.c:906
size_t Size
Definition: c.h:356
int NBuffers
Definition: globals.c:123
Size CheckpointerShmemSize ( void  )

Definition at line 906 of file checkpointer.c.

References add_size(), mul_size(), NBuffers, and offsetof.

Referenced by CheckpointerShmemInit(), and CreateSharedMemoryAndSemaphores().

907 {
908  Size size;
909 
910  /*
911  * Currently, the size of the requests[] array is arbitrarily set equal to
912  * NBuffers. This may prove too large or small ...
913  */
914  size = offsetof(CheckpointerShmemStruct, requests);
915  size = add_size(size, mul_size(NBuffers, sizeof(CheckpointerRequest)));
916 
917  return size;
918 }
Size mul_size(Size s1, Size s2)
Definition: shmem.c:492
Size add_size(Size s1, Size s2)
Definition: shmem.c:475
size_t Size
Definition: c.h:356
int NBuffers
Definition: globals.c:123
#define offsetof(type, field)
Definition: c.h:555
void CheckpointWriteDelay ( int  flags,
double  progress 
)

Definition at line 676 of file checkpointer.c.

References AbsorbFsyncRequests(), AmCheckpointerProcess, CheckArchiveTimeout(), CHECKPOINT_IMMEDIATE, got_SIGHUP, ImmediateCheckpointRequested(), IsCheckpointOnSchedule(), pg_usleep(), PGC_SIGHUP, pgstat_send_bgwriter(), ProcessConfigFile(), shutdown_requested, UpdateSharedMemoryConfig(), and WRITES_PER_ABSORB.

Referenced by BufferSync().

677 {
678  static int absorb_counter = WRITES_PER_ABSORB;
679 
680  /* Do nothing if checkpoint is being executed by non-checkpointer process */
681  if (!AmCheckpointerProcess())
682  return;
683 
684  /*
685  * Perform the usual duties and take a nap, unless we're behind schedule,
686  * in which case we just try to catch up as quickly as possible.
687  */
688  if (!(flags & CHECKPOINT_IMMEDIATE) &&
692  {
693  if (got_SIGHUP)
694  {
695  got_SIGHUP = false;
697  /* update shmem copies of config variables */
699  }
700 
702  absorb_counter = WRITES_PER_ABSORB;
703 
705 
706  /*
707  * Report interim activity statistics to the stats collector.
708  */
710 
711  /*
712  * This sleep used to be connected to bgwriter_delay, typically 200ms.
713  * That resulted in more frequent wakeups if not much work to do.
714  * Checkpointer and bgwriter are no longer related so take the Big
715  * Sleep.
716  */
717  pg_usleep(100000L);
718  }
719  else if (--absorb_counter <= 0)
720  {
721  /*
722  * Absorb pending fsync requests after each WRITES_PER_ABSORB write
723  * operations even when we don't sleep, to prevent overflow of the
724  * fsync request queue.
725  */
727  absorb_counter = WRITES_PER_ABSORB;
728  }
729 }
static bool IsCheckpointOnSchedule(double progress)
Definition: checkpointer.c:740
void ProcessConfigFile(GucContext context)
static bool ImmediateCheckpointRequested(void)
Definition: checkpointer.c:646
void pg_usleep(long microsec)
Definition: signal.c:53
#define AmCheckpointerProcess()
Definition: miscadmin.h:408
Definition: guc.h:72
int progress
Definition: pgbench.c:172
static void UpdateSharedMemoryConfig(void)
#define WRITES_PER_ABSORB
Definition: checkpointer.c:140
void pgstat_send_bgwriter(void)
Definition: pgstat.c:4151
static volatile sig_atomic_t got_SIGHUP
Definition: checkpointer.c:152
static void CheckArchiveTimeout(void)
Definition: checkpointer.c:585
#define CHECKPOINT_IMMEDIATE
Definition: xlog.h:178
void AbsorbFsyncRequests(void)
static volatile sig_atomic_t shutdown_requested
Definition: checkpointer.c:154
static void chkpt_quickdie ( SIGNAL_ARGS  )
static

Definition at line 823 of file checkpointer.c.

References BlockSig, on_exit_reset(), and PG_SETMASK.

Referenced by CheckpointerMain().

824 {
826 
827  /*
828  * We DO NOT want to run proc_exit() callbacks -- we're here because
829  * shared memory may be corrupted, so we don't want to try to clean up our
830  * transaction. Just nail the windows shut and get out of town. Now that
831  * there's an atexit callback to prevent third-party code from breaking
832  * things by calling exit() directly, we have to reset the callbacks
833  * explicitly to make this work as intended.
834  */
835  on_exit_reset();
836 
837  /*
838  * Note we do exit(2) not exit(0). This is to force the postmaster into a
839  * system reset cycle if some idiot DBA sends a manual SIGQUIT to a random
840  * backend. This is necessary precisely because we don't clean up our
841  * shared memory state. (The "dead man switch" mechanism in pmsignal.c
842  * should ensure the postmaster sees this as a crash, too, but no harm in
843  * being doubly sure.)
844  */
845  exit(2);
846 }
#define PG_SETMASK(mask)
Definition: pqsignal.h:19
void on_exit_reset(void)
Definition: ipc.c:396
sigset_t BlockSig
Definition: pqsignal.c:22
static void chkpt_sigusr1_handler ( SIGNAL_ARGS  )
static

Definition at line 874 of file checkpointer.c.

References latch_sigusr1_handler().

Referenced by CheckpointerMain().

875 {
876  int save_errno = errno;
877 
879 
880  errno = save_errno;
881 }
void latch_sigusr1_handler(void)
Definition: latch.c:1473
static void ChkptSigHupHandler ( SIGNAL_ARGS  )
static

Definition at line 850 of file checkpointer.c.

References got_SIGHUP, MyLatch, and SetLatch().

Referenced by CheckpointerMain().

851 {
852  int save_errno = errno;
853 
854  got_SIGHUP = true;
855  SetLatch(MyLatch);
856 
857  errno = save_errno;
858 }
static volatile sig_atomic_t got_SIGHUP
Definition: checkpointer.c:152
void SetLatch(volatile Latch *latch)
Definition: latch.c:414
struct Latch * MyLatch
Definition: globals.c:52
static bool CompactCheckpointerRequestQueue ( void  )
static

Definition at line 1194 of file checkpointer.c.

References Assert, CurrentMemoryContext, DEBUG1, HASHCTL::entrysize, ereport, errmsg(), HASH_BLOBS, HASH_CONTEXT, hash_create(), hash_destroy(), HASH_ELEM, HASH_ENTER, hash_search(), HASHCTL::hcxt, HASHCTL::keysize, LWLockHeldByMe(), MemSet, CheckpointerShmemStruct::num_requests, palloc0(), pfree(), and CheckpointerShmemStruct::requests.

Referenced by ForwardFsyncRequest().

1195 {
1196  struct CheckpointerSlotMapping
1197  {
1198  CheckpointerRequest request;
1199  int slot;
1200  };
1201 
1202  int n,
1203  preserve_count;
1204  int num_skipped = 0;
1205  HASHCTL ctl;
1206  HTAB *htab;
1207  bool *skip_slot;
1208 
1209  /* must hold CheckpointerCommLock in exclusive mode */
1210  Assert(LWLockHeldByMe(CheckpointerCommLock));
1211 
1212  /* Initialize skip_slot array */
1213  skip_slot = palloc0(sizeof(bool) * CheckpointerShmem->num_requests);
1214 
1215  /* Initialize temporary hash table */
1216  MemSet(&ctl, 0, sizeof(ctl));
1217  ctl.keysize = sizeof(CheckpointerRequest);
1218  ctl.entrysize = sizeof(struct CheckpointerSlotMapping);
1219  ctl.hcxt = CurrentMemoryContext;
1220 
1221  htab = hash_create("CompactCheckpointerRequestQueue",
1223  &ctl,
1225 
1226  /*
1227  * The basic idea here is that a request can be skipped if it's followed
1228  * by a later, identical request. It might seem more sensible to work
1229  * backwards from the end of the queue and check whether a request is
1230  * *preceded* by an earlier, identical request, in the hopes of doing less
1231  * copying. But that might change the semantics, if there's an
1232  * intervening FORGET_RELATION_FSYNC or FORGET_DATABASE_FSYNC request, so
1233  * we do it this way. It would be possible to be even smarter if we made
1234  * the code below understand the specific semantics of such requests (it
1235  * could blow away preceding entries that would end up being canceled
1236  * anyhow), but it's not clear that the extra complexity would buy us
1237  * anything.
1238  */
1239  for (n = 0; n < CheckpointerShmem->num_requests; n++)
1240  {
1241  CheckpointerRequest *request;
1242  struct CheckpointerSlotMapping *slotmap;
1243  bool found;
1244 
1245  /*
1246  * We use the request struct directly as a hashtable key. This
1247  * assumes that any padding bytes in the structs are consistently the
1248  * same, which should be okay because we zeroed them in
1249  * CheckpointerShmemInit. Note also that RelFileNode had better
1250  * contain no pad bytes.
1251  */
1252  request = &CheckpointerShmem->requests[n];
1253  slotmap = hash_search(htab, request, HASH_ENTER, &found);
1254  if (found)
1255  {
1256  /* Duplicate, so mark the previous occurrence as skippable */
1257  skip_slot[slotmap->slot] = true;
1258  num_skipped++;
1259  }
1260  /* Remember slot containing latest occurrence of this request value */
1261  slotmap->slot = n;
1262  }
1263 
1264  /* Done with the hash table. */
1265  hash_destroy(htab);
1266 
1267  /* If no duplicates, we're out of luck. */
1268  if (!num_skipped)
1269  {
1270  pfree(skip_slot);
1271  return false;
1272  }
1273 
1274  /* We found some duplicates; remove them. */
1275  preserve_count = 0;
1276  for (n = 0; n < CheckpointerShmem->num_requests; n++)
1277  {
1278  if (skip_slot[n])
1279  continue;
1280  CheckpointerShmem->requests[preserve_count++] = CheckpointerShmem->requests[n];
1281  }
1282  ereport(DEBUG1,
1283  (errmsg("compacted fsync request queue from %d entries to %d entries",
1284  CheckpointerShmem->num_requests, preserve_count)));
1285  CheckpointerShmem->num_requests = preserve_count;
1286 
1287  /* Cleanup. */
1288  pfree(skip_slot);
1289  return true;
1290 }
void hash_destroy(HTAB *hashp)
Definition: dynahash.c:810
#define DEBUG1
Definition: elog.h:25
#define HASH_CONTEXT
Definition: hsearch.h:93
#define HASH_ELEM
Definition: hsearch.h:87
MemoryContext hcxt
Definition: hsearch.h:78
bool LWLockHeldByMe(LWLock *l)
Definition: lwlock.c:1831
Size entrysize
Definition: hsearch.h:73
CheckpointerRequest requests[FLEXIBLE_ARRAY_MEMBER]
Definition: checkpointer.c:134
#define MemSet(start, val, len)
Definition: c.h:858
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
Definition: dynahash.c:902
Definition: dynahash.c:208
void pfree(void *pointer)
Definition: mcxt.c:950
MemoryContext CurrentMemoryContext
Definition: mcxt.c:37
#define ereport(elevel, rest)
Definition: elog.h:122
static CheckpointerShmemStruct * CheckpointerShmem
Definition: checkpointer.c:137
#define HASH_BLOBS
Definition: hsearch.h:88
void * palloc0(Size size)
Definition: mcxt.c:878
HTAB * hash_create(const char *tabname, long nelem, HASHCTL *info, int flags)
Definition: dynahash.c:316
Size keysize
Definition: hsearch.h:72
#define Assert(condition)
Definition: c.h:676
int errmsg(const char *fmt,...)
Definition: elog.c:797
bool FirstCallSinceLastCheckpoint ( void  )

Definition at line 1375 of file checkpointer.c.

References CheckpointerShmemStruct::ckpt_done, CheckpointerShmemStruct::ckpt_lck, SpinLockAcquire, and SpinLockRelease.

Referenced by BackgroundWriterMain().

1376 {
1377  static int ckpt_done = 0;
1378  int new_done;
1379  bool FirstCall = false;
1380 
1382  new_done = CheckpointerShmem->ckpt_done;
1384 
1385  if (new_done != ckpt_done)
1386  FirstCall = true;
1387 
1388  ckpt_done = new_done;
1389 
1390  return FirstCall;
1391 }
#define SpinLockAcquire(lock)
Definition: spin.h:62
static CheckpointerShmemStruct * CheckpointerShmem
Definition: checkpointer.c:137
#define SpinLockRelease(lock)
Definition: spin.h:64
bool ForwardFsyncRequest ( RelFileNode  rnode,
ForkNumber  forknum,
BlockNumber  segno 
)

Definition at line 1122 of file checkpointer.c.

References AmBackgroundWriterProcess, AmCheckpointerProcess, CheckpointerShmemStruct::checkpointer_pid, PROC_HDR::checkpointerLatch, CompactCheckpointerRequestQueue(), elog, ERROR, CheckpointerRequest::forknum, IsUnderPostmaster, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), CheckpointerShmemStruct::max_requests, CheckpointerShmemStruct::num_backend_fsync, CheckpointerShmemStruct::num_backend_writes, CheckpointerShmemStruct::num_requests, ProcGlobal, CheckpointerShmemStruct::requests, CheckpointerRequest::rnode, CheckpointerRequest::segno, and SetLatch().

Referenced by ForgetDatabaseFsyncRequests(), ForgetRelationFsyncRequests(), register_dirty_segment(), and register_unlink().

1123 {
1124  CheckpointerRequest *request;
1125  bool too_full;
1126 
1127  if (!IsUnderPostmaster)
1128  return false; /* probably shouldn't even get here */
1129 
1130  if (AmCheckpointerProcess())
1131  elog(ERROR, "ForwardFsyncRequest must not be called in checkpointer");
1132 
1133  LWLockAcquire(CheckpointerCommLock, LW_EXCLUSIVE);
1134 
1135  /* Count all backend writes regardless of if they fit in the queue */
1138 
1139  /*
1140  * If the checkpointer isn't running or the request queue is full, the
1141  * backend will have to perform its own fsync request. But before forcing
1142  * that to happen, we can try to compact the request queue.
1143  */
1144  if (CheckpointerShmem->checkpointer_pid == 0 ||
1147  {
1148  /*
1149  * Count the subset of writes where backends have to do their own
1150  * fsync
1151  */
1154  LWLockRelease(CheckpointerCommLock);
1155  return false;
1156  }
1157 
1158  /* OK, insert request */
1160  request->rnode = rnode;
1161  request->forknum = forknum;
1162  request->segno = segno;
1163 
1164  /* If queue is more than half full, nudge the checkpointer to empty it */
1165  too_full = (CheckpointerShmem->num_requests >=
1167 
1168  LWLockRelease(CheckpointerCommLock);
1169 
1170  /* ... but not till after we release the lock */
1171  if (too_full && ProcGlobal->checkpointerLatch)
1173 
1174  return true;
1175 }
CheckpointerRequest requests[FLEXIBLE_ARRAY_MEMBER]
Definition: checkpointer.c:134
PROC_HDR * ProcGlobal
Definition: proc.c:80
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1715
#define AmBackgroundWriterProcess()
Definition: miscadmin.h:407
#define ERROR
Definition: elog.h:43
#define AmCheckpointerProcess()
Definition: miscadmin.h:408
static bool CompactCheckpointerRequestQueue(void)
bool IsUnderPostmaster
Definition: globals.c:101
static CheckpointerShmemStruct * CheckpointerShmem
Definition: checkpointer.c:137
Latch * checkpointerLatch
Definition: proc.h:248
void SetLatch(volatile Latch *latch)
Definition: latch.c:414
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1111
#define elog
Definition: elog.h:219
static bool ImmediateCheckpointRequested ( void  )
static

Definition at line 646 of file checkpointer.c.

References CHECKPOINT_IMMEDIATE, checkpoint_requested, CheckpointerShmem, and CheckpointerShmemStruct::ckpt_flags.

Referenced by CheckpointWriteDelay().

647 {
649  {
651 
652  /*
653  * We don't need to acquire the ckpt_lck in this case because we're
654  * only looking at a single flag bit.
655  */
656  if (cps->ckpt_flags & CHECKPOINT_IMMEDIATE)
657  return true;
658  }
659  return false;
660 }
static CheckpointerShmemStruct * CheckpointerShmem
Definition: checkpointer.c:137
static volatile sig_atomic_t checkpoint_requested
Definition: checkpointer.c:153
#define CHECKPOINT_IMMEDIATE
Definition: xlog.h:178
static bool IsCheckpointOnSchedule ( double  progress)
static

Definition at line 740 of file checkpointer.c.

References Assert, CheckPointCompletionTarget, CheckPointSegments, CheckPointTimeout, ckpt_active, ckpt_cached_elapsed, ckpt_start_recptr, ckpt_start_time, elapsed_time(), GetInsertRecPtr(), gettimeofday(), GetXLogReplayRecPtr(), NULL, RecoveryInProgress(), and XLogSegSize.

Referenced by CheckpointWriteDelay().

741 {
742  XLogRecPtr recptr;
743  struct timeval now;
744  double elapsed_xlogs,
745  elapsed_time;
746 
748 
749  /* Scale progress according to checkpoint_completion_target. */
751 
752  /*
753  * Check against the cached value first. Only do the more expensive
754  * calculations once we reach the target previously calculated. Since
755  * neither time or WAL insert pointer moves backwards, a freshly
756  * calculated value can only be greater than or equal to the cached value.
757  */
759  return false;
760 
761  /*
762  * Check progress against WAL segments written and CheckPointSegments.
763  *
764  * We compare the current WAL insert location against the location
765  * computed before calling CreateCheckPoint. The code in XLogInsert that
766  * actually triggers a checkpoint when CheckPointSegments is exceeded
767  * compares against RedoRecptr, so this is not completely accurate.
768  * However, it's good enough for our purposes, we're only calculating an
769  * estimate anyway.
770  *
771  * During recovery, we compare last replayed WAL record's location with
772  * the location computed before calling CreateRestartPoint. That maintains
773  * the same pacing as we have during checkpoints in normal operation, but
774  * we might exceed max_wal_size by a fair amount. That's because there can
775  * be a large gap between a checkpoint's redo-pointer and the checkpoint
776  * record itself, and we only start the restartpoint after we've seen the
777  * checkpoint record. (The gap is typically up to CheckPointSegments *
778  * checkpoint_completion_target where checkpoint_completion_target is the
779  * value that was in effect when the WAL was generated).
780  */
781  if (RecoveryInProgress())
782  recptr = GetXLogReplayRecPtr(NULL);
783  else
784  recptr = GetInsertRecPtr();
785  elapsed_xlogs = (((double) (recptr - ckpt_start_recptr)) / XLogSegSize) / CheckPointSegments;
786 
787  if (progress < elapsed_xlogs)
788  {
789  ckpt_cached_elapsed = elapsed_xlogs;
790  return false;
791  }
792 
793  /*
794  * Check progress against time elapsed and checkpoint_timeout.
795  */
796  gettimeofday(&now, NULL);
797  elapsed_time = ((double) ((pg_time_t) now.tv_sec - ckpt_start_time) +
798  now.tv_usec / 1000000.0) / CheckPointTimeout;
799 
800  if (progress < elapsed_time)
801  {
803  return false;
804  }
805 
806  /* It looks like we're on schedule. */
807  return true;
808 }
#define XLogSegSize
Definition: xlog_internal.h:92
int gettimeofday(struct timeval *tp, struct timezone *tzp)
Definition: gettimeofday.c:105
XLogRecPtr GetInsertRecPtr(void)
Definition: xlog.c:8211
int64 pg_time_t
Definition: pgtime.h:23
bool RecoveryInProgress(void)
Definition: xlog.c:7878
XLogRecPtr GetXLogReplayRecPtr(TimeLineID *replayTLI)
Definition: xlog.c:11098
int CheckPointTimeout
Definition: checkpointer.c:145
int CheckPointSegments
Definition: xlog.c:124
int progress
Definition: pgbench.c:172
static bool ckpt_active
Definition: checkpointer.c:159
static pg_time_t ckpt_start_time
Definition: checkpointer.c:162
static XLogRecPtr ckpt_start_recptr
Definition: checkpointer.c:163
#define NULL
Definition: c.h:229
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define Assert(condition)
Definition: c.h:676
static double elapsed_time(instr_time *starttime)
Definition: explain.c:782
static double ckpt_cached_elapsed
Definition: checkpointer.c:164
Datum now(PG_FUNCTION_ARGS)
Definition: timestamp.c:1534
double CheckPointCompletionTarget
Definition: checkpointer.c:147
static void ReqCheckpointHandler ( SIGNAL_ARGS  )
static

Definition at line 862 of file checkpointer.c.

References checkpoint_requested, MyLatch, and SetLatch().

Referenced by CheckpointerMain().

863 {
864  int save_errno = errno;
865 
866  checkpoint_requested = true;
867  SetLatch(MyLatch);
868 
869  errno = save_errno;
870 }
void SetLatch(volatile Latch *latch)
Definition: latch.c:414
static volatile sig_atomic_t checkpoint_requested
Definition: checkpointer.c:153
struct Latch * MyLatch
Definition: globals.c:52
static void ReqShutdownHandler ( SIGNAL_ARGS  )
static

Definition at line 885 of file checkpointer.c.

References MyLatch, SetLatch(), and shutdown_requested.

Referenced by CheckpointerMain().

886 {
887  int save_errno = errno;
888 
889  shutdown_requested = true;
890  SetLatch(MyLatch);
891 
892  errno = save_errno;
893 }
void SetLatch(volatile Latch *latch)
Definition: latch.c:414
struct Latch * MyLatch
Definition: globals.c:52
static volatile sig_atomic_t shutdown_requested
Definition: checkpointer.c:154
void RequestCheckpoint ( int  flags)

Definition at line 966 of file checkpointer.c.

References CHECK_FOR_INTERRUPTS, CHECKPOINT_IMMEDIATE, CHECKPOINT_WAIT, CheckpointerShmemStruct::checkpointer_pid, CheckpointerShmemStruct::ckpt_done, CheckpointerShmemStruct::ckpt_failed, CheckpointerShmemStruct::ckpt_flags, CheckpointerShmemStruct::ckpt_lck, CheckpointerShmemStruct::ckpt_started, CreateCheckPoint(), elog, ereport, errhint(), errmsg(), ERROR, IsPostmasterEnvironment, LOG, pg_usleep(), smgrcloseall(), SpinLockAcquire, and SpinLockRelease.

Referenced by createdb(), do_pg_start_backup(), dropdb(), DropTableSpace(), movedb(), standard_ProcessUtility(), StartupXLOG(), XLogPageRead(), and XLogWrite().

967 {
968  int ntries;
969  int old_failed,
970  old_started;
971 
972  /*
973  * If in a standalone backend, just do it ourselves.
974  */
976  {
977  /*
978  * There's no point in doing slow checkpoints in a standalone backend,
979  * because there's no other backends the checkpoint could disrupt.
980  */
982 
983  /*
984  * After any checkpoint, close all smgr files. This is so we won't
985  * hang onto smgr references to deleted files indefinitely.
986  */
987  smgrcloseall();
988 
989  return;
990  }
991 
992  /*
993  * Atomically set the request flags, and take a snapshot of the counters.
994  * When we see ckpt_started > old_started, we know the flags we set here
995  * have been seen by checkpointer.
996  *
997  * Note that we OR the flags with any existing flags, to avoid overriding
998  * a "stronger" request by another backend. The flag senses must be
999  * chosen to make this work!
1000  */
1002 
1003  old_failed = CheckpointerShmem->ckpt_failed;
1004  old_started = CheckpointerShmem->ckpt_started;
1005  CheckpointerShmem->ckpt_flags |= flags;
1006 
1008 
1009  /*
1010  * Send signal to request checkpoint. It's possible that the checkpointer
1011  * hasn't started yet, or is in process of restarting, so we will retry a
1012  * few times if needed. Also, if not told to wait for the checkpoint to
1013  * occur, we consider failure to send the signal to be nonfatal and merely
1014  * LOG it.
1015  */
1016  for (ntries = 0;; ntries++)
1017  {
1019  {
1020  if (ntries >= 20) /* max wait 2.0 sec */
1021  {
1022  elog((flags & CHECKPOINT_WAIT) ? ERROR : LOG,
1023  "could not request checkpoint because checkpointer not running");
1024  break;
1025  }
1026  }
1027  else if (kill(CheckpointerShmem->checkpointer_pid, SIGINT) != 0)
1028  {
1029  if (ntries >= 20) /* max wait 2.0 sec */
1030  {
1031  elog((flags & CHECKPOINT_WAIT) ? ERROR : LOG,
1032  "could not signal for checkpoint: %m");
1033  break;
1034  }
1035  }
1036  else
1037  break; /* signal sent successfully */
1038 
1040  pg_usleep(100000L); /* wait 0.1 sec, then retry */
1041  }
1042 
1043  /*
1044  * If requested, wait for completion. We detect completion according to
1045  * the algorithm given above.
1046  */
1047  if (flags & CHECKPOINT_WAIT)
1048  {
1049  int new_started,
1050  new_failed;
1051 
1052  /* Wait for a new checkpoint to start. */
1053  for (;;)
1054  {
1056  new_started = CheckpointerShmem->ckpt_started;
1058 
1059  if (new_started != old_started)
1060  break;
1061 
1063  pg_usleep(100000L);
1064  }
1065 
1066  /*
1067  * We are waiting for ckpt_done >= new_started, in a modulo sense.
1068  */
1069  for (;;)
1070  {
1071  int new_done;
1072 
1074  new_done = CheckpointerShmem->ckpt_done;
1075  new_failed = CheckpointerShmem->ckpt_failed;
1077 
1078  if (new_done - new_started >= 0)
1079  break;
1080 
1082  pg_usleep(100000L);
1083  }
1084 
1085  if (new_failed != old_failed)
1086  ereport(ERROR,
1087  (errmsg("checkpoint request failed"),
1088  errhint("Consult recent messages in the server log for details.")));
1089  }
1090 }
bool IsPostmasterEnvironment
Definition: globals.c:100
int errhint(const char *fmt,...)
Definition: elog.c:987
void CreateCheckPoint(int flags)
Definition: xlog.c:8533
#define LOG
Definition: elog.h:26
void smgrcloseall(void)
Definition: smgr.c:326
#define SpinLockAcquire(lock)
Definition: spin.h:62
void pg_usleep(long microsec)
Definition: signal.c:53
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
static CheckpointerShmemStruct * CheckpointerShmem
Definition: checkpointer.c:137
#define SpinLockRelease(lock)
Definition: spin.h:64
#define CHECKPOINT_WAIT
Definition: xlog.h:183
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define CHECKPOINT_IMMEDIATE
Definition: xlog.h:178
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:98
#define elog
Definition: elog.h:219
static void UpdateSharedMemoryConfig ( void  )
static

Definition at line 1356 of file checkpointer.c.

References DEBUG2, elog, SyncRepUpdateSyncStandbysDefined(), and UpdateFullPageWrites().

Referenced by CheckpointerMain(), and CheckpointWriteDelay().

1357 {
1358  /* update global shmem state for sync rep */
1360 
1361  /*
1362  * If full_page_writes has been changed by SIGHUP, we update it in shared
1363  * memory and write an XLOG_FPW_CHANGE record.
1364  */
1366 
1367  elog(DEBUG2, "checkpointer updated shared memory configuration values");
1368 }
void SyncRepUpdateSyncStandbysDefined(void)
Definition: syncrep.c:1064
#define DEBUG2
Definition: elog.h:24
void UpdateFullPageWrites(void)
Definition: xlog.c:9510
#define elog
Definition: elog.h:219

Variable Documentation

volatile sig_atomic_t checkpoint_requested = false
static
double CheckPointCompletionTarget = 0.5
CheckpointerShmemStruct* CheckpointerShmem
static

Definition at line 137 of file checkpointer.c.

Referenced by ImmediateCheckpointRequested().

int CheckPointTimeout = 300

Definition at line 145 of file checkpointer.c.

Referenced by CheckpointerMain(), and IsCheckpointOnSchedule().

int CheckPointWarning = 30

Definition at line 146 of file checkpointer.c.

Referenced by CheckpointerMain().

bool ckpt_active = false
static

Definition at line 159 of file checkpointer.c.

Referenced by CheckpointerMain(), and IsCheckpointOnSchedule().

double ckpt_cached_elapsed
static

Definition at line 164 of file checkpointer.c.

Referenced by CheckpointerMain(), and IsCheckpointOnSchedule().

XLogRecPtr ckpt_start_recptr
static

Definition at line 163 of file checkpointer.c.

Referenced by CheckpointerMain(), and IsCheckpointOnSchedule().

pg_time_t ckpt_start_time
static

Definition at line 162 of file checkpointer.c.

Referenced by CheckpointerMain(), and IsCheckpointOnSchedule().

volatile sig_atomic_t got_SIGHUP = false
static

Definition at line 152 of file checkpointer.c.

Referenced by CheckpointerMain(), CheckpointWriteDelay(), and ChkptSigHupHandler().

pg_time_t last_checkpoint_time
static

Definition at line 166 of file checkpointer.c.

Referenced by CheckpointerMain().

pg_time_t last_xlog_switch_time
static

Definition at line 167 of file checkpointer.c.

Referenced by CheckArchiveTimeout(), and CheckpointerMain().

volatile sig_atomic_t shutdown_requested = false
static

Definition at line 154 of file checkpointer.c.

Referenced by CheckpointerMain(), CheckpointWriteDelay(), and ReqShutdownHandler().