diff options
-rw-r--r-- | doc/src/sgml/ref/checkpoint.sgml | 35 | ||||
-rw-r--r-- | src/backend/postmaster/checkpointer.c | 28 | ||||
-rw-r--r-- | src/bin/psql/tab-complete.in.c | 13 | ||||
-rw-r--r-- | src/test/regress/expected/stats.out | 9 | ||||
-rw-r--r-- | src/test/regress/sql/stats.sql | 6 |
5 files changed, 79 insertions, 12 deletions
diff --git a/doc/src/sgml/ref/checkpoint.sgml b/doc/src/sgml/ref/checkpoint.sgml index fad5e982d03..36a9e323f44 100644 --- a/doc/src/sgml/ref/checkpoint.sgml +++ b/doc/src/sgml/ref/checkpoint.sgml @@ -24,6 +24,8 @@ PostgreSQL documentation CHECKPOINT [ ( option [, ...] ) ] <phrase>where <replaceable class="parameter">option</replaceable> can be one of:</phrase> + + MODE { FAST | SPREAD } </synopsis> </refsynopsisdiv> @@ -39,15 +41,25 @@ CHECKPOINT [ ( option [, ...] ) ] </para> <para> - The <command>CHECKPOINT</command> command forces a fast + By default, the <command>CHECKPOINT</command> command forces a fast checkpoint when the command is issued, without waiting for a regular checkpoint scheduled by the system (controlled by the settings in <xref linkend="runtime-config-wal-checkpoints"/>). + To request the checkpoint be spread over a longer interval, set the + <literal>MODE</literal> option to <literal>SPREAD</literal>. <command>CHECKPOINT</command> is not intended for use during normal operation. </para> <para> + The server may consolidate concurrently requested checkpoints. Such + consolidated requests will contain a combined set of options. For example, + if one session requests a fast checkpoint and another requests a spread + checkpoint, the server may combine those requests and perform one fast + checkpoint. + </para> + + <para> If executed during recovery, the <command>CHECKPOINT</command> command will force a restartpoint (see <xref linkend="wal-configuration"/>) rather than writing a new checkpoint. @@ -63,8 +75,25 @@ CHECKPOINT [ ( option [, ...] ) ] <refsect1> <title>Parameters</title> - <para> - </para> + <variablelist> + <varlistentry> + <term><literal>MODE</literal></term> + <listitem> + <para> + When set to <literal>FAST</literal>, which is the default, the requested + checkpoint will be completed as fast as possible, which may result in a + significantly higher rate of I/O during the checkpoint. + </para> + <para> + <literal>MODE</literal> can also be set to <literal>SPREAD</literal> to + request the checkpoint be spread over a longer interval (controlled via + the settings in <xref linkend="runtime-config-wal-checkpoints"/>), like a + regular checkpoint scheduled by the system. This can reduce the rate of + I/O during the checkpoint. + </para> + </listitem> + </varlistentry> + </variablelist> </refsect1> <refsect1> diff --git a/src/backend/postmaster/checkpointer.c b/src/backend/postmaster/checkpointer.c index dc01f2382f1..9d77269a374 100644 --- a/src/backend/postmaster/checkpointer.c +++ b/src/backend/postmaster/checkpointer.c @@ -43,6 +43,7 @@ #include "access/xlog_internal.h" #include "access/xlogrecovery.h" #include "catalog/pg_authid.h" +#include "commands/defrem.h" #include "libpq/pqsignal.h" #include "miscadmin.h" #include "pgstat.h" @@ -987,11 +988,28 @@ CheckpointerShmemInit(void) void ExecCheckpoint(ParseState *pstate, CheckPointStmt *stmt) { + bool fast = true; + foreach_ptr(DefElem, opt, stmt->options) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("unrecognized CHECKPOINT option \"%s\"", opt->defname), - parser_errposition(pstate, opt->location))); + { + if (strcmp(opt->defname, "mode") == 0) + { + char *mode = defGetString(opt); + + if (strcmp(mode, "spread") == 0) + fast = false; + else if (strcmp(mode, "fast") != 0) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("unrecognized MODE option \"%s\"", mode), + parser_errposition(pstate, opt->location))); + } + else + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("unrecognized CHECKPOINT option \"%s\"", opt->defname), + parser_errposition(pstate, opt->location))); + } if (!has_privs_of_role(GetUserId(), ROLE_PG_CHECKPOINT)) ereport(ERROR, @@ -1003,7 +1021,7 @@ ExecCheckpoint(ParseState *pstate, CheckPointStmt *stmt) "pg_checkpoint"))); RequestCheckpoint(CHECKPOINT_WAIT | - CHECKPOINT_FAST | + (fast ? CHECKPOINT_FAST : 0) | (RecoveryInProgress() ? 0 : CHECKPOINT_FORCE)); } diff --git a/src/bin/psql/tab-complete.in.c b/src/bin/psql/tab-complete.in.c index 089fe367d9f..a7db04efd93 100644 --- a/src/bin/psql/tab-complete.in.c +++ b/src/bin/psql/tab-complete.in.c @@ -3156,6 +3156,19 @@ match_previous_words(int pattern_id, /* CHECKPOINT */ else if (Matches("CHECKPOINT")) COMPLETE_WITH("("); + else if (HeadMatches("CHECKPOINT", "(*") && + !HeadMatches("CHECKPOINT", "(*)")) + { + /* + * This fires if we're in an unfinished parenthesized option list. + * get_previous_words treats a completed parenthesized option list as + * one word, so the above test is correct. + */ + if (ends_with(prev_wd, '(') || ends_with(prev_wd, ',')) + COMPLETE_WITH("MODE"); + else if (TailMatches("MODE")) + COMPLETE_WITH("FAST", "SPREAD"); + } /* CLOSE */ else if (Matches("CLOSE")) COMPLETE_WITH_QUERY_PLUS(Query_for_list_of_cursors, diff --git a/src/test/regress/expected/stats.out b/src/test/regress/expected/stats.out index 9b865ae5f6c..b4df9ad5960 100644 --- a/src/test/regress/expected/stats.out +++ b/src/test/regress/expected/stats.out @@ -927,12 +927,17 @@ DROP TABLE test_stats_temp; -- of the checkpoint. But after a second checkpoint we'll see at least the -- results of the first. -- --- While at it, test checkpoint options. +-- While at it, test checkpoint options. Note that we don't test MODE SPREAD +-- because it would prolong the test. CHECKPOINT (WRONG); ERROR: unrecognized CHECKPOINT option "wrong" LINE 1: CHECKPOINT (WRONG); ^ -CHECKPOINT; +CHECKPOINT (MODE WRONG); +ERROR: unrecognized MODE option "wrong" +LINE 1: CHECKPOINT (MODE WRONG); + ^ +CHECKPOINT (MODE FAST); CHECKPOINT; SELECT num_requested > :rqst_ckpts_before FROM pg_stat_checkpointer; ?column? diff --git a/src/test/regress/sql/stats.sql b/src/test/regress/sql/stats.sql index 97b50926aa6..0868b250a64 100644 --- a/src/test/regress/sql/stats.sql +++ b/src/test/regress/sql/stats.sql @@ -440,9 +440,11 @@ DROP TABLE test_stats_temp; -- of the checkpoint. But after a second checkpoint we'll see at least the -- results of the first. -- --- While at it, test checkpoint options. +-- While at it, test checkpoint options. Note that we don't test MODE SPREAD +-- because it would prolong the test. CHECKPOINT (WRONG); -CHECKPOINT; +CHECKPOINT (MODE WRONG); +CHECKPOINT (MODE FAST); CHECKPOINT; SELECT num_requested > :rqst_ckpts_before FROM pg_stat_checkpointer; |