
Continuamos nos familiarizando com a ferramenta pg_probackup .
Na primeira parte, instalamos o pg_probackup, criamos e configuramos uma instância, fizemos dois backups - completo e incremental no modo DELTA, aprendemos a visualizar e alterar a configuração da instância. Conseguimos uma lista de backups, escrevemos um script (bkp_base.sh) que faz o backup do cluster e envia os resultados da última operação de backup para o sistema de monitoramento. Hoje enfrentaremos tarefas não menos interessantes.
Problema 2
Dado: Temos dois servidores, no primeiro temos nosso banco de dados (hostname srv_db1, usuário postgres), e no segundo vamos armazenar backups (hostname srv_bkp, usuário backup_user). Mas, além dos backups no mesmo servidor, manteremos cópias dos logs de pré-gravação para podermos restaurar em um momento arbitrário (recuperação pontual) nos últimos 3 dias.
Solução:
Para poder restaurar para o point in time selecionado (ponto de restauração), devemos ter um backup feito antes do ponto de restauração, assim como todos os arquivos WAL desde o momento em que o backup começou até o ponto de restauração.
Já temos backups, resta configurar o arquivamento WAL em srv_bkp.
Conecte-se a srv_db1 usando o usuário postgres e execute os seguintes comandos:
ssh-keygen -t rsa
ssh-copy-id backup_user@srv_bkp
Vamos modificar o arquivo ~ / .ssh / autorized_keys para srv_bkp:
command="pg_probackup-12 agent" ssh-rsa AAAA....
De volta a srv_db1, você precisa habilitar o modo de arquivo (archive_mode) e configurar o parâmetro archive_command. Ele contém um comando para fazer backup de um segmento WAL completo.
psql -c 'show archive_mode'
se retornou, mude para ligado
psql -c 'alter system set archive_mode = on'
Para que a alteração seja aplicada, você precisa reiniciar o PostgreSQL, mas por enquanto vamos adiar esta ação e configurar mais um parâmetro.
Se o fluxo de arquivos WAL for grande o suficiente, o servidor de backup pode ficar sem espaço em breve, então podemos inserir a opção --compress na linha archive_command, então os arquivos de log serão compactados antes de serem enviados para srv_bkp. E não precisaremos nos preocupar com o fato de que esses arquivos precisarão ser descompactados separadamente durante a recuperação - o pg_probackup pode funcionar com arquivos compactados.
alter system set archive_command = 'pg_probackup-12 archive-push -B /home/backup_user/backup_db --instance=db1 --wal-file-path=%p --wal-file-name=%f --remote-host=srv_bkp --remote-user=backup_user --compress';
Agora você pode reiniciar.
O que fizemos na primeira tarefa é chamado de backup offline. É assim chamado porque essa cópia contém todos os arquivos WAL necessários para restaurá-la. Na tarefa atual, estamos passando de cópias off-line para cópias de arquivo; tais cópias não contêm os logs necessários dentro delas, mas isso não importa, porque vamos salvar todos os arquivos WAL de que precisamos em um arquivo. Ao restaurar a partir de cópias de backup, os arquivos WAL serão copiados do arquivo.
Uma vez que, na situação em consideração, estamos mudando de backups offline (feitos em modo de fluxo) para arquivados (em modo de arquivo), pode surgir uma situação em que fizemos uma cópia quando o modo de arquivo ainda não estava ativado, após o que alguns dos segmentos WAL já apareceram removido. Isso significa que o primeiro backup após a mudança para o modo de arquivo não pode ser feito no modo PAGE, porque o segmento do WAL no arquivo entre o passado e a cópia atual pode não estar completo.
Vamos fazer isso usando o script criado na primeira tarefa:
./bkp_base.sh DELTA
Então vamos criar nosso primeiro backup no modo PAGE
./bkp_base.sh PAGE
Deixe-me lembrá-lo de que existem três modos incrementais disponíveis: PAGE, DELTA e PTRACK. Eles diferem uns dos outros nas formas de obter as informações necessárias sobre as páginas alteradas:
E agora vamos pensar que a cópia de backup, para poder se recuperar dela, precisa dos arquivos WAL criados durante a criação do backup. Essa. se fizermos um backup incremental por 30 minutos e durante esses 30 minutos 10 GB de WAL foram criados, apenas esses 10 GB serão necessários para que possamos nos recuperar de forma consistente. Todos os outros arquivos WAL são necessários apenas para fins de recuperação pontual.
A tarefa indicou que queremos ser capazes de nos recuperar a qualquer momento nos últimos 3 dias. Ou seja, todos os WAL desse período devem ser salvos, além disso, é necessário salvar todos os WAL que são necessários para restaurar dos backups anteriores, mas não precisamos armazenar todos os outros arquivos do WAL!
E, se pudermos usar o comando find para remover WALs desatualizados, adicionando mtime e -exec rm {} a ele, determinar qual segmento do WAL é necessário para restaurar consistentemente um backup específico não se torna uma tarefa fácil. É bom que os desenvolvedores pensem sobre isso e adicionem o parâmetro --wal-depth, com o qual você pode definir a profundidade de armazenamento WAL, calculada em backups.
Ele pode ser descrito esquematicamente da seguinte forma:

