Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit1007465

Browse files
committed
Add pg_promote function
This function is able to promote a standby with this new SQL-callablefunction. Execution access can be granted to non-superusers so thatfailover tools can observe the principle of least privilege.Catalog version is bumped.Author: Laurenz AlbeReviewed-by: Michael Paquier, Masahiko SawadaDiscussion:https://postgr.es/m/6e7c79b3ec916cf49742fb8849ed17cd87aed620.camel@cybertec.at
1 parent0a8590b commit1007465

File tree

13 files changed

+143
-20
lines changed

13 files changed

+143
-20
lines changed

‎doc/src/sgml/func.sgml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19202,6 +19202,9 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup());
1920219202
<indexterm>
1920319203
<primary>pg_is_wal_replay_paused</primary>
1920419204
</indexterm>
19205+
<indexterm>
19206+
<primary>pg_promote</primary>
19207+
</indexterm>
1920519208
<indexterm>
1920619209
<primary>pg_wal_replay_pause</primary>
1920719210
</indexterm>
@@ -19232,6 +19235,22 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup());
1923219235
<entry>True if recovery is paused.
1923319236
</entry>
1923419237
</row>
19238+
<row>
19239+
<entry>
19240+
<literal><function>pg_promote(<parameter>wait</parameter> <type>boolean</type> DEFAULT true, <parameter>wait_seconds</parameter> <type>integer</type> DEFAULT 60)</function></literal>
19241+
</entry>
19242+
<entry><type>boolean</type></entry>
19243+
<entry>
19244+
Promotes a physical standby server. Returns <literal>true</literal>
19245+
if promotion is successful and <literal>false</literal> otherwise.
19246+
With <parameter>wait</parameter> set to <literal>true</literal>, the
19247+
default, the function waits until promotion is completed or
19248+
<parameter>wait_seconds</parameter> seconds have passed, otherwise the
19249+
function returns immediately after sending the promotion signal to the
19250+
postmaster. This function is restricted to superusers by default, but
19251+
other users can be granted EXECUTE to run the function.
19252+
</entry>
19253+
</row>
1923519254
<row>
1923619255
<entry>
1923719256
<literal><function>pg_wal_replay_pause()</function></literal>

‎doc/src/sgml/high-availability.sgml

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1471,14 +1471,17 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)'
14711471
</para>
14721472

14731473
<para>
1474-
To trigger failover of a log-shipping standby server,
1475-
run <command>pg_ctl promote</command> or create a trigger
1476-
file with the file name and path specified by the <varname>trigger_file</varname>
1477-
setting in <filename>recovery.conf</filename>. If you're planning to use
1478-
<command>pg_ctl promote</command> to fail over, <varname>trigger_file</varname> is
1479-
not required. If you're setting up the reporting servers that are
1480-
only used to offload read-only queries from the primary, not for high
1481-
availability purposes, you don't need to promote it.
1474+
To trigger failover of a log-shipping standby server, run
1475+
<command>pg_ctl promote</command>, call <function>pg_promote</function>,
1476+
or create a trigger file with the file name and path specified by the
1477+
<varname>trigger_file</varname> setting in
1478+
<filename>recovery.conf</filename>. If you're planning to use
1479+
<command>pg_ctl promote</command> or to call
1480+
<function>pg_promote</function> to fail over,
1481+
<varname>trigger_file</varname> is not required. If you're
1482+
setting up the reporting servers that are only used to offload read-only
1483+
queries from the primary, not for high availability purposes, you don't
1484+
need to promote it.
14821485
</para>
14831486
</sect1>
14841487

‎doc/src/sgml/monitoring.sgml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1268,7 +1268,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser
12681268
<entry>Waiting in an extension.</entry>
12691269
</row>
12701270
<row>
1271-
<entry morerows="33"><literal>IPC</literal></entry>
1271+
<entry morerows="34"><literal>IPC</literal></entry>
12721272
<entry><literal>BgWorkerShutdown</literal></entry>
12731273
<entry>Waiting for background worker to shut down.</entry>
12741274
</row>
@@ -1388,6 +1388,10 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser
13881388
<entry><literal>ProcArrayGroupUpdate</literal></entry>
13891389
<entry>Waiting for group leader to clear transaction id at transaction end.</entry>
13901390
</row>
1391+
<row>
1392+
<entry><literal>Promote</literal></entry>
1393+
<entry>Waiting for standby promotion.</entry>
1394+
</row>
13911395
<row>
13921396
<entry><literal>ReplicationOriginDrop</literal></entry>
13931397
<entry>Waiting for a replication origin to become inactive to be dropped.</entry>

‎doc/src/sgml/recovery-config.sgml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -439,7 +439,8 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows
439439
<para>
440440
Specifies a trigger file whose presence ends recovery in the
441441
standby. Even if this value is not set, you can still promote
442-
the standby using <command>pg_ctl promote</command>.
442+
the standby using <command>pg_ctl promote</command> or calling
443+
<function>pg_promote</function>.
443444
This setting has no effect if <varname>standby_mode</varname> is <literal>off</literal>.
444445
</para>
445446
</listitem>

