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 1303 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().

1304 {
1305  CheckpointerRequest *requests = NULL;
1306  CheckpointerRequest *request;
1307  int n;
1308 
1309  if (!AmCheckpointerProcess())
1310  return;
1311 
1312  LWLockAcquire(CheckpointerCommLock, LW_EXCLUSIVE);
1313 
1314  /* Transfer stats counts into pending pgstats message */
1317 
1320 
1321  /*
1322  * We try to avoid holding the lock for a long time by copying the request
1323  * array, and processing the requests after releasing the lock.
1324  *
1325  * Once we have cleared the requests from shared memory, we have to PANIC
1326  * if we then fail to absorb them (eg, because our hashtable runs out of
1327  * memory). This is because the system cannot run safely if we are unable
1328  * to fsync what we have been told to fsync. Fortunately, the hashtable
1329  * is so small that the problem is quite unlikely to arise in practice.
1330  */
1332  if (n > 0)
1333  {
1334  requests = (CheckpointerRequest *) palloc(n * sizeof(CheckpointerRequest));
1335  memcpy(requests, CheckpointerShmem->requests, n * sizeof(CheckpointerRequest));
1336  }
1337 
1339 
1341 
1342  LWLockRelease(CheckpointerCommLock);
1343 
1344  for (request = requests; n > 0; request++, n--)
1345  RememberFsyncRequest(request->rnode, request->forknum, request->segno);
1346 
1347  END_CRIT_SECTION();
1348 
1349  if (requests)
1350  pfree(requests);
1351 }
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:132
PgStat_MsgBgWriter BgWriterStats
Definition: pgstat.c:127
CheckpointerRequest requests[FLEXIBLE_ARRAY_MEMBER]
Definition: checkpointer.c:134
#define START_CRIT_SECTION()
Definition: miscadmin.h:130
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1715
void pfree(void *pointer)
Definition: mcxt.c:950
#define AmCheckpointerProcess()
Definition: miscadmin.h:405
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 586 of file checkpointer.c.

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

Referenced by CheckpointerMain(), and CheckpointWriteDelay().

