Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit cdd46c7

Browse files
committed
Start background writer during archive recovery. Background writer now performs
its usual buffer cleaning duties during archive recovery, and it's responsible for performing restartpoints. This requires some changes in postmaster. When the startup process has done all the initialization and is ready to start WAL redo, it signals the postmaster to launch the background writer. The postmaster is signaled again when the point in recovery is reached where we know that the database is in consistent state. Postmaster isn't interested in that at the moment, but that's the point where we could let other backends in to perform read-only queries. The postmaster is signaled third time when the recovery has ended, so that postmaster knows that it's safe to start accepting connections. The startup process now traps SIGTERM, and performs a "clean" shutdown. If you do a fast shutdown during recovery, a shutdown restartpoint is performed, like a shutdown checkpoint, and postmaster kills the processes cleanly. You still have to continue the recovery at next startup, though. Currently, the background writer is only launched during archive recovery. We could launch it during crash recovery as well, but it seems better to keep that codepath as simple as possible, for the sake of robustness. And it couldn't do any restartpoints during crash recovery anyway, so it wouldn't be that useful. log_restartpoints is gone. Use log_checkpoints instead. This is yet to be documented. This whole operation is a pre-requisite for Hot Standby, but has some value of its own whether the hot standby patch makes 8.4 or not. Simon Riggs, with lots of modifications by me.
1 parent 36a9cf3 commit cdd46c7

File tree

8 files changed

+920
-191
lines changed

8 files changed

+920
-191
lines changed

src/backend/access/transam/xlog.c

+577-98
Large diffs are not rendered by default.

src/backend/bootstrap/bootstrap.c

+4-7
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/bootstrap/bootstrap.c,v 1.249 2009/01/22 20:16:00 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/bootstrap/bootstrap.c,v 1.250 2009/02/18 15:58:41 heikki Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -37,7 +37,6 @@
3737
#include "storage/proc.h"
3838
#include "tcop/tcopprot.h"
3939
#include "utils/builtins.h"
40-
#include "utils/flatfiles.h"
4140
#include "utils/fmgroids.h"
4241
#include "utils/memutils.h"
4342
#include "utils/ps_status.h"
@@ -416,14 +415,12 @@ AuxiliaryProcessMain(int argc, char *argv[])
416415
proc_exit(1); /* should never return */
417416

418417
case StartupProcess:
419-
bootstrap_signals();
420-
StartupXLOG();
421-
BuildFlatFiles(false);
422-
proc_exit(0); /* startup done */
418+
/* don't set signals, startup process has its own agenda */
419+
StartupProcessMain();
420+
proc_exit(1); /* should never return */
423421

424422
case BgWriterProcess:
425423
/* don't set signals, bgwriter has its own agenda */
426-
InitXLOGAccess();
427424
BackgroundWriterMain();
428425
proc_exit(1); /* should never return */
429426

src/backend/postmaster/bgwriter.c

+56-21
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
*
3838
*
3939
* IDENTIFICATION
40-
* $PostgreSQL: pgsql/src/backend/postmaster/bgwriter.c,v 1.55 2009/01/01 17:23:46 momjian Exp $
40+
* $PostgreSQL: pgsql/src/backend/postmaster/bgwriter.c,v 1.56 2009/02/18 15:58:41 heikki Exp $
4141
*
4242
*-------------------------------------------------------------------------
4343
*/
@@ -49,6 +49,7 @@
4949
#include <unistd.h>
5050

