Replicação por Streaming do PostgreSQL

PostgreSQLBeginner
Pratique Agora

Introdução

Neste laboratório, você aprenderá a configurar a replicação de streaming do PostgreSQL. Este poderoso recurso permite manter uma cópia ao vivo e somente leitura do seu banco de dados primário em um servidor secundário, conhecido como réplica. A réplica recebe e aplica continuamente as alterações de dados do primário, tornando-a útil para alta disponibilidade, balanceamento de carga de consultas de leitura e backups.

Você passará por todo o processo, começando pela configuração do servidor primário para permitir a replicação. Em seguida, criará um servidor réplica fazendo um backup base. Finalmente, iniciará a réplica, testará o fluxo de dados entre os dois servidores e verá como a réplica permanece sincronizada com o primário.

Configurar o Servidor Primário para Replicação

Nesta primeira etapa, você configurará o servidor PostgreSQL primário para prepará-lo para replicação. Isso envolve modificar seus arquivos de configuração para permitir conexões de rede, habilitar o nível necessário de Write-Ahead Log (WAL) e criar um usuário especial para replicação.

1. Modificar o Arquivo de Configuração do PostgreSQL

Para se preparar para a replicação, você precisa modificar o arquivo de configuração principal, postgresql.conf. Editar este arquivo grande manualmente com um editor de texto como nano pode ser desafiador e propenso a erros devido ao grande número de opções. Um método mais eficiente e confiável é usar ferramentas de linha de comando para visualizar e atualizar as configurações específicas que você precisa alterar. Isso evita ter que percorrer centenas de linhas e previne erros acidentais.

Primeiro, vamos verificar os valores atuais das configurações que precisamos modificar: listen_addresses, wal_level e max_wal_senders.

CONF_FILE="/etc/postgresql/14/main/postgresql.conf"
echo "--- Current Settings ---"
sudo grep -E "^#?\s*(listen_addresses|wal_level|max_wal_senders)" $CONF_FILE

Você provavelmente verá essas linhas comentadas com um #.

Agora, vamos atualizar essas configurações automaticamente. Os comandos a seguir farão backup do arquivo de configuração e, em seguida, atualizarão cada parâmetro necessário.

CONF_FILE="/etc/postgresql/14/main/postgresql.conf"
## Create a backup before making changes
sudo cp $CONF_FILE ${CONF_FILE}.bak.$(date +%s)

## Set listen_addresses to allow connections from any IP address
sudo sed -i -E "s/^[#\s]*listen_addresses\s*=.*/listen_addresses = '*'/" "$CONF_FILE"

## Set wal_level to 'replica' to enable replication logs
sudo sed -i -E "s/^[#\s]*wal_level\s*=.*/wal_level = replica/" "$CONF_FILE"

## Set the maximum number of concurrent replication connections
sudo sed -i -E "s/^[#\s]*max_wal_senders\s*=.*/max_wal_senders = 10/" "$CONF_FILE"

Finalmente, vamos verificar se as alterações foram aplicadas corretamente. O comando abaixo exibirá os novos valores, filtrando quaisquer linhas comentadas.

echo "--- Verified Settings ---"
sudo grep -E "^(listen_addresses|wal_level|max_wal_senders)" $CONF_FILE

A saída deve mostrar a configuração atualizada e ativa:

listen_addresses = '*'
wal_level = replica
max_wal_senders = 10

Com essas configurações confirmadas, o servidor está devidamente configurado para as próximas etapas.

2. Criar um Usuário Dedicado para Replicação

É uma boa prática usar um usuário dedicado para replicação em vez de um superusuário. Vamos criar uma role chamada replicator.

Conecte-se ao PostgreSQL usando o cliente de linha de comando psql:

sudo -u postgres psql

Agora, execute o seguinte comando SQL para criar o usuário com privilégios de replicação e uma senha:

CREATE ROLE replicator WITH REPLICATION LOGIN PASSWORD 'replicapass';

Você deverá ver a saída CREATE ROLE. Agora, saia do cliente psql:

\q

3. Permitir a Conexão de Replicação

Em seguida, você precisará configurar o servidor para permitir que o usuário replicator se conecte do servidor réplica. Você fará isso editando o arquivo pg_hba.conf.

Abra o arquivo com nano:

sudo nano /etc/postgresql/14/main/pg_hba.conf

Adicione a seguinte linha ao final do arquivo. Esta regra especifica que o usuário replicator tem permissão para se conectar ao pseudo-banco de dados replication de qualquer endereço IP (0.0.0.0/0). Para este laboratório, usamos 127.0.0.1/32 já que ambos os servidores estão na mesma máquina.

host    replication     replicator      127.0.0.1/32            md5

Pressione Ctrl+X, Y e Enter para salvar e sair.

4. Reiniciar o Servidor Primário

Para aplicar todas essas alterações de configuração, você deve reiniciar o serviço PostgreSQL.

sudo service postgresql restart