587 {
588  pg_time_t now;
589  pg_time_t last_time;
590  XLogRecPtr last_switch_lsn;
591 
593  return;
594 
595  now = (pg_time_t) time(NULL);
596 
597  /* First we do a quick check using possibly-stale local state. */
598  if ((int) (now - last_xlog_switch_time) < XLogArchiveTimeout)
599  return;
600 
601  /*
602  * Update local state ... note that last_xlog_switch_time is the last time
603  * a switch was performed *or requested*.
604  */
605  last_time = GetLastSegSwitchData(&last_switch_lsn);
606 
608 
609  /* Now we can do the real checks */
610  if ((int) (now - last_xlog_switch_time) >= XLogArchiveTimeout)
611  {
612  /*
613  * Switch segment only when "important" WAL has been logged since the
614  * last segment switch.
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  ereport(DEBUG1,
629  (errmsg("transaction log switch forced (archive_timeout=%d)",
631  }
632 
633  /*
634  * Update state in any case, so we don't retry constantly when the
635  * system is idle.
636  */
638  }
639 }
XLogRecPtr GetLastImportantRecPtr(void)
Definition: xlog.c:8230
#define XLogSegSize
Definition: xlog_internal.h:92
XLogRecPtr RequestXLogSwitch(bool mark_unimportant)
Definition: xlog.c:9385
#define DEBUG1
Definition: elog.h:25
int64 pg_time_t
Definition: pgtime.h:23
pg_time_t GetLastSegSwitchData(XLogRecPtr *lastSwitchLSN)
Definition: xlog.c:8259
int XLogArchiveTimeout
Definition: xlog.c:93
bool RecoveryInProgress(void)
Definition: xlog.c:7863
#define ereport(elevel, rest)
Definition: elog.h:122
static pg_time_t last_xlog_switch_time
Definition: checkpointer.c:167
#define Max(x, y)
Definition: c.h:800
#define NULL
Definition: c.h:229
uint64 XLogRecPtr
Definition: xlogdefs.h:21
int errmsg(const char *fmt,...)
Definition: elog.c:797
Datum now(PG_FUNCTION_ARGS)
Definition: timestamp.c:1533
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
209  * file */
210  pqsignal(SIGINT, ReqCheckpointHandler); /* request checkpoint */
211  pqsignal(SIGTERM, SIG_IGN); /* ignore SIGTERM */
212  pqsignal(SIGQUIT, chkpt_quickdie); /* hard crash time */
216  pqsignal(SIGUSR2, ReqShutdownHandler); /* request shutdown */
217 
218  /*
219  * Reset some signals that are accepted by postmaster but not here
220  */
226 
227  /* We allow SIGQUIT (quickdie) at all times */
228  sigdelset(&BlockSig, SIGQUIT);
229 
230  /*
231  * Initialize so that first time-driven event happens at the correct time.
232  */
234 
235  /*
236  * Create a resource owner to keep track of our resources (currently only
237  * buffer pins).
238  */
239  CurrentResourceOwner = ResourceOwnerCreate(NULL, "Checkpointer");
240 
241  /*
242  * Create a memory context that we will do all our work in. We do this so
243  * that we can reset the context during error recovery and thereby avoid
244  * possible memory leaks. Formerly this code just ran in
245  * TopMemoryContext, but resetting that would be a really bad idea.
246  */
247  checkpointer_context = AllocSetContextCreate(TopMemoryContext,
248  "Checkpointer",
250  MemoryContextSwitchTo(checkpointer_context);
251 
252  /*
253  * If an exception is encountered, processing resumes here.
254  *
255  * See notes in postgres.c about the design of this coding.
256  */
257  if (sigsetjmp(local_sigjmp_buf, 1) != 0)
258  {
259  /* Since not using PG_TRY, must reset error stack by hand */
261 
262  /* Prevent interrupts while cleaning up */
263  HOLD_INTERRUPTS();
264 
265  /* Report the error to the server log */
266  EmitErrorReport();
267 
268  /*
269  * These operations are really just a minimal subset of
270  * AbortTransaction(). We don't have very many resources to worry
271  * about in checkpointer, but we do have LWLocks, buffers, and temp
272  * files.
273  */
277  AbortBufferIO();
278  UnlockBuffers();
279  /* buffer pins are released here: */
282  false, true);
283  /* we needn't bother with the other ResourceOwnerRelease phases */
284  AtEOXact_Buffers(false);
285  AtEOXact_SMgr();
286  AtEOXact_Files();
287  AtEOXact_HashTables(false);
288 
289  /* Warn any waiting backends that the checkpoint failed. */
290  if (ckpt_active)
291  {
296 
297  ckpt_active = false;
298  }
299 
300  /*
301  * Now return to normal top-level context and clear ErrorContext for
302  * next time.
303  */
304  MemoryContextSwitchTo(checkpointer_context);
305  FlushErrorState();
306 
307  /* Flush any leaked data in the top-level context */
308  MemoryContextResetAndDeleteChildren(checkpointer_context);
309 
310  /* Now we can allow interrupts again */
312 
313  /*
314  * Sleep at least 1 second after any error. A write error is likely
315  * to be repeated, and we don't want to be filling the error logs as
316  * fast as we can.
317  */
318  pg_usleep(1000000L);
319 
320  /*
321  * Close all open files after any error. This is helpful on Windows,
322  * where holding deleted files open causes various strange errors.
323  * It's not clear we need it elsewhere, but shouldn't hurt.
324  */
325  smgrcloseall();
326  }
327 
328  /* We can now handle ereport(ERROR) */
329  PG_exception_stack = &local_sigjmp_buf;
330 
331  /*
332  * Unblock signals (they were blocked when the postmaster forked us)
333  */
335 
336  /*
337  * Ensure all shared memory values are set correctly for the config. Doing
338  * this here ensures no race conditions from other concurrent updaters.
339  */
341 
342  /*
343  * Advertise our latch that backends can use to wake us up while we're
344  * sleeping.
345  */
347 
348  /*
349  * Loop forever
350  */
351  for (;;)
352  {
353  bool do_checkpoint = false;
354  int flags = 0;
355  pg_time_t now;
356  int elapsed_secs;
357  int cur_timeout;
358  int rc;
359 
360  /* Clear any already-pending wakeups */
362 
363  /*
364  * Process any requests or signals received recently.
365  */
367 
368  if (got_SIGHUP)
369  {
370  got_SIGHUP = false;
372 
373  /*
374  * Checkpointer is the last process to shut down, so we ask it to
375  * hold the keys for a range of other tasks required most of which
376  * have nothing to do with checkpointing at all.
377  *
378  * For various reasons, some config values can change dynamically
379  * so the primary copy of them is held in shared memory to make
380  * sure all backends see the same value. We make Checkpointer
381  * responsible for updating the shared memory copy if the
382  * parameter setting changes because of SIGHUP.
383  */
385  }
387  {
388  checkpoint_requested = false;
389  do_checkpoint = true;
391  }
392  if (shutdown_requested)
393  {
394  /*
395  * From here on, elog(ERROR) should end with exit(1), not send
396  * control back to the sigsetjmp block above
397  */
398  ExitOnAnyError = true;
399  /* Close down the database */
400  ShutdownXLOG(0, 0);
401  /* Normal exit from the checkpointer is here */
402  proc_exit(0); /* done */
403  }
404 
405  /*
406  * Force a checkpoint if too much time has elapsed since the last one.
407  * Note that we count a timed checkpoint in stats only when this
408  * occurs without an external request, but we set the CAUSE_TIME flag
409  * bit even if there is also an external request.
410  */
411  now = (pg_time_t) time(NULL);
412  elapsed_secs = now - last_checkpoint_time;
413  if (elapsed_secs >= CheckPointTimeout)
414  {
415  if (!do_checkpoint)
417  do_checkpoint = true;
418  flags |= CHECKPOINT_CAUSE_TIME;
419  }
420 
421  /*
422  * Do a checkpoint if requested.
423  */
424  if (do_checkpoint)
425  {
426  bool ckpt_performed = false;
427  bool do_restartpoint;
428 
429  /*
430  * Check if we should perform a checkpoint or a restartpoint. As a
431  * side-effect, RecoveryInProgress() initializes TimeLineID if
432  * it's not set yet.
433  */
434  do_restartpoint = RecoveryInProgress();
435 
436  /*
437  * Atomically fetch the request flags to figure out what kind of a
438  * checkpoint we should perform, and increase the started-counter
439  * to acknowledge that we've started a new checkpoint.
440  */
442  flags |= CheckpointerShmem->ckpt_flags;
446 
447  /*
448  * The end-of-recovery checkpoint is a real checkpoint that's
449  * performed while we're still in recovery.
450  */
451  if (flags & CHECKPOINT_END_OF_RECOVERY)
452  do_restartpoint = false;
453 
454  /*
455  * We will warn if (a) too soon since last checkpoint (whatever
456  * caused it) and (b) somebody set the CHECKPOINT_CAUSE_XLOG flag
457  * since the last checkpoint start. Note in particular that this
458  * implementation will not generate warnings caused by
459  * CheckPointTimeout < CheckPointWarning.
460  */
461  if (!do_restartpoint &&
462  (flags & CHECKPOINT_CAUSE_XLOG) &&
463  elapsed_secs < CheckPointWarning)
464  ereport(LOG,
465  (errmsg_plural("checkpoints are occurring too frequently (%d second apart)",
466  "checkpoints are occurring too frequently (%d seconds apart)",
467  elapsed_secs,
468  elapsed_secs),
469  errhint("Consider increasing the configuration parameter \"max_wal_size\".")));
470 
471  /*
472  * Initialize checkpointer-private variables used during
473  * checkpoint.
474  */
475  ckpt_active = true;
476  if (do_restartpoint)
478  else
482 
483  /*
484  * Do the checkpoint.
485  */
486  if (!do_restartpoint)
487  {
488  CreateCheckPoint(flags);
489  ckpt_performed = true;
490  }
491  else
492  ckpt_performed = CreateRestartPoint(flags);
493 
494  /*
495  * After any checkpoint, close all smgr files. This is so we
496  * won't hang onto smgr references to deleted files indefinitely.
497  */
498  smgrcloseall();
499 
500  /*
501  * Indicate checkpoint completion to any waiting backends.
502  */
506 
507  if (ckpt_performed)
508  {
509  /*
510  * Note we record the checkpoint start time not end time as
511  * last_checkpoint_time. This is so that time-driven
512  * checkpoints happen at a predictable spacing.
513  */
514  last_checkpoint_time = now;
515  }
516  else
517  {
518  /*
519  * We were not able to perform the restartpoint (checkpoints
520  * throw an ERROR in case of error). Most likely because we
521  * have not received any new checkpoint WAL records since the
522  * last restartpoint. Try again in 15 s.
523  */
524  last_checkpoint_time = now - CheckPointTimeout + 15;
525  }
526 
527  ckpt_active = false;
528  }
529 
530  /* Check for archive_timeout and switch xlog files if necessary. */
532 
533  /*
534  * Send off activity statistics to the stats collector. (The reason
535  * why we re-use bgwriter-related code for this is that the bgwriter
536  * and checkpointer used to be just one process. It's probably not
537  * worth the trouble to split the stats support into two independent
538  * stats message types.)
539  */
541 
542  /*
543  * Sleep until we are signaled or it's time for another checkpoint or
544  * xlog file switch.
545  */
546  now = (pg_time_t) time(NULL);
547  elapsed_secs = now - last_checkpoint_time;
548  if (elapsed_secs >= CheckPointTimeout)
549  continue; /* no sleep for us ... */
550  cur_timeout = CheckPointTimeout - elapsed_secs;
552  {
553  elapsed_secs = now - last_xlog_switch_time;
554  if (elapsed_secs >= XLogArchiveTimeout)
555  continue; /* no sleep for us ... */
556  cur_timeout = Min(cur_timeout, XLogArchiveTimeout - elapsed_secs);
557  }
558 
559  rc = WaitLatch(MyLatch,
561  cur_timeout * 1000L /* convert to ms */,
563 
564  /*
565  * Emergency bailout if postmaster has died. This is to avoid the
566  * necessity for manual cleanup of all postmaster children.
567  */
568  if (rc & WL_POSTMASTER_DEATH)
569  exit(1);
570  }
571 }
#define SIGUSR1
Definition: win32.h:211
XLogRecPtr GetInsertRecPtr(void)
Definition: xlog.c:8196
int MyProcPid
Definition: globals.c:38
int errhint(const char *fmt,...)
Definition: elog.c:987
#define SIGCONT
Definition: win32.h:205
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:863
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:8507
PGPROC * MyProc
Definition: proc.c:67
PgStat_Counter m_timed_checkpoints
Definition: pgstat.h:413
#define SIGWINCH
Definition: win32.h:209
void AtEOXact_Buffers(bool isCommit)
Definition: bufmgr.c:2415
ResourceOwner CurrentResourceOwner
Definition: resowner.c:138
#define Min(x, y)
Definition: c.h:806
bool CreateRestartPoint(int flags)
Definition: xlog.c:9054
#define SIGTTIN
Definition: win32.h:207
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
PgStat_MsgBgWriter BgWriterStats
Definition: pgstat.c:127
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:461
#define LOG
Definition: elog.h:26
bool RecoveryInProgress(void)
Definition: xlog.c:7863
#define SIGQUIT
Definition: win32.h:197
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:116
ErrorContextCallback * error_context_stack
Definition: elog.c:88
#define CHECKPOINT_CAUSE_XLOG
Definition: xlog.h:186
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:300
#define SIG_IGN
Definition: win32.h:193
void ConditionVariableCancelSleep(void)
void AtEOXact_Files(void)
Definition: fd.c:2580
XLogRecPtr GetXLogReplayRecPtr(TimeLineID *replayTLI)
Definition: xlog.c:11070
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:165
static void ChkptSigHupHandler(SIGNAL_ARGS)
Definition: checkpointer.c:851
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:1205
#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:8311
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:104
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:824
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:3910
#define SIGPIPE
Definition: win32.h:201
#define SIGHUP
Definition: win32.h:196
#define SIG_DFL
Definition: win32.h:191
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:886
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:208
static double ckpt_cached_elapsed
Definition: checkpointer.c:164
static void CheckArchiveTimeout(void)
Definition: checkpointer.c:586
#define HOLD_INTERRUPTS()
Definition: miscadmin.h:114
#define CHECKPOINT_CAUSE_TIME
Definition: xlog.h:187
struct Latch * MyLatch
Definition: globals.c:51
void LWLockReleaseAll(void)
Definition: lwlock.c:1814
void AbsorbFsyncRequests(void)
void AtEOXact_HashTables(bool isCommit)
Definition: dynahash.c:1798
#define SIGCHLD
Definition: win32.h:206
static void chkpt_sigusr1_handler(SIGNAL_ARGS)
Definition: checkpointer.c:875
static pg_time_t last_checkpoint_time
Definition: checkpointer.c:166
#define WL_LATCH_SET
Definition: latch.h:124
#define SIGALRM
Definition: win32.h:202
Datum now(PG_FUNCTION_ARGS)
Definition: timestamp.c:1533
#define SIGUSR2
Definition: win32.h:212
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 926 of file checkpointer.c.

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

