PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Mecanismos de replicação física no PostgreSQL


O Postgres vem com recursos de replicação física e lógica. Continue lendo para saber mais sobre vários aspectos da replicação física.

Replicação física


Os métodos de replicação física são usados ​​para manter uma cópia completa de todos os dados de um único cluster (no Postgres, um cluster é um conjunto de bancos de dados gerenciados por um único processo principal do servidor Postgres chamado postmaster ), normalmente em outra máquina. A máquina de origem é chamada de primária no jargão do Postgres, e o destino é chamado de standby .

Esperas quentes, mornas e “frias”


Um servidor em espera que é mantido o mais atualizado possível com o servidor primário em tempo real e permite que os clientes executem transações somente leitura é chamado dehot standby, ou mais popularmente uma réplica de leitura . Hot standbys foram adicionados ao Postgres na versão 9, antes do qual havia apenas warm esperas. Um warmstandby é semelhante a um hot standby, exceto que não permite que os clientes se conectem a ele.

(Além disso:Hot standbys não podem executar consultas que criam tabelas temporárias. Esta é uma limitação do Postgres.)

Uma espera “fria” (não é um termo oficial) geralmente é um servidor em espera que não inicia até um failover. Como o cold standby não está funcionando, é possível que, na inicialização, ele precise primeiro aplicar as alterações pendentes antes de começar a aceitar conexões de clientes.

Arquivos WAL


No curso normal das operações, um servidor PostgreSQL gera uma série ordenada de registros WAL (write ahead log). Estes são basicamente um log de alterações, semelhante ao AOF do Redis ou ao binlog do MySQL. Em sua essência, a replicação física é o transporte desses registros para outra máquina e fazer com que o outro postmaster que está executando lá aceite e aplique esses registros em seu banco de dados local.

Os registros WAL são divididos em arquivos de tamanho igual (geralmente 16 MB) chamadossegmentos WAL ou apenas arquivos WAL . Esses arquivos são criados em um diretório chamado pg_wal no diretório de dados do cluster (pg_wal foi chamado pg_xlog nas versões do Postgres anteriores a 10). Arquivos WAL antigos são descartados quando não são mais necessários (e também com base em alguns parâmetros de configuração).

Modo de recuperação


O postmaster pode ser inicializado em um modo chamado modo de recuperação , colocando um arquivo de configuração válido chamado recovery.conf no diretório de dados do cluster. No modo de recuperação, o Postgres só importará e aplicará arquivos WAL gerados por um servidor primário e, por si só, não gerará nenhum arquivo WAL. Servidores quentes e de espera ativa são executados no modo de recuperação.

Quando inicializado no modo de recuperação, o Postgres tentará primeiro importar todos os arquivos WAL disponíveis em um arquivo (mais sobre isso abaixo). Quando o arquivo não tem mais arquivos WAL para oferecer, ele tenta importar qualquer arquivo que esteja no pg_wal do init diretório. Quando isso também estiver concluído, se uma conexão primária estiver configurada estandby_modeset para on no recovery.conf, o Postgres se conectará ao primário e extrairá e aplicará novos registros WAL à medida que forem criados no primário.

Envio de Log


Imagine ter um gatilho que será invocado no servidor primário sempre que um novo arquivo WAL for criado. Este gatilho pode então copiar o novo arquivo WAL para outra máquina usando, digamos, rsync , e coloque-o no pg_wal diretório de um postmaster em execução no modo de recuperação. Você pode fazer uma espera como esta?

A resposta é sim e, de fato, essa era a prática padrão antes que a replicação de streaming fosse adicionada no Postgres v9. Essa prática é chamada de transporte de logs .

O gatilho é um script de shell, que pode ser configurado usando archive_command. O nome e o caminho do arquivo WAL podem ser passados ​​para o script.

Arquivamento WAL


Em vez de fazer rsync sobre o arquivo WAL, digamos que o copiamos para um bucket do S3 ou para um diretório montado em NFS que também pode ser acessado da máquina em espera. Este local compartilhado agora conterá todos os arquivos WAL gerados pelo primário. torna-se um arquivo , e o processo de armazenamento de arquivos WAL no arquivo é chamado de arquivamento contínuo ou simplesmente arquivamento WAL .