O servidor primário está agora pronto para aceitar conexões de replicação.

Criar a Réplica a partir de um Backup Base

Com o servidor primário configurado, o próximo passo é criar a réplica. A maneira padrão de fazer isso é tirar um "backup base" do servidor primário. Isso cria uma cópia idêntica do diretório de dados do primário, que servirá como ponto de partida para a réplica.

1. Criar um Diretório de Dados para a Réplica

Primeiro, crie um novo diretório onde os dados da réplica serão armazenados. É uma boa prática criar isso em um local do sistema, não no diretório pessoal de um usuário, para evitar problemas de permissão. Vamos criá-lo como o usuário postgres no diretório padrão do PostgreSQL.

sudo -u postgres mkdir -p /var/lib/postgresql/14/replica

2. Tirar o Backup Base

Agora, use a utilidade pg_basebackup para copiar os dados do servidor primário. Este comando se conectará ao primário como o usuário replicator e transmitirá os dados para o novo diretório da réplica. Como você criou o diretório como o usuário postgres, não há problemas de permissão para resolver.

Execute o seguinte comando. Você será solicitado a digitar a senha do usuário replicator, que é replicapass.

sudo -u postgres pg_basebackup -h localhost -p 5432 -U replicator -D /var/lib/postgresql/14/replica -P -v -R

Vamos detalhar este comando:

  • sudo -u postgres: Executa o comando como o usuário do sistema postgres, que possui as permissões necessárias.
  • pg_basebackup: A utilidade para tirar backups base.
  • -h localhost -p 5432: Especifica o host e a porta do servidor primário.
  • -U replicator: O nome de usuário para se conectar.
  • -D /var/lib/postgresql/14/replica: O diretório de destino para o backup.
  • -P: Mostra um relatório de progresso.
  • -v: Habilita o modo verboso.
  • -R: Esta é uma opção muito útil. Ela cria um arquivo standby.signal e anexa as configurações de conexão ao arquivo postgresql.auto.conf no diretório de destino, o que configura automaticamente o novo diretório de dados como uma réplica.

3. Copiar Arquivos de Configuração

O backup base copia os arquivos de dados principais, mas em muitos sistemas baseados em Debian (como este ambiente Ubuntu), os arquivos de configuração (pg_hba.conf e pg_ident.conf) são armazenados separadamente em /etc/postgresql/ e não são incluídos no backup. Você deve copiá-los manualmente para o diretório de dados da réplica. Após a cópia, você também deve garantir que eles pertençam ao usuário postgres para que o processo do servidor possa lê-los.

sudo cp /etc/postgresql/14/main/pg_hba.conf /var/lib/postgresql/14/replica/
sudo cp /etc/postgresql/14/main/pg_ident.conf /var/lib/postgresql/14/replica/
sudo chown postgres:postgres /var/lib/postgresql/14/replica/pg_hba.conf
sudo chown postgres:postgres /var/lib/postgresql/14/replica/pg_ident.conf

Com os arquivos de dados e a configuração no lugar, o diretório da réplica está pronto para as etapas finais de configuração.

Configurar e Iniciar o Servidor Réplica

O backup base preparou o diretório de dados da réplica. No entanto, como você está executando os servidores primário e réplica na mesma máquina, ambos não podem usar a mesma porta de rede (o padrão é 5432). Nesta etapa, você configurará a réplica para usar uma porta diferente e, em seguida, a iniciará.

1. Configurar a Porta da Réplica

Edite o arquivo postgresql.conf dentro do diretório de dados da réplica para alterar sua porta de escuta. Observe que você precisa de sudo porque este arquivo agora pertence ao usuário postgres.

sudo nano /var/lib/postgresql/14/replica/postgresql.conf

Adicione a seguinte linha ao final do arquivo para definir a porta como 5433:

port = 5433

Pressione Ctrl+X, Y e Enter para salvar e sair.

2. Definir Permissões do Diretório de Dados

Por segurança, o PostgreSQL exige que seu diretório de dados não seja acessível por outros usuários. Você deve definir suas permissões como 700, o que concede permissões de leitura, escrita e execução apenas ao proprietário (postgres).

sudo chmod 0700 /var/lib/postgresql/14/replica

3. Iniciar o Servidor Réplica

Agora você pode iniciar o servidor réplica. Você usará pg_ctl, uma utilidade padrão do PostgreSQL para controlar um servidor de banco de dados.

Execute o seguinte comando para iniciar a réplica. Você deve usar o caminho completo para pg_ctl porque o comando sudo pode não saber onde encontrá-lo de outra forma. Também especificaremos um arquivo de log em /tmp para facilitar a verificação do status do servidor.

sudo -u postgres /usr/lib/postgresql/14/bin/pg_ctl -D /var/lib/postgresql/14/replica -l /tmp/replica.log start
  • pg_ctl: A utilidade de controle do servidor.
  • -D /var/lib/postgresql/14/replica: Especifica o diretório de dados para esta instância do servidor.
  • -l /tmp/replica.log: Especifica o arquivo de log.
  • start: A ação a ser executada.