Referenced by CreateSharedMemoryAndSemaphores().

927 {
928  Size size = CheckpointerShmemSize();
929  bool found;
930 
932  ShmemInitStruct("Checkpointer Data",
933  size,
934  &found);
935 
936  if (!found)
937  {
938  /*
939  * First time through, so initialize. Note that we zero the whole
940  * requests array; this is so that CompactCheckpointerRequestQueue can
941  * assume that any pad bytes in the request structs are zeroes.
942  */
943  MemSet(CheckpointerShmem, 0, size);
946  }
947 }
#define SpinLockInit(lock)
Definition: spin.h:60
#define MemSet(start, val, len)
Definition: c.h:857
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:907
size_t Size
Definition: c.h:356
int NBuffers
Definition: globals.c:122
Size CheckpointerShmemSize ( void  )

Definition at line 907 of file checkpointer.c.

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

Referenced by CheckpointerShmemInit(), and CreateSharedMemoryAndSemaphores().

908 {
909  Size size;
910 
911  /*
912  * Currently, the size of the requests[] array is arbitrarily set equal to
913  * NBuffers. This may prove too large or small ...
914  */
915  size = offsetof(CheckpointerShmemStruct, requests);
916  size = add_size(size, mul_size(NBuffers, sizeof(CheckpointerRequest)));
917 
918  return size;
919 }
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:122
#define offsetof(type, field)
Definition: c.h:555
void CheckpointWriteDelay ( int  flags,
double  progress 
)