O inverso desta operação – buscar arquivos WAL do arquivo para um Postgres em modo de recuperação – pode ser configurado usandorestore_command. Semelhante ao archive_command , este também é o caminho para um script de shell. O postmaster em execução no modo de recuperação sabe qual arquivo WAL deseja. O nome do arquivo pode ser passado para o script.

Como exemplo, aqui estão os comandos de arquivamento e restauração para armazenar e buscar arquivos WAL de e para um bucket do S3:
archive_command = 's3cmd put %p s3://BUCKET/path/%f' # in postgresql.conf
restore_command = 's3cmd get s3://BUCKET/path/%f %p' # in recovery.conf

Ao iniciar no modo de recuperação, se restore_command estiver configurado, o Postgres tentará primeiro buscar os arquivos WAL do arquivo.

pg_standby


No modo de recuperação, o Postgres não sabe e não pode saber antecipadamente quantos arquivos WAL foram gerados até agora. Se restore_command estiver configurado, o Postgres irá invocá-lo repetidamente com nomes de arquivo WAL progressivos (os nomes estão em uma sequência previsível) até que o comando retorne um erro.

Por exemplo, o comando de restauração foi capaz de atender às solicitações de arquivos WAL000000010000000000000001 através de 00000001000000000000001A mas falha para00000001000000000000001B uma vez que não foi encontrado no local do arquivo. Na ausência de arquivos WAL de outras fontes, o Postgres assumirá que o arquivo WAL 00000001000000000000001B ainda não foi gerado pelo primário e terminará a recuperação após a aplicação de 00000001000000000000001A .

Considere o que aconteceria se o comando de restauração esperasse pelo arquivo00000001000000000000001B para estar disponível, em vez de sair com erro, pois não foi encontrado. O Postgres continuará aguardando o comando de restauração e, portanto, continuará no modo de recuperação.

Esta é uma configuração válida e uma maneira válida de configurar uma espera a quente.

O Postgres vem com um comando chamado pg_standby, que pode ser usado para configurar um warm standby desta forma, desde que o arquivo seja um diretório.pg_standby aguardará que um arquivo fique disponível, se não puder ser encontrado.

Os comandos de arquivamento e restauração usando pg_standby ficarão assim:
archive_command = 'cp %p /some/path/%f'         # in postgresql.conf
restore_command = 'pg_standby /some/path %f %p' # in recovery.conf

Replicação de streaming


Depois de processar arquivos WAL arquivados, bem como arquivos no pg_wal diretório, o Postgres pode se conectar a um servidor primário pela rede e buscar e aplicar repetidamente novos arquivos WAL à medida que são criados. Esse recurso, adicionado no Postgres 9, é chamado de replicação de streaming .

O servidor primário ao qual se conectar pode ser especificado no arquivo recovery.conf:
# recovery.conf
standby_mode = on
primary_conninfo = 'host=10.0.1.10 user=repl password=p@ssw0rd'

Hot Standby


Por padrão, quando em modo de recuperação, o Postgres não aceitará conexões de clientes, rejeitando-as com mensagens de erro “sistema de banco de dados está em modo de recuperação”. Adicionando a linha hot_standby = on em recovery.conf, você pode fazer conexões de cliente Postgresaccept e permitir que elas executem transações somente leitura:
# recovery.conf
hot_standby = on

Geralmente não há razão para desligar o hot_standby.

A documentação do PostgreSQL contém mais informações sobre como configurar e executar um standby no modo “hot standby”.

Slots de replicação


Os slots de replicação foram introduzidos no Postgres 9.4. Eles são um mecanismo para acompanhar com precisão e durabilidade o quanto um standby está atrasado em relação ao primário. Isso permite que o primário garanta que os arquivos WAL ainda necessários para que o standby seja atualizado não sejam excluídos.

Antes dos slots de replicação, não era possível para o primário determinar isso, e você acabaria em situações em que um modo de espera era deixado de lado porque um arquivo WAL necessário havia sido excluído pelo primário. Claro, os arquivos WAL podem corrigir esse problema. Sem um arquivo WAL, no entanto, a única opção era reconstruir o modo de espera a partir de um novo backup.