Você deverá ver a mensagem:

waiting for server to start.... done
server started

4. Verificar o Arquivo de Log da Réplica

Para confirmar que a réplica iniciou corretamente e se conectou ao primário, visualize seu arquivo de log com sudo, pois ele pertence ao usuário postgres:

sudo cat /tmp/replica.log

Procure por linhas indicando que o sistema de banco de dados está pronto para aceitar conexões somente leitura e que iniciou o streaming do primário. Você deverá ver algo semelhante a isto:

...
LOG:  database system is ready to accept read-only connections
LOG:  started streaming WAL from primary at 0/4000000 on timeline 1
...

Isso confirma que seu servidor réplica está ativo, em execução e conectado com sucesso ao primário.

Testar a Replicação

Agora que ambos os servidores estão em execução, é hora de testar se a replicação está funcionando como esperado. Você criará uma tabela no servidor primário e verificará se ela aparece na réplica. Você também confirmará que a réplica é somente leitura.

1. Verificar o Status da Replicação no Primário

Primeiro, conecte-se ao servidor primário (na porta 5432) e verifique a visualização pg_stat_replication. Esta visualização fornece informações de monitoramento sobre réplicas conectadas.

sudo -u postgres psql -p 5432

Execute esta consulta:

SELECT client_addr, state, sync_state FROM pg_stat_replication;

A saída deve mostrar sua réplica conectada, com seu estado como streaming e sync_state como async ou sync.

 client_addr |   state   | sync_state
-------------+-----------+------------
 127.0.0.1   | streaming | async
(1 row)

2. Criar Dados no Primário

Enquanto ainda conectado ao primário, crie uma nova tabela e insira alguns dados:

CREATE TABLE replication_test (id INT, message TEXT);
INSERT INTO replication_test VALUES (1, 'Hello from primary!');

Agora, consulte a tabela para confirmar que os dados estão lá:

SELECT * FROM replication_test;

Você deverá ver a linha que acabou de inserir. Saia do shell psql do primário:

\q

3. Verificar Dados na Réplica

Abra um novo terminal ou use o existente para se conectar ao servidor réplica na porta 5433. Você precisará fornecer a senha para o usuário postgres, que é labex.

psql -h localhost -p 5433 -U postgres -d postgres

Agora, consulte a tabela replication_test na réplica:

SELECT * FROM replication_test;

Você deverá ver exatamente os mesmos dados que criou no primário. Isso confirma que a replicação por streaming está funcionando!

 id |      message
----+---------------------
  1 | Hello from primary!
(1 row)

4. Testar a Natureza Somente Leitura da Réplica

Tente inserir dados na tabela na réplica:

INSERT INTO replication_test VALUES (2, 'Hello from replica?');

O comando falhará com um erro porque um servidor réplica está em modo somente leitura por padrão.

ERROR:  cannot execute INSERT in a read-only transaction

Este é um comportamento esperado e uma característica chave de uma réplica de streaming. Saia do shell psql da réplica:

\q

Limpar o Ambiente

Nesta etapa final, você desligará os servidores e removerá os arquivos e diretórios criados durante o laboratório para retornar o ambiente ao seu estado inicial.

1. Parar o Servidor Réplica

Primeiro, pare o servidor réplica usando pg_ctl. Lembre-se de usar o caminho completo para o executável.

sudo -u postgres /usr/lib/postgresql/14/bin/pg_ctl -D /var/lib/postgresql/14/replica stop

Você verá uma mensagem de confirmação de que o servidor foi parado.

waiting for server to shut down.... done
server stopped

2. Parar o Servidor Primário

Em seguida, pare o servidor primário usando o comando service.

sudo service postgresql stop

3. Remover Dados e Logs da Réplica

Agora que os servidores estão parados, você pode remover com segurança o diretório de dados da réplica e o arquivo de log que você criou. Observe que sudo é necessário, pois esses arquivos pertencem ao usuário postgres.

sudo rm -rf /var/lib/postgresql/14/replica /tmp/replica.log

Isso completa o processo de limpeza. Você configurou, testou e desmantelou com sucesso um ambiente de replicação por streaming do PostgreSQL.

Resumo

Neste laboratório, você configurou com sucesso a replicação por streaming do PostgreSQL do zero. Você aprendeu como preparar um servidor primário modificando postgresql.conf e pg_hba.conf e criando um usuário de replicação dedicado. Em seguida, você usou pg_basebackup para criar uma réplica e a configurou para rodar em uma porta separada.

Ao testar a configuração, você verificou que os dados gravados no primário são automaticamente replicados para o servidor secundário em tempo quase real. Você também confirmou que um servidor réplica é somente leitura, o que é um aspecto fundamental de seu design. Essas habilidades são essenciais para gerenciar implantações robustas e escaláveis do PostgreSQL.