Observe que agora está em algum lugar no meio do sábado, o que significa que podemos excluir todos os arquivos WAL que não são necessários para restaurar backups com mais de três dias (cor marrom no gráfico). Os WALs que ainda são necessários são destacados em amarelo. Aqui, uma questão lógica pode surgir - mas, afinal, já é meio do sábado, o que significa que alguns dos logs da manhã criados na quarta-feira não são mais necessários e podem ser excluídos. Sim, é assim, e você pode configurar a exclusão do WAL em excesso pelo menos a cada minuto, mas em nosso artigo excluiremos os registros junto com a criação dos backups, portanto, apesar de não se enquadrarem mais na política de retenção, eles serão excluídos ao criar o próximo backup. ...
Altere as configurações da instância db1 - adicione o tempo de vida dos arquivos WAL
pg_probackup set-config --instance db1 --wal-depth=3
Vamos verificar se as configurações foram aplicadas:
pg_probackup show-config --instance=db1 | grep wal-depth
Adicione o sinalizador --delete-wal ao comando backup no script bkp_base.sh e também remova a chave --stream, porque estamos passando de backups offline para arquivados
pg_probackup backup --instance=db1 -j 2 --progress -b $1 --compress --delete-expired --delete-wal
No momento, configuramos a criação de backups de arquivo em um servidor separado. Além disso, os arquivos de log são adicionados aqui, o que nos dá a oportunidade de usar a recuperação não apenas para um backup específico, mas também para realizar a recuperação point-in-time - recuperação para um point-in-time específico.
Como agora temos um arquivo de arquivos WAL, podemos usar o modo PAGE para criar backups incrementais, deixe-me lembrar que neste modo, as alterações relativas ao backup anterior são calculadas não por arquivos de dados, mas pelo WAL acumulado desde o backup anterior.
PS Apenas para fins educacionais! Vamos criar uma tabela no banco de dados no servidor srv_db1:
psql -c 'create table timing(time_now timestamp with time zone)'
Então, vamos escrever a seguinte linha no crontab:
* * * * * psql -c 'insert into timing(select now())'
A cada minuto, informações sobre a hora atual serão gravadas no banco de dados, essas informações serão úteis para nós quando restaurarmos para um determinado momento.
Problema 3
Dado:
Temos dois servidores, o primeiro tem nosso banco de dados (hostname srv_db1, usuário postgres), o segundo armazena backups arquivados e arquivos WAL (hostname srv_bkp, usuário backup_user). Outro servidor srv_db2 aparece em nosso ambiente (usuário postgres), no qual teremos que implantar uma réplica de nosso cluster e reconfigurar o pg_probackup para que faça backups da réplica.
Decisão:
A Internet está cheia de descrições de como criar réplicas no PostgreSQL, você apenas tem que dirigir "criar uma réplica no PostgreSQL" no mecanismo de busca - escolha, eu não quero! Existem documentações, artigos e até tutoriais em vídeo. E todos esses métodos são bons, mas geralmente não levam em conta que já temos backups. Queremos criar uma réplica usando um backup, então removemos a carga de leitura do mestre. Ou seja, nosso servidor de produção não saberá que em algum lugar próximo a ele uma réplica está sendo criada (isso, é claro, com reservas - aqui o slot de replicação precisará ser criado e os direitos de acesso definidos, mas enquanto estamos criando uma réplica, não há carga adicional no mestre não será).
Configuramos o acesso por chaves entre os servidores srv_bkp e srv_db2, instalamos PostgreSQL e pg_probackup em srv_db2 (fizemos tudo exceto a instalação do PostgreSQL durante a primeira tarefa, mas se você tiver alguma dúvida sobre como instalar o DBMS, dê uma olhada aqui ).
Vá para srv_db2
ssh-keygen -t rsa
ssh-copy-id backup_user@srv_bkp
Vá para srv_bkp
ssh-copy-id postgres@srv_db2
Vamos ligar nosso paranóico interno e editar ~ / .ssh / autorized_keys - inserir
command="pg_probackup-12 agent"
antes de novas chaves.
Usar arquivos WAL é muito mais lento do que restaurar de um backup, então vamos criar outro backup incremental - conecte-se ao servidor srv_bkp usando backup_user e execute o comando:
pg_probackup backup --instance=db1 -j 2 --progress -b PAGE --compress
Por que não usamos o script que criamos? O fato é que anteriormente adicionamos a opção --delete-wal ao script, ou seja, após criar esse backup, não poderíamos restaurar para um ponto no tempo que era há três dias. Mas se sairmos desse backup, então o próximo backup feito executando nosso script ainda sairá do WAL apenas pelos últimos dois dias, ou seja, após restaurarmos a partir desse backup, faz sentido excluí-lo.
Fazemos a recuperação:
time pg_probackup restore --instance=db1 -D /var/lib/pgsql/12/data -j 2 --restore-as-replica --progress --remote-proto=ssh --remote-host=srv_db2 --archive-host=srv_bkp --archive-user=backup_user --log-level-console=log --log-level-file=verbose --log-filename=restore_rep.log
O diretório / var / lib / pgsql / 12 / data deve estar vazio, além disso, no servidor srv_db1, você deve fazer alterações em pg_hba.conf - permitir o acesso do servidor srv_db2 usando o protocolo de replicação.
host replication all srv_db2 md5
Nós relemos a configuração:
psql -c 'select pg_reload_conf()'
Verificando erros de digitação:
psql -c 'select * from pg_hba_file_rules'
crie um arquivo ~ / .pgpass em srv_db2, no qual especificamos as permissões de conexão em srv_db1, mas desta vez com a base de replicação e iniciamos o PostgreSQL.
srv_db1:5432:replication:backup:Strong_PWD
E vamos mudar seus direitos para 600:
chmod 600 ~/.pgpass
Iniciamos o cluster em srv_db2.
Vamos verificar se tudo funciona bem. Usaremos as seguintes possibilidades para isso.
Examinamos o arquivo de registro de réplica nele, em algum lugar próximo ao final, a seguinte linha deve aparecer:
Database system is ready to accept read only connections
psql -c 'select pg_is_in_recovery()'
deve retornar t
Agora vamos criar uma placa t1 no assistente:
srv_db1: psql -c 'create table t1()'
Vamos verificar se apareceu na réplica.
srv_db2: psql -c '\d'
A placa está no lugar e a replicação está funcionando. Retiramos a placa do mestre.
srv_db1: psql -c 'drop table t1'
Claro, em um banco de dados real, agora seria necessário criar um slot de replicação no mestre e configurar a réplica para que ela vá para o mestre por meio desse slot, mas o tópico de nosso artigo não são réplicas, mas backups, então continuaremos.
Então, a réplica funciona para nós, se necessário, podemos mudar para a réplica, mas vamos nos fazer uma pergunta - podemos fazer melhor?
Claro que você pode. Por que precisamos fazer backups do mestre quando podemos remover a carga de leitura do mestre e transferi-la para uma réplica?
CUIDADO! O MONITORAMENTO DE FALTA DO REPLIC DEVE SER MONITORADO, CASO CONTRÁRIO PODE SABER QUE VOCÊ NÃO SABERÁ QUE O REPLICA ESTÁ LAGADO E CONTINUARÁ A BACKUP DO REPLICA LAG.
Vamos fazer isso!
Fazemos alterações nas configurações do cluster nos servidores srv_db1 e srv_db2:
alter system set archive_timeout=180;
select pg_reload_conf();
Vá para srv_bkp e altere o valor do parâmetro do host remoto:
pg_probackup set-config --instance db1 --remote-host=srv_db2
Fazemos alterações em .pgpass no servidor srv_bkp - adicionamos as strings de conexão ao servidor srv_db2:
srv_db2:5432:replication:backup:Strong_PWD
srv_db2:5432:backupdb:backup:Strong_PWD
E vamos tentar fazer outro backup.
srv_bkp: ./bkp_base.sh PAGE
Vemos que o backup funcionou.
O problema está resolvido!
A próxima parte será dedicada à restauração de backups: consideraremos várias opções de recuperação, aprenderemos como restaurar para um backup específico, para um ponto no tempo, familiarizar-nos com restaurações parciais e incrementais.