‎src/backend/access/transam/xlog.c

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -78,12 +78,6 @@
7878

7979
externuint32bootstrap_data_checksum_version;
8080

81-
/* File path names (all relative to $PGDATA) */
82-
#defineRECOVERY_COMMAND_FILE"recovery.conf"
83-
#defineRECOVERY_COMMAND_DONE"recovery.done"
84-
#definePROMOTE_SIGNAL_FILE"promote"
85-
#defineFALLBACK_PROMOTE_SIGNAL_FILE "fallback_promote"
86-
8781

8882
/* User-settable parameters */
8983
intmax_wal_size_mb=1024;/* 1 GB */

‎src/backend/access/transam/xlogfuncs.c

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,16 @@
1616
*/
1717
#include"postgres.h"
1818

19+
#include<unistd.h>
20+
1921
#include"access/htup_details.h"
2022
#include"access/xlog.h"
2123
#include"access/xlog_internal.h"
2224
#include"access/xlogutils.h"
2325
#include"catalog/pg_type.h"
2426
#include"funcapi.h"
2527
#include"miscadmin.h"
28+
#include"pgstat.h"
2629
#include"replication/walreceiver.h"
2730
#include"storage/smgr.h"
2831
#include"utils/builtins.h"
@@ -697,3 +700,77 @@ pg_backup_start_time(PG_FUNCTION_ARGS)
697700

698701
PG_RETURN_DATUM(xtime);
699702
}
703+
704+
/*
705+
* Promotes a standby server.
706+
*
707+
* A result of "true" means that promotion has been completed if "wait" is
708+
* "true", or initiated if "wait" is false.
709+
*/
710+
Datum
711+
pg_promote(PG_FUNCTION_ARGS)
712+
{
713+
boolwait=PG_GETARG_BOOL(0);
714+
intwait_seconds=PG_GETARG_INT32(1);
715+
FILE*promote_file;
716+
inti;
717+
718+
if (!RecoveryInProgress())
719+
ereport(ERROR,
720+
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
721+
errmsg("recovery is not in progress"),
722+
errhint("Recovery control functions can only be executed during recovery.")));
723+
724+
if (wait_seconds <=0)
725+
ereport(ERROR,
726+
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
727+
errmsg("\"wait_seconds\" cannot be negative or equal zero")));
728+
729+
/* create the promote signal file */
730+
promote_file=AllocateFile(PROMOTE_SIGNAL_FILE,"w");
731+
if (!promote_file)
732+
ereport(ERROR,
733+
(errcode_for_file_access(),
734+
errmsg("could not create file \"%s\": %m",
735+
PROMOTE_SIGNAL_FILE)));
736+
737+
if (FreeFile(promote_file))
738+
ereport(ERROR,
739+
(errcode_for_file_access(),
740+
errmsg("could not write file \"%s\": %m",
741+
PROMOTE_SIGNAL_FILE)));
742+
743+
/* signal the postmaster */
744+
if (kill(PostmasterPid,SIGUSR1)!=0)
745+
{
746+
ereport(WARNING,
747+
(errmsg("failed to send signal to postmaster: %m")));
748+
(void)unlink(PROMOTE_SIGNAL_FILE);
749+
PG_RETURN_BOOL(false);
750+
}
751+
752+
/* return immediately if waiting was not requested */
753+
if (!wait)
754+
PG_RETURN_BOOL(true);
755+
756+
/* wait for the amount of time wanted until promotion */
757+
#defineWAITS_PER_SECOND 10
758+
for (i=0;i<WAITS_PER_SECOND*wait_seconds;i++)
759+
{
760+
ResetLatch(MyLatch);
761+
762+
if (!RecoveryInProgress())
763+
PG_RETURN_BOOL(true);
764+
765+
CHECK_FOR_INTERRUPTS();
766+
767+
WaitLatch(MyLatch,
768+
WL_LATCH_SET |WL_TIMEOUT |WL_POSTMASTER_DEATH,
769+
1000L /WAITS_PER_SECOND,
770+
WAIT_EVENT_PROMOTE);
771+
}
772+
773+
ereport(WARNING,
774+
(errmsg("server did not promote within %d seconds",wait_seconds)));
775+
PG_RETURN_BOOL(false);
776+
}

