postgresql postgres repmgr
Desenvolvido pela 2ndQuadrant, o repmgr é um gerenciador de cluster de alta disponibilidade com boa integração com o Barman e diversas funcionalidades.
Ele usa a própria instância para registrar o estado e saúde dos nós, então depende da criação de uma extensão em algum banco de dados da instância. Também acompanha o andamento dos nós por uma conexão de replicação. Por isso, a versão do repmgr depende da versão do servidor.
A configuração é baseada em um arquivo de texto estilo ini, como por exemplo
/etc/repmgr/16/repmgr.conf
:
# identificador numérico único do nó dentro do cluster node_id=1 # nome do nó no cluster node_name='pg-1.local' # string de conexão que outros nós podem usar para consultar o estado deste nó conninfo='host=pg-1.local user=repmgr dbname=repmgr' # diretório de dados data_directory='/var/lib/pgsql/16/data' # diretório dos binários da mesma versão do PostgreSQL pg_bindir='/usr/pgsql-16/bin/' # identificador do cluster no barman barman_server='app' # hostname do servidor do barman barman_host='barman@pg-a.local' # comandos de controle do nó service_start_command = 'sudo systemctl start postgresql-16' service_stop_command = 'sudo systemctl stop postgresql-16' service_restart_command = 'sudo systemctl restart postgresql-16' service_reload_command = 'sudo systemctl reload postgresql-16'
As configurações mais importantes são:
-
node_id
: Indentificador numérico que deve ser único para cada nó. -
node_name
: Nome do nó. -
conninfo
: String de conexão que outros nós podem usar para consultar ou alterar o estado do cluster e deste nó. -
data_directory
: Diretório de dados da instância neste nó. -
pg_bindir
: Diretório dos binários da mesma versão majoritária do PosgreSQL. -
barman_server
: Identificador da instância dentro do Barman. -
barman_host
: Usuário e hostname para acesso ao Barman por ssh. -
service_*_command
: Comandos que podem ser usados para controlar o serviço do PostgreSQL neste nó.
Com o primário no ar, assim como usuário, banco de dados e arquivo de configuração corretos, o registro do primário é feito como:
[postgres@pg-1 ~]$ repmgr primary register INFO: connecting to primary database... NOTICE: attempting to install extension "repmgr" NOTICE: "repmgr" extension successfully installed NOTICE: primary node record (ID: 1) registered
Depois do primário registrado no cluster de alta disponibilidade, e com o Barman também devidamente configurado, é possível clonar uma réplica:
[postgres@pg-2 ~]$ repmgr -h pg-1.local -U repmgr standby clone NOTICE: destination directory "/var/lib/pgsql/16/data" provided INFO: connecting to Barman server to verify backup for "app" INFO: checking and correcting permissions on existing directory "/var/lib/pgsql/16/data" INFO: creating directory "/var/lib/pgsql/16/data/repmgr"... INFO: connecting to Barman server to fetch server parameters INFO: connecting to source node DETAIL: connection string is: host=pg-1.local user=repmgr DETAIL: current installation size is 31 MB WARNING: data checksums are not enabled and "wal_log_hints" is "off" DETAIL: pg_rewind requires "wal_log_hints" to be enabled NOTICE: retrieving backup from Barman... receiving file list ... 1298 files to consider PG_VERSION [...] NOTICE: standby clone (from Barman) complete NOTICE: you can now start your PostgreSQL server HINT: for example: sudo systemctl start postgresql-16 HINT: after starting the server, you need to register this standby with "repmgr standby register"
Então o serviço é iniciado (sudo systemctl start postgresql-16
) e a réplica é
registrada:
[postgres@pg-2 ~]$ repmgr -h pg-1.local -U repmgr standby register --upstream-node-id 1 INFO: connecting to local node "pg-2.local" (ID: 2) WARNING: database connection parameters not required when the standby to be registered is running DETAIL: repmgr uses the "conninfo" parameter in "repmgr.conf" to connect to the standby INFO: connecting to primary database INFO: standby registration complete NOTICE: standby node "pg-2.local" (ID: 2) successfully registered
Uma testemunha não participa da replicação dos dados, mas participa do heartbeat que é feito através do protocolo de replicação do PostgreSQL. Isso significa que precisa existir um PostgreSQL mínimo em execução na máquina da testemunha, aceitando conexões das outras máquinas do cluster de alta disponibilidade.
Primeiro, crie uma instância na máquina testemunha e configure-a como as outras, ou seja, aceitando conexões externas das outras máquinas.
Crie um arquivo de configuração do repmgr simplificado:
# identificador numérico único do nó dentro do cluster node_id=3 # nome do nó no cluster node_name='pg-a.local' # conexão conninfo='host=pg-a.local user=repmgr dbname=repmgr' # diretório de dados data_directory='/var/lib/pgsql/16/data'
E registre o nó no cluster:
[postgres@pg-a ~]$ repmgr -h pg-1.local -U repmgr witness register INFO: connecting to witness node "pg-a.local" (ID: 3) INFO: connecting to primary node NOTICE: attempting to install extension "repmgr" NOTICE: "repmgr" extension successfully installed INFO: witness registration complete NOTICE: witness node "pg-a.local" (ID: 3) successfully registered
É possível consultar o estado do cluster com:
[postgres@pg-a ~]$ repmgr cluster show ID | Name | Role | Status | Upstream | Location | Priority | Timeline | Connection string ----+------------+---------+-----------+------------+----------+----------+----------+------------------------------------------- 1 | pg-1.local | primary | * running | | default | 100 | 1 | host=pg-1.local user=repmgr dbname=repmgr 2 | pg-2.local | standby | running | pg-1.local | default | 100 | 1 | host=pg-2.local user=repmgr dbname=repmgr 3 | pg-a.local | witness | * running | pg-1.local | default | 0 | n/a | host=pg-a.local user=repmgr dbname=repmgr
É possível fazer o chaveamento manual entre o primário e a réplica:
[postgres@pg-2 ~]$ repmgr standby switchover NOTICE: executing switchover on node "pg-2.local" (ID: 2) WARNING: 1 sibling nodes found, but option "--siblings-follow" not specified DETAIL: these nodes will remain attached to the current primary: pg-a.local (node ID: 3, witness server) NOTICE: local node "pg-2.local" (ID: 2) will be promoted to primary; current primary "pg-1.local" (ID: 1) will be demoted to standby NOTICE: stopping current primary node "pg-1.local" (ID: 1) NOTICE: issuing CHECKPOINT on node "pg-1.local" (ID: 1) DETAIL: executing server command "sudo systemctl stop postgresql-16" INFO: checking for primary shutdown; 1 of 60 attempts ("shutdown_check_timeout") NOTICE: current primary has been cleanly shut down at location 0/5000028 NOTICE: promoting standby to primary DETAIL: promoting server "pg-2.local" (ID: 2) using pg_promote() NOTICE: waiting up to 60 seconds (parameter "promote_check_timeout") for promotion to complete NOTICE: STANDBY PROMOTE successful DETAIL: server "pg-2.local" (ID: 2) was successfully promoted to primary INFO: local node 1 can attach to rejoin target node 2 DETAIL: local node's recovery point: 0/5000028; rejoin target node's fork point: 0/50000A0 NOTICE: setting node 1's upstream to node 2 WARNING: unable to ping "host=pg-1.local user=repmgr dbname=repmgr" DETAIL: PQping() returned "PQPING_NO_RESPONSE" NOTICE: starting server using "sudo systemctl start postgresql-16" NOTICE: NODE REJOIN successful DETAIL: node 1 is now attached to node 2 INFO: waiting for node "pg-1.local" (ID: 1) to connect to new primary; 1 of max 60 attempts (parameter "node_rejoin_timeout") DETAIL: checking for record in node "pg-2.local"'s "pg_stat_replication" table where "application_name" is "pg-1.local" NOTICE: node "pg-2.local" (ID: 2) promoted to primary, node "pg-1.local" (ID: 1) demoted to standby NOTICE: switchover was successful DETAIL: node "pg-2.local" is now primary and node "pg-1.local" is attached as standby NOTICE: STANDBY SWITCHOVER has completed successfully
E observar a inversão dos papéis:
[postgres@pg-2 ~]$ repmgr cluster show ID | Name | Role | Status | Upstream | Location | Priority | Timeline | Connection string ----+------------+---------+-----------+------------+----------+----------+----------+------------------------------------------- 1 | pg-1.local | standby | running | pg-2.local | default | 100 | 1 | host=pg-1.local user=repmgr dbname=repmgr 2 | pg-2.local | primary | * running | | default | 100 | 2 | host=pg-2.local user=repmgr dbname=repmgr 3 | pg-a.local | witness | * running | pg-1.local | default | 0 | n/a | host=pg-a.local user=repmgr dbname=repmgr
Configure as máquinas pg-1, pg-2 e pg-a como um cluster de alta disponibilidade usando as configurações e comandos acima.