Definition at line 677 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().

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

Definition at line 824 of file checkpointer.c.

References BlockSig, on_exit_reset(), and PG_SETMASK.

Referenced by CheckpointerMain().

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

References latch_sigusr1_handler().

Referenced by CheckpointerMain().

876 {
877  int save_errno = errno;
878 
880 
881  errno = save_errno;
882 }
void latch_sigusr1_handler(void)
Definition: latch.c:1572
static void ChkptSigHupHandler ( SIGNAL_ARGS  )
static

Definition at line 851 of file checkpointer.c.

References got_SIGHUP, MyLatch, and SetLatch().

Referenced by CheckpointerMain().

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

Definition at line 1195 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().

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

Definition at line 1376 of file checkpointer.c.

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

Referenced by BackgroundWriterMain().

1377 {
1378  static int ckpt_done = 0;
1379  int new_done;
1380  bool FirstCall = false;
1381 
1383  new_done = CheckpointerShmem->ckpt_done;
1385 
1386  if (new_done != ckpt_done)
1387  FirstCall = true;
1388 
1389  ckpt_done = new_done;
1390 
1391  return FirstCall;
1392 }
#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 1123 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().

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

Definition at line 647 of file checkpointer.c.

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

Referenced by CheckpointWriteDelay().

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

Definition at line 741 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().

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

Definition at line 863 of file checkpointer.c.

References checkpoint_requested, MyLatch, and SetLatch().

Referenced by CheckpointerMain().

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

Definition at line 886 of file checkpointer.c.

References MyLatch, SetLatch(), and shutdown_requested.

Referenced by CheckpointerMain().

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

Definition at line 967 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().

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

Definition at line 1357 of file checkpointer.c.

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

Referenced by CheckpointerMain(), and CheckpointWriteDelay().

1358 {
1359  /* update global shmem state for sync rep */
1361 
1362  /*
1363  * If full_page_writes has been changed by SIGHUP, we update it in shared
1364  * memory and write an XLOG_FPW_CHANGE record.
1365  */
1367 
1368  elog(DEBUG2, "checkpointer updated shared memory configuration values");
1369 }
void SyncRepUpdateSyncStandbysDefined(void)
Definition: syncrep.c:1022
#define DEBUG2
Definition: elog.h:24
void UpdateFullPageWrites(void)
Definition: xlog.c:9484
#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().