‎src/backend/catalog/system_views.sql

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1027,6 +1027,11 @@ CREATE OR REPLACE FUNCTION pg_stop_backup (
10271027
RETURNS SETOF record STRICT VOLATILE LANGUAGE internalas'pg_stop_backup_v2'
10281028
PARALLEL RESTRICTED;
10291029

1030+
CREATEOR REPLACE FUNCTION
1031+
pg_promote(waitboolean DEFAULT true, wait_secondsinteger DEFAULT60)
1032+
RETURNSboolean STRICT VOLATILE LANGUAGE INTERNALAS'pg_promote'
1033+
PARALLEL RESTRICTED;
1034+
10301035
-- legacy definition for compatibility with 9.3
10311036
CREATEOR REPLACE FUNCTION
10321037
json_populate_record(base anyelement, from_json json, use_json_as_textboolean DEFAULT false)
@@ -1138,6 +1143,7 @@ REVOKE EXECUTE ON FUNCTION pg_rotate_logfile() FROM public;
11381143
REVOKE EXECUTEON FUNCTION pg_reload_conf()FROM public;
11391144
REVOKE EXECUTEON FUNCTION pg_current_logfile()FROM public;
11401145
REVOKE EXECUTEON FUNCTION pg_current_logfile(text)FROM public;
1146+
REVOKE EXECUTEON FUNCTION pg_promote(boolean,integer)FROM public;
11411147

11421148
REVOKE EXECUTEON FUNCTION pg_stat_reset()FROM public;
11431149
REVOKE EXECUTEON FUNCTION pg_stat_reset_shared(text)FROM public;

‎src/backend/postmaster/pgstat.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3663,6 +3663,9 @@ pgstat_get_wait_ipc(WaitEventIPC w)
36633663
caseWAIT_EVENT_PROCARRAY_GROUP_UPDATE:
36643664
event_name="ProcArrayGroupUpdate";
36653665
break;
3666+
caseWAIT_EVENT_PROMOTE:
3667+
event_name="Promote";
3668+
break;
36663669
caseWAIT_EVENT_REPLICATION_ORIGIN_DROP:
36673670
event_name="ReplicationOriginDrop";
36683671
break;

‎src/include/access/xlog.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,10 +319,16 @@ extern void do_pg_abort_backup(void);
319319
externSessionBackupStateget_backup_status(void);
320320

321321
/* File path names (all relative to $PGDATA) */
322+
#defineRECOVERY_COMMAND_FILE"recovery.conf"
323+
#defineRECOVERY_COMMAND_DONE"recovery.done"
322324
#defineBACKUP_LABEL_FILE"backup_label"
323325
#defineBACKUP_LABEL_OLD"backup_label.old"
324326

325327
#defineTABLESPACE_MAP"tablespace_map"
326328
#defineTABLESPACE_MAP_OLD"tablespace_map.old"
327329

330+
/* files to signal promotion to primary */
331+
#definePROMOTE_SIGNAL_FILE"promote"
332+
#defineFALLBACK_PROMOTE_SIGNAL_FILE "fallback_promote"
333+
328334
#endif/* XLOG_H */

‎src/include/catalog/catversion.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,6 @@
5353
*/
5454

5555
/*yyyymmddN */
56-
#defineCATALOG_VERSION_NO201810111
56+
#defineCATALOG_VERSION_NO201810251
5757

5858
#endif

‎src/include/catalog/pg_proc.dat

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5824,6 +5824,10 @@
58245824
proname => 'pg_backup_start_time', provolatile => 's',
58255825
prorettype => 'timestamptz', proargtypes => '',
58265826
prosrc => 'pg_backup_start_time' },
5827+
{ oid => '3436', descr => 'promote standby server',
5828+
proname => 'pg_promote', provolatile => 'v',
5829+
prorettype => 'bool', proargtypes => 'bool int4', proargnames => '{wait,wait_seconds}',
5830+
prosrc => 'pg_promote' },
58275831
{ oid => '2848', descr => 'switch to new wal file',
58285832
proname => 'pg_switch_wal', provolatile => 'v', prorettype => 'pg_lsn',
58295833
proargtypes => '', prosrc => 'pg_switch_wal' },

‎src/include/pgstat.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -829,6 +829,7 @@ typedef enum
829829
WAIT_EVENT_PARALLEL_CREATE_INDEX_SCAN,
830830
WAIT_EVENT_PARALLEL_FINISH,
831831
WAIT_EVENT_PROCARRAY_GROUP_UPDATE,
832+
WAIT_EVENT_PROMOTE,
832833
WAIT_EVENT_REPLICATION_ORIGIN_DROP,
833834
WAIT_EVENT_REPLICATION_SLOT_DROP,
834835
WAIT_EVENT_SAFE_SNAPSHOT,

‎src/test/recovery/t/004_timeline_switch.pl

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
use File::Pathqw(rmtree);
77
use PostgresNode;
88
use TestLib;
9-
use Test::Moretests=>1;
9+
use Test::Moretests=>2;
1010

1111
$ENV{PGDATABASE} ='postgres';
1212

@@ -37,9 +37,14 @@
3737
$node_master->wait_for_catchup($node_standby_1,'replay',
3838
$node_master->lsn('write'));
3939

40-
# Stop and remove master, and promote standby 1, switching it to a new timeline
40+
# Stop and remove master
4141
$node_master->teardown_node;
42-
$node_standby_1->promote;
42+
43+
# promote standby 1 using "pg_promote", switching it to a new timeline
44+
my$psql_out ='';
45+
$node_standby_1->psql('postgres',"SELECT pg_promote(wait_seconds => 300)",
46+
stdout=> \$psql_out);
47+
is($psql_out,'t',"promotion of standby with pg_promote");
4348

4449
# Switch standby 2 to replay from standby 1
4550
rmtree($node_standby_2->data_dir .'/recovery.conf');

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp