PG_AUTOCTL PERFORM PROMOTION(1)

πŸ’– pg_autoctl perform promotion β€” the manual, but make it cute πŸ’–

okay bestie, gather round 🫢 this one's from pg_auto_failover, and it's genuinely one of my faves because it lets you hand-pick who becomes the new primary. no cap.


✨ NAME ✨

pg_autoctl perform promotion β€” bestie, it's literally the promotion command. πŸ’…

pg_autoctl perform promotion β€” Perform a failover that promotes a target node. that's it, that's the whole job. she's a queen πŸ‘‘


🌸 SYNOPSIS 🌸

so the monitor (pg_auto_promotion) kicks off a Postgres failover orchestration, and it aims it at whichever node you name:

   usage: pg_autoctl perform promotion  [ --pgdata --formation --group ]

   --pgdata      path to data directory
   --formation   formation to target, defaults to 'default'
   --name        node name to target, defaults to current node
   --wait        how many seconds to wait, default to 60

πŸ¦‹ DESCRIPTION πŸ¦‹

the pg_auto_promotion monitor can orchestrate a manual promotion, which some people also call a switchover (same vibe, different name, iykyk). and here's the slay part: when it does that, split-brain is prevented because the Finite State Machine uses intermediary states. she does not let two primaries happen. not on her watch πŸ’€

the pg_autoctl perform promotion command just sits there and waits until the promotion is known complete on the monitor, or until the hard-coded 60s timeout has passed. whichever comes first, periodt.

also important: the promotion orchestration happens in the background, done by the monitor. so even if pg_autoctl perform promotion gives up on the timeout, the promotion keeps going at the monitor. she's not stopping for you, bestie, she's got main character energy ✨


πŸŽ€ OPTIONS πŸŽ€

  • --pgdata β€” where the Postgres node that's being managed locally lives. defaults to the environment variable PGDATA. and heads up: use --monitor to connect to a monitor from literally anywhere, instead of the monitor URI that a local Postgres node managed with pg_autoctl is using. πŸ’–
  • --formation β€” which formation to target for the operation. defaults to default.
  • --name β€” name of the node that should be elected as the new primary node. your pick, your power πŸ‘‘
  • --wait β€” how many seconds to wait for notifications about the promotion. the command stops when the promotion is finished (meaning a node is primary), or when the timeout has elapsed, whichever happens first. and the value 0 (zero) disables the timeout and lets the command wait forever. forever ever. no cap 😭

🌈 ENVIRONMENT 🌈

  • PGDATA β€” Postgres directory location. can be used instead of the --pgdata option. same thing, less typing πŸ’…
  • PG_AUTOCTL_MONITOR β€” Postgres URI to connect to the monitor node, can be used instead of the --monitor option.
  • PG_CONFIG β€” can be set to the absolute path to the pg_config Postgres tool. this is mostly used in the context of building extensions, though it can be a useful way to select a Postgres version when several are installed on the same system.
  • PATH β€” used the usual way, mostly. some entries that are searched in the PATH by the pg_autoctl command are expected to be found only once, to avoid mistakes with Postgres major versions. one copy, please 🫢
  • PGHOST, PGPORT, PGDATABASE, PGUSER, PGCONNECT_TIMEOUT, ... β€” see the Postgres docs about Environment Variables for details.
  • TMPDIR β€” the pgcopydb command creates all its work files and directories in ${TMPDIR}/pgcopydb, and defaults to /tmp/pgcopydb.
  • XDG_CONFIG_HOME β€” the pg_autoctl command stores its configuration files in the standard place XDG_CONFIG_HOME. see the XDG Base Directory Specification.
  • XDG_DATA_HOME β€” the pg_autoctl command stores its internal states files in the standard place XDG_DATA_HOME, which defaults to ~/.local/share. see the XDG Base Directory Specification.

⭐ EXAMPLES ⭐

okay so let's look at where we start. three nodes, node2 is the primary, everyone else is a secondary:

$ pg_autoctl show state
 Name |  Node |      Host:Port |       LSN |   Connection |       Current State |      Assigned State
