postgres postgresql service start stop restart reload status
Várias ações diferentes são necessárias para a gestão de um sistema de
gerenciamento de banco de dados (SGBD) como o PostgreSQL. As mais conhecidas são
start
e stop
, mas mesmo elas têm uma profundidade maior que apenas seus
nomes indicam. Nesta parte veremos elas a fundo, assim como suas ações
companheiras.
Os comandos para gestão dos serviços do PostgreSQL dependem do sistema operacional e da origem dos pacotes instalados. Os comandos a seguir pressupõem o uso dos repositórios PGDG, como vistos antes.
Quando em dúvida sobre qual comando usar, dê preferência ao sistema de gestão de
serviços da sua distribuição (systemd, Upstart, openrc...). Em segunda posição,
use os comandos pg_ctl
quando estritamente necessário. Os scripts de
conveniência da distribuição também podem ser úteis para atividades raras como
initdb
ou upgrade
. Se possível, não envie sinais ao PostgreSQL, pois a
chance de erro humano na escolha do sinal, na descoberta dos processos do
PostgreSQL e no envio ao postgres
(ou postmaster
em CentOS antes do PG 16) é
significativa. Guarde essa última estratégia apenas para automatizar ferramentas
e scripts de administração e de alta disponibilidade que não puderem usar as
primeiras opções.
Uma vez que o diretório de dados tenha sido inicializado, é possível iniciar o serviço do PostgreSQL, que irá aceitar conexões por uma porta TCP (5432 por padrão), tratar as requisições SQL vindas dessa conexão, e persistir as alterações no diretório de dados.
Iniciando o serviço pelo systemd, como root:
[root@pg-1 ~]# systemctl start postgresql-16
Iniciando o serviço manualmente, como postgres:
[postgres@pg-1 ~]$ /usr/pgsql-16/bin/pg_ctl start -D /var/lib/pgsql/16/data
Iniciando o serviço pelo systemd, como root:
root@pg-1:~# systemctl start postgresql@16-main
Iniciando o serviço manualmente, como postgres:
postgres@pg-1:~$ /usr/lib/postgresql/16/bin/pg_ctl start -D /var/lib/postgres/16/main
Iniciando o serviço pelo script de conveniência, como postgres ou root:
postgres@pg-1:~$ pg_ctlcluster 16 main start
Existem diversas formas de observar o serviço do PostgreSQL que está no ar.
Algumas envolvem ferramentas básicas de sistema operacional, como ss
e
pgrep
, enquanto outras dependem dos comandos específicos do PostgreSQL.
Com ss
podemos listar portas TCP (-t
) que estão sendo ouvidas (listening,
-l
). Quando o PostgreSQL está ouvindo a sua porta padrão 5432, o número dela
será substituído pelo nome do serviço (assim como getent services 5432
), como
a seguir:
[postgres@pg-1 ~]$ ss -t -l State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 128 127.0.0.1:postgresql 0.0.0.0:* LISTEN 0 128 [::1]:postgresql [::]:*
Com pgrep
podemos consultar processos com o nome postgres
(Debian) ou
postmaster
(CentOS para versões anteriores ao PG 16), que muito provavelmente
são processos do PostgreSQL:
[postgres@pg-1 ~]$ pgrep -a postgres 16002 /usr/pgsql-16/bin/postmaster -D /var/lib/pgsql/16/data/ 16004 postgres: logger 16006 postgres: checkpointer 16007 postgres: background writer 16008 postgres: walwriter 16009 postgres: autovacuum launcher 16010 postgres: logical replication launcher
Mas as formas com resultado mais confiável são consultando o próprio serviço que foi iniciado recentemente. Isso não só traz o serviço, como também todos os processos abaixo dele, os diretórios de dados e de binários e contabilizações de recursos (CPU, memória, IO, rede/IP) consumidos:
[postgres@pg-1 ~]$ systemctl status postgresql-16 ● postgresql-16.service - PostgreSQL 16 database server Loaded: loaded (/usr/lib/systemd/system/postgresql-16.service; disabled; vendor preset: disabled) Drop-In: /etc/systemd/system/postgresql-16.service.d └─override.conf Active: active (running) since Mon 2024-09-24 17:13:30 UTC; 9s ago Docs: https://www.postgresql.org/docs/16/static/ Process: 15996 ExecStartPre=/usr/pgsql-16/bin/postgresql-16-check-db-dir ${PGDATA} (code=exited, status=0/SUCCESS) Main PID: 16002 (postmaster) IP: 12.8K in, 12.8K out IO: 9.2M read, 256.0K written Tasks: 8 (limit: 2881) Memory: 26.7M CPU: 46ms CGroup: /system.slice/postgresql-16.service ├─16002 /usr/pgsql-16/bin/postgres -D /var/lib/pgsql/64/data/ ├─16004 postgres: logger ├─16006 postgres: checkpointer ├─16007 postgres: background writer ├─16008 postgres: walwriter ├─16009 postgres: autovacuum launcher └─16010 postgres: logical replication launcher
Conferindo o serviço pelo systemd, como postgres ou root:
[postgres@pg-1 ~]$ systemctl status postgresql-16
Conferindo o serviço manualmente, como postgres:
[postgres@pg-1 ~]$ /usr/pgsql-16/bin/pg_ctl status -D /var/lib/pgsql/16/data
Conferindo o serviço pelo systemd, como postgres ou root:
postgres@pg-1:~$ systemctl status postgresql@16-main
Conferindo o serviço manualmente, como postgres:
postgres@pg-1:~$ /usr/lib/postgresql/16/bin/pg_ctl status -D /var/lib/postgres/16/main
Conferindo o serviço pelo script de conveniência, como postgres ou root:
postgres@pg-1:~$ pg_ctlcluster 16 main status
Ou:
postgres@pg-1:~$ pg_lsclusters
Quando uma configuração é alterada, ela não é aplicada imediatamente. Isso é intencional e desejado, assim o administrador do sistema tem a oportunidade de fazer diversas mudanças nos arquivos de configurações e aplicá-las todas ao mesmo tempo, de forma atômica.
Essa ação de recarregar o conteúdo dos arquivos de configuração é chamada de
reload
e não interrompe a disponibilidade do serviço, ou seja, não aborta
transações em andamento ou impede novas conexões (diferentemente do restart
,
a seguir).
Uma forma de acionar a ação é enviando o sinal SIGHUP
para o processo
principal do PostgreSQL. Por exemplo, usando o pid reportado anteriormente como
Main PID
pelo systemctl status postgresql-16
:
[postgres@pg-1 ~]$ kill -HUP 16002
Outra forma é através da chamada da função pg_reload_conf()
por uma conexão administrativa ao PostgreSQL:
(psql)# SELECT pg_reload_conf(); pg_reload_conf ---------------- t (1 row)
E as formas restantes são similares às que vimos antes:
Relendo os arquivos de configuração pelo systemd, como root:
[root@pg-1 ~]# systemctl reload postgresql-16
Relendo os arquivos de configuração manualmente, como postgres:
[postgres@pg-1 ~]$ /usr/pgsql-16/bin/pg_ctl reload -D /var/lib/pgsql/16/data
Relendo os arquivos de configuração pelo systemd, como root:
root@pg-1:~# systemctl reload postgresql@16-main
Relendo os arquivos de configuração manualmente, como postgres:
postgres@pg-1:~$ /usr/lib/postgresql/16/bin/pg_ctl reload -D /var/lib/postgres/16/main
Relendo os arquivos de configuração pelo script de conveniência, como postgres ou root:
postgres@pg-1:~$ pg_ctlcluster 16 main reload
Quando um sistema de gerenciamento de banco de dados está em execução, ele
gerencia conexões, que podem ter transações ou backups em andamento, assim como
gerencia buffers de escrita em disco (guardados na região de memória
compartilhada delimitada pelo parâmetro shared_buffers
). Então devemos
decidir, no momento em que o SGBD for parado, o que fazer com as transações em
andamento e com os buffers sujos. Essa decisão influencia diretamente os tempos
de parada e de início posterior.
O PostgreSQL tem três modos de parada, cada um com tratamentos diferentes sobre transações e buffers:
modo | transações | buffers | tempos | sinal |
---|---|---|---|---|
smart | aguarda o término normal das transações | escreve os buffers e deixa a instância em estado consistente | stop lento e start rápido | SIGTERM |
fast (padrão) | aborta transações em andamento | escreve os buffers e deixa a instância em estado consistente | stop médio e start rápido | SIGINT |
immediate | aborta transações em andamento | descarta buffers sujos e deixa a instância em estado inconsistente | stop rápido e start lento | SIGQUIT |
Como visto acima, cada modo pode ser acionado pelo uso de um sinal diferente
enviado ao processo postgres
(ou postmaster
em CentOS antes do PG 16),
similar ao método mostrado no reload
.
ATENÇÃO: Nunca tente finalizar o PostgreSQL com um SIGKILL. Esse sinal não permite que o PostgreSQL libere segmentos de memória compartilhada ou semáforos, além de possivelmente deixar os subprocessos do PostgreSQL no ar.
Mais informações sobre como parar o serviço na documentação oficial.
Parando pelo systemd com modo padrão (fast
), como root:
[root@pg-1 ~]# systemctl stop postgresql-16
Parando manualmente com os três modos, como postgres:
[postgres@pg-1 ~]$ /usr/pgsql-16/bin/pg_ctl stop -m smart -D /var/lib/pgsql/16/data [postgres@pg-1 ~]$ /usr/pgsql-16/bin/pg_ctl stop -m fast -D /var/lib/pgsql/16/data [postgres@pg-1 ~]$ /usr/pgsql-16/bin/pg_ctl stop -m immediate -D /var/lib/pgsql/16/data
Parando pelo systemd com modo padrão (fast
), como root:
root@pg-1:~# systemctl stop postgresql@16-main
Parando manualmente com os três modos, como postgres:
postgres@pg-1:~$ /usr/lib/postgresql/16/bin/pg_ctl stop -m smart -D /var/lib/postgres/16/main postgres@pg-1:~$ /usr/lib/postgresql/16/bin/pg_ctl stop -m fast -D /var/lib/postgres/16/main postgres@pg-1:~$ /usr/lib/postgresql/16/bin/pg_ctl stop -m immediate -D /var/lib/postgres/16/main
Parando pelo script de conveniência, pelos três modos, como postgres ou root:
postgres@pg-1:~$ pg_ctlcluster 16 main -m smart stop postgres@pg-1:~$ pg_ctlcluster 16 main -m fast stop postgres@pg-1:~$ pg_ctlcluster 16 main -m immediate stop
Em alguns casos é necessário reiniciar completamente o serviço, como para
aplicar atualizações de versões minoritárias ou
aplicar configurações de contexto postmaster
. Essa ação
faz com que o banco de dados fique indisponível por algum tempo, normalmente de
segundos a minutos, dependente do volume de dados, volume de transações, do
hardware e de alguns fatores externos. Portanto, é comum evitarmos ela nos casos
em que um reload
seria suficiente. Em outros casos, montamos um cluster de
alta disponibilidade para que o serviço seja chaveado para outro nó antes do
reinício.
O reinício pode ser alcançado simplesmente executando as ações de stop
seguida do start
. Contudo, também existe a ação restart
, que engloba as duas ações anteriores em uma, e que pode ser invocada como as anteriores:
Reiniciando pelo systemd, como root:
[root@pg-1 ~]# systemctl restart postgresql-16
Reiniciando manualmente, como postgres:
[postgres@pg-1 ~]$ /usr/pgsql-16/bin/pg_ctl restart -D /var/lib/pgsql/16/data
Reiniciando pelo systemd, como root:
root@pg-1:~# systemctl restart postgresql@16-main
Reiniciando manualmente, como postgres:
postgres@pg-1:~$ /usr/lib/postgresql/16/bin/pg_ctl restart -D /var/lib/postgres/16/main
Reiniciando pelo script de conveniência, como postgres ou root:
postgres@pg-1:~$ pg_ctlcluster 16 main restart
Cada sistema operacional tem o seu próprio mecanismo de gestão de serviços. Mas no systemd os comandos são:
Habilitando no systemd, como root:
[root@pg-1 ~]# systemctl enable postgresql-16
Habilitando no systemd, como root:
root@pg-1:~# systemctl enable postgresql@16-main
Existem várias formas de permitir que um usuário comum controle um serviço.
Serviços gerenciados pelo systemd
podem ser submetidos a um conjunto de regras
implementadas pelo Polkit (antigo
Policy Kit). Essas regras são escritas em arquivos em /etc/polkit-1/rules.d
e
avaliadas na ordem lexicográfica dos nomes dos arquivos. Então podemos criar um
arquivo /etc/polkit-1/rules.d/30-postgres.rules
com uma regra permitindo que
usuários pertencentes ao grupo postgres
possam usar todas as ações sobre os
serviços com nomes que comecem com postgres
, como o seguinte exemplo:
polkit.addRule(function(action, subject) { if (action.id == "org.freedesktop.systemd1.manage-units" && /^postgresql.*\.service$/.test(action.lookup("unit")) && subject.isInGroup("postgres")) { return polkit.Result.YES; } })
Dessa forma, o usuário postgres consegue controlar o serviço diretamente:
[postgres@pg-1 ~]$ systemctl start postgresql-16
Em um único arquivo é possível adicionar diversas regras, como outras permitindo as ações certas entre os serviços do postgres, barman, repmgr e seus usuários.
A forma mais popular é com sudo
, mas também é a mais
criticada por questões
de segurança, já que permite não só controle dos serviços, mas execução de
comandos gerais, sem a possiblilidade de bloquear comandos de forma confiável.
Use com cuidado.
Crie o arquivo /etc/sudoers.d/postgres
para permitir o gerenciamento do
serviço pelo postgres/repmgr com o conteúdo:
Defaults:postgres !requiretty postgres ALL = NOPASSWD: \ /usr/bin/systemctl reload postgresql-16, \ /usr/bin/systemctl restart postgresql-16, \ /usr/bin/systemctl start postgresql-16, \ /usr/bin/systemctl status postgresql-16, \ /usr/bin/systemctl stop postgresql-16
Dessa forma, o usuário postgres consegue controlar o serviço indiretamente
através do sudo
:
[postgres@pg-1 ~]$ sudo systemctl start postgresql-16