Você pode ler mais sobre slots de replicação aqui.

Etapas para configurar um Hot Standby


Vamos dar uma olhada nas etapas necessárias para configurar um hot standby para um primário existente.

1. Criar usuário de replicação

Primeiro, precisamos de um usuário para o modo de espera para se conectar como:
$ psql -p 6000
psql (11.2 (Debian 11.2-1.pgdg90+1))
Type "help" for help.

postgres=# CREATE USER repluser REPLICATION PASSWORD 'p@ssw0rd';
CREATE USER

E as alterações correspondentes em pg_hba.conf :
# TYPE  DATABASE        USER          ADDRESS        METHOD
host    replication     repluser      standby-ip/32  md5
# (replace standby-ip)

É claro que você pode usar qualquer mecanismo de autenticação padrão do PostgreSQL. O usuário precisa ter privilégios de replicação e login e não requer acesso a nenhum banco de dados específico.

Certifique-se de recarregar o servidor primário para que as alterações no pg_hba.conf tenham efeito.

2. Faça um backup

A espera precisa começar a partir de um backup do primário. Você pode e deve fazer isso usando pg_basebackup com um novo slot de replicação:
pg_basebackup -h primary-ip -p 6000 -U repluser -C -S slot_standby1 -R -D standby

Isso se conecta ao primário em primary-ip:6000 com o usuário que acabamos de criar e faz um backup dele no diretório standby . Um novo slot de replicaçãoslot_standby1 é criado.

3. Adicione recovery.conf em espera

Usaremos esse slot como nosso slot de replicação em espera, para que haja continuidade do backup.

Perguntamos ao pg_basebackup para criar um recovery.conf para nós acima (opção "-R"). Vamos dar uma olhada nisso:
$ cat standby/recovery.conf
standby_mode = 'on'
primary_conninfo = 'user=repluser password=''p@ssw0rd'' host=primary-ip port=6000 sslmode=prefer sslcompression=0 krbsrvname=postgres target_session_attrs=any'
primary_slot_name = 'slot_standby1'

Isso é realmente muito bom, e não precisamos modificá-lo ainda mais. Vamos simplesmente trazer o modo de espera agora:
o$ pg_ctl -D standby -l log_standby -o --port=6001 start
waiting for server to start.... done
server started
postgres@stg1:/tmp/demo$ cat log_standby
2019-06-19 09:17:50.032 UTC [21733] LOG:  listening on IPv4 address "127.0.0.1", port 6001
2019-06-19 09:17:50.034 UTC [21733] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.6001"
2019-06-19 09:17:50.067 UTC [21734] LOG:  database system was interrupted; last known up at 2019-06-19 09:12:05 UTC
2019-06-19 09:17:50.111 UTC [21734] LOG:  entering standby mode
2019-06-19 09:17:50.119 UTC [21734] LOG:  redo starts at 0/2000028
2019-06-19 09:17:50.120 UTC [21734] LOG:  consistent recovery state reached at 0/20000F8
2019-06-19 09:17:50.120 UTC [21733] LOG:  database system is ready to accept read only connections
2019-06-19 09:17:50.138 UTC [21739] LOG:  started streaming WAL from primary at 0/3000000 on timeline 1

E é isso! O arquivo de log indica que a replicação de streaming está ativa e em execução. Agora você deve ser capaz de se conectar ao modo de espera na porta 6001, executar consultas somente leitura e ver as alterações serem replicadas do primário mais ou menos em tempo real.

Próximas etapas


Os documentos do PostgreSQL são um ótimo lugar para começar a se aprofundar em todos os recursos relacionados à replicação do Postgres. Você desejará examinar tópicos como replicação atrasada, replicação em cascata, esperas síncronas e muito mais.

Embora o Postgres venha com um conjunto impressionante de recursos, ainda existem casos de uso que não são suportados. Esta página wiki do Postgres tem uma lista de ferramentas de terceiros que fornecem funcionalidades adicionais relacionadas à replicação.