------+-------+----------------+-----------+--------------+---------------------+--------------------
node1 |     1 | localhost:5501 | 0/4000F88 |    read-only |           secondary |           secondary
node2 |     2 | localhost:5502 | 0/4000F88 |   read-write |             primary |             primary
node3 |     3 | localhost:5503 | 0/4000F88 |    read-only |           secondary |           secondary

now we ask for a promotion targeting node1, and bestie, watch the states dance. this is the FSM doing her little choreography and honestly it's iconic:

$ pg_autoctl perform promotion --name node1
13:08:13 15297 INFO  Listening monitor notifications about state changes in formation "default" and group 0
13:08:13 15297 INFO  Following table displays times when notifications are received
    Time |  Name |  Node |      Host:Port |       Current State |      Assigned State
---------+-------+-------+----------------+---------------------+--------------------
13:08:13 | node1 |   0/1 | localhost:5501 |           secondary |           secondary
13:08:13 | node2 |   0/2 | localhost:5502 |             primary |            draining
13:08:13 | node2 |   0/2 | localhost:5502 |            draining |            draining
13:08:13 | node1 |   0/1 | localhost:5501 |           secondary |          report_lsn
13:08:13 | node3 |   0/3 | localhost:5503 |           secondary |          report_lsn
13:08:19 | node3 |   0/3 | localhost:5503 |          report_lsn |          report_lsn
13:08:19 | node1 |   0/1 | localhost:5501 |          report_lsn |          report_lsn
13:08:19 | node1 |   0/1 | localhost:5501 |          report_lsn |   prepare_promotion
13:08:19 | node1 |   0/1 | localhost:5501 |   prepare_promotion |   prepare_promotion
13:08:19 | node1 |   0/1 | localhost:5501 |   prepare_promotion |    stop_replication
13:08:19 | node2 |   0/2 | localhost:5502 |            draining |      demote_timeout
13:08:19 | node3 |   0/3 | localhost:5503 |          report_lsn |      join_secondary
13:08:19 | node2 |   0/2 | localhost:5502 |      demote_timeout |      demote_timeout
13:08:19 | node3 |   0/3 | localhost:5503 |      join_secondary |      join_secondary
13:08:20 | node1 |   0/1 | localhost:5501 |    stop_replication |    stop_replication
13:08:20 | node1 |   0/1 | localhost:5501 |    stop_replication |        wait_primary
13:08:20 | node2 |   0/2 | localhost:5502 |      demote_timeout |             demoted
13:08:20 | node1 |   0/1 | localhost:5501 |        wait_primary |        wait_primary
13:08:20 | node3 |   0/3 | localhost:5503 |      join_secondary |           secondary
13:08:20 | node2 |   0/2 | localhost:5502 |             demoted |             demoted
13:08:20 | node2 |   0/2 | localhost:5502 |             demoted |          catchingup
13:08:21 | node3 |   0/3 | localhost:5503 |           secondary |           secondary
13:08:21 | node1 |   0/1 | localhost:5501 |        wait_primary |             primary
13:08:21 | node2 |   0/2 | localhost:5502 |          catchingup |          catchingup
13:08:21 | node1 |   0/1 | localhost:5501 |             primary |             primary

and look at that glow-up πŸ₯Ή node1 is the primary now, node2 got demoted and caught up as a secondary, node3 is chillin' as a secondary. ate. no crumbs.

$ pg_autoctl show state
 Name |  Node |      Host:Port |       LSN |   Connection |       Current State |      Assigned State
------+-------+----------------+-----------+--------------+---------------------+--------------------
node1 |     1 | localhost:5501 | 0/40012F0 |   read-write |             primary |             primary
node2 |     2 | localhost:5502 | 0/40012F0 |    read-only |           secondary |           secondary
node3 |     3 | localhost:5503 | 0/40012F0 |    read-only |           secondary |           secondary

πŸ‘‘ AUTHOR πŸ‘‘

Microsoft


Copyright (c) Microsoft Corporation. All rights reserved.


and that's the whole page, bestie! this is version 2.2, dated Apr 07, 2025, from the pg_auto_failover project πŸ’– go promote somebody, you got this 🫢✨
πŸ“¦ where this page comes from