5151
#include "access/xlog_internal.h"
52+
#include "catalog/pg_control.h"
5253
#include "libpq/pqsignal.h"
5354
#include "miscadmin.h"
5455
#include "pgstat.h"
@@ -423,9 +424,19 @@ BackgroundWriterMain(void)
423424
*/
424425
if (do_checkpoint)
425426
{
427+
bool ckpt_performed = false;
428+
bool do_restartpoint;
429+
426430
/* use volatile pointer to prevent code rearrangement */
427431
volatile BgWriterShmemStruct *bgs = BgWriterShmem;
428432

433+
/*
434+
* Check if we should perform a checkpoint or a restartpoint.
435+
* As a side-effect, RecoveryInProgress() initializes
436+
* TimeLineID if it's not set yet.
437+
*/
438+
do_restartpoint = RecoveryInProgress();
439+
429440
/*
430441
* Atomically fetch the request flags to figure out what kind of a
431442
* checkpoint we should perform, and increase the started-counter
@@ -444,7 +455,8 @@ BackgroundWriterMain(void)
444455
* implementation will not generate warnings caused by
445456
* CheckPointTimeout < CheckPointWarning.
446457
*/
447-
if ((flags & CHECKPOINT_CAUSE_XLOG) &&
458+
if (!do_restartpoint &&
459+
(flags & CHECKPOINT_CAUSE_XLOG) &&
448460
elapsed_secs < CheckPointWarning)
449461
ereport(LOG,
450462
(errmsg("checkpoints are occurring too frequently (%d seconds apart)",
@@ -455,14 +467,21 @@ BackgroundWriterMain(void)
455467
* Initialize bgwriter-private variables used during checkpoint.
456468
*/
457469
ckpt_active = true;
458-
ckpt_start_recptr = GetInsertRecPtr();
470+
if (!do_restartpoint)
471+
ckpt_start_recptr = GetInsertRecPtr();
459472
ckpt_start_time = now;
460473
ckpt_cached_elapsed = 0;
461474

462475
/*
463476
* Do the checkpoint.
464477
*/
465-
CreateCheckPoint(flags);
478+
if (!do_restartpoint)
479+
{
480+
CreateCheckPoint(flags);
481+
ckpt_performed = true;
482+
}
483+
else
484+
ckpt_performed = CreateRestartPoint(flags);
466485

467486
/*
468487
* After any checkpoint, close all smgr files. This is so we
@@ -477,14 +496,27 @@ BackgroundWriterMain(void)
477496
bgs->ckpt_done = bgs->ckpt_started;
478497
SpinLockRelease(&bgs->ckpt_lck);
479498

480-
ckpt_active = false;
499+
if (ckpt_performed)
500+
{
501+
/*
502+
* Note we record the checkpoint start time not end time as
503+
* last_checkpoint_time. This is so that time-driven
504+
* checkpoints happen at a predictable spacing.
505+
*/
506+
last_checkpoint_time = now;
507+
}
508+
else
509+
{
510+
/*
511+
* We were not able to perform the restartpoint (checkpoints
512+
* throw an ERROR in case of error). Most likely because we
513+
* have not received any new checkpoint WAL records since the
514+
* last restartpoint. Try again in 15 s.
515+
*/
516+
last_checkpoint_time = now - CheckPointTimeout + 15;
517+
}
481518

482-
/*
483-
* Note we record the checkpoint start time not end time as
484-
* last_checkpoint_time. This is so that time-driven checkpoints
485-
* happen at a predictable spacing.
486-
*/
487-
last_checkpoint_time = now;
519+
ckpt_active = false;
488520
}
489521
else
490522
BgBufferSync();
@@ -507,7 +539,7 @@ CheckArchiveTimeout(void)
507539
pg_time_t now;
508540
pg_time_t last_time;
509541

510-
if (XLogArchiveTimeout <= 0)
542+
if (XLogArchiveTimeout <= 0 || RecoveryInProgress())
511543
return;
512544

513545
now = (pg_time_t) time(NULL);
@@ -714,16 +746,19 @@ IsCheckpointOnSchedule(double progress)
714746
* However, it's good enough for our purposes, we're only calculating an
715747
* estimate anyway.
716748
*/
717-
recptr = GetInsertRecPtr();
718-
elapsed_xlogs =
719-
(((double) (int32) (recptr.xlogid - ckpt_start_recptr.xlogid)) * XLogSegsPerFile +
720-
((double) recptr.xrecoff - (double) ckpt_start_recptr.xrecoff) / XLogSegSize) /
721-
CheckPointSegments;
722-
723-
if (progress < elapsed_xlogs)
749+
if (!RecoveryInProgress())
724750
{
725-
ckpt_cached_elapsed = elapsed_xlogs;
726-
return false;
751+
recptr = GetInsertRecPtr();
752+
elapsed_xlogs =
753+
(((double) (int32) (recptr.xlogid - ckpt_start_recptr.xlogid)) * XLogSegsPerFile +
754+
((double) recptr.xrecoff - (double) ckpt_start_recptr.xrecoff) / XLogSegSize) /
755+
CheckPointSegments;
756+
757+
if (progress < elapsed_xlogs)
758+
{
759+
ckpt_cached_elapsed = elapsed_xlogs;
760+
return false;
761+
}
727762
}
728763

729764
/*

0 commit comments

Comments
 (0)