Backups incrementais do postgresql com pgbackrest - um curso para um jovem lutador do desenvolvedor

Isenção de responsabilidade

Eu sou um desenvolvedor. Eu escrevo código e interajo com o banco de dados apenas como usuário. De forma alguma pretendo ser um administrador de sistema, muito menos um dba. Mas…

Acontece que precisei organizar um backup do banco de dados postgresql. Sem nuvens - basta usar SSH e garantir que tudo funcione sem pedir dinheiro. O que fazemos nesses casos? Isso mesmo, colocamos o pgdump no cron, fazemos backup de tudo no arquivo todos os dias e, se estivermos completamente perdidos, enviamos esse arquivo para algum lugar distante.

Desta vez a dificuldade era que, de acordo com os planos, o banco de dados deveria crescer cerca de +- 100 MB por dia. Claro, depois de algumas semanas, o desejo de fazer backup de tudo com o pgdump desaparecerá. É aqui que os backups incrementais vêm em socorro.

Interessante? Bem-vindo ao gato.

O backup incremental é um tipo de backup quando nem todos os arquivos de origem são copiados, mas apenas os novos e os alterados desde a criação da cópia anterior.

Como qualquer desenvolvedor que não estava absolutamente disposto (naquela época) a entender as complexidades do postgres, eu queria encontrar o botão verde. Bem, você sabe, como no AWS, DigitalOcean: você pressionou um botão - obteve replicação, pressionou o segundo - configurou backups, o terceiro - reverteu tudo algumas horas. Não encontrei um botão ou uma ferramenta GUI bonita. Se você conhece algum (gratuito ou barato), escreva nos comentários.

Depois de pesquisar no Google, encontrei duas ferramentas pgbarman и encosto. Simplesmente não tive sucesso com o primeiro (documentação muito escassa, tentei descobrir tudo de acordo com manuais antigos), mas com o segundo a documentação acabou por estar à altura, mas não sem falhas. Para simplificar o trabalho de quem se depara com tarefa semelhante, este artigo foi escrito.

Após a leitura deste artigo, você aprenderá como fazer backups incrementais, salvá-los em um servidor remoto (repositório com backups) e restaurá-los em caso de perda de dados ou outros problemas no servidor principal.

Treinamento

Para reproduzir o manual você precisará de dois VPS. O primeiro será o armazenamento (o repositório onde serão armazenados os backups), e o segundo, na verdade, o próprio servidor com postgres (no meu caso, versão 11 do postgres).

Supõe-se que no servidor com postgres você tenha root, usuário sudo, usuário postgres e o próprio postgres esteja instalado (o usuário postgres é criado automaticamente ao instalar o postgresql), e no servidor de repositório haja usuário root e sudo (no manual o nome de usuário pgbackrest será usado).

Para que você tenha menos problemas na hora de reproduzir as instruções, escrevo em itálico onde, com qual usuário e com quais direitos executei o comando enquanto escreve e verifica o artigo.

Instalando o pgbackrest

Repositório (usuário pgbackrest):

1. Baixe o arquivo do pgbackrest e transfira seu conteúdo para a pasta /build:

sudo mkdir /build
sudo wget -q -O - 
       https://github.com/pgbackrest/pgbackrest/archive/release/2.18.tar.gz | 
       sudo tar zx -C /build

2. Instale as dependências necessárias para montagem:

sudo apt-get update
sudo apt-get install build-essential libssl-dev libxml2-dev libperl-dev zlib1g-dev 
       libpq-dev

3. Montagem do encosto:

cd /build/pgbackrest-release-2.18/src && sudo ./configure
sudo make -s -C /build/pgbackrest-release-2.18/src

4. Copie o arquivo executável para o diretório /usr/bin:

sudo cp /build/pgbackrest-release-2.18/src/pgbackrest /usr/bin
sudo chmod 755 /usr/bin/pgbackrest

5. Pgbackrest requer perl. Instalar:

sudo apt-get install perl

6. Crie diretórios para logs, conceda-lhes certos direitos:

sudo mkdir -p -m 770 /var/log/pgbackrest
sudo chown pgbackrest:pgbackrest /var/log/pgbackrest
sudo mkdir -p /etc/pgbackrest
sudo mkdir -p /etc/pgbackrest/conf.d
sudo touch /etc/pgbackrest/pgbackrest.conf
sudo chmod 640 /etc/pgbackrest/pgbackrest.conf
sudo chown pgbackrest:pgbackrest /etc/pgbackrest/pgbackrest.conf

7. Verifique:

pgbackrest version

Servidor Postgres (usuário sudo ou root):

O processo de instalação do pgbackrest em um servidor com postgres é semelhante ao processo de instalação no repositório (sim, o pgbackrest deve estar instalado em ambos os servidores), mas no 6º parágrafo o segundo e último comandos:

sudo chown pgbackrest:pgbackrest /var/log/pgbackrest
sudo chown pgbackrest:pgbackrest /etc/pgbackrest/pgbackrest.conf

substituir com:

sudo chown postgres:postgres /var/log/pgbackrest
sudo chown postgres:postgres /etc/pgbackrest/pgbackrest.conf

Configurando a interação entre servidores via SSH sem senha

Para que o pgbackrest funcione corretamente, é necessário configurar a interação entre o servidor postgres e o repositório através do arquivo chave.

Repositório (usuário pgbackrest):

Crie um par de chaves:

mkdir -m 750 /home/pgbackrest/.ssh
ssh-keygen -f /home/pgbackrest/.ssh/id_rsa 
       -t rsa -b 4096 -N ""

Atenção! Executamos os comandos acima sem sudo.

Servidor Postgres (usuário sudo ou root):

Crie um par de chaves:

sudo -u postgres mkdir -m 750 -p /var/lib/postgresql/.ssh
sudo -u postgres ssh-keygen -f /var/lib/postgresql/.ssh/id_rsa 
       -t rsa -b 4096 -N ""

Repositório (usuário sudo):

Copie a chave pública do servidor postgres para o servidor do repositório:

(echo -n 'no-agent-forwarding,no-X11-forwarding,no-port-forwarding,' && 
       echo -n 'command="/usr/bin/pgbackrest ${SSH_ORIGINAL_COMMAND#* }" ' && 
       sudo ssh root@<postgres_server_ip> cat /var/lib/postgresql/.ssh/id_rsa.pub) | 
       sudo -u pgbackrest tee -a /home/pgbackrest/.ssh/authorized_keys

Nesta etapa será solicitada a senha do usuário root. Você precisa inserir a senha do usuário root do servidor postgres!

Servidor Postgres (usuário sudo):

Copie a chave pública do repositório para o servidor com postgres:

(echo -n 'no-agent-forwarding,no-X11-forwarding,no-port-forwarding,' && 
       echo -n 'command="/usr/bin/pgbackrest ${SSH_ORIGINAL_COMMAND#* }" ' && 
       sudo ssh root@<repository_server_ip> cat /home/pgbackrest/.ssh/id_rsa.pub) | 
       sudo -u postgres tee -a /var/lib/postgresql/.ssh/authorized_keys

Nesta etapa será solicitada a senha do usuário root. Você precisa inserir exatamente a senha do usuário root do repositório!

Verificamos:

Repositório (usuário root, para a pureza do experimento):

sudo -u pgbackrest ssh postgres@<postgres_server_ip>

Servidor Postgres (usuário root, para a pureza do experimento):

sudo -u postgres ssh pgbackrest@<repository_server_ip>

Garantimos que teremos acesso sem problemas.

Configurando um servidor postgres

Servidor Postgres (usuário sudo ou root):

1. Vamos permitir ataques no servidor postgres de IPs externos. Para fazer isso, edite o arquivo postgresql.conf (localizado na pasta /etc/postgresql/11/main), adicionando a linha a ele:

listen_addresses = '*'

Se tal linha já existir, remova o comentário ou defina o valor do parâmetro como '*'.

No arquivo pg_hba.conf (também localizado na pasta /etc/postgresql/11/main) adicione as seguintes linhas:

hostssl  all  all  0.0.0.0/0  md5
host  all  all  0.0.0.0/0  md5

em que:

hostssl/host - подключаемся через SSL (или нет)
all - разрешаем подключение ко всем базам
all - имя пользователя, которому разрешаем подключение (всем)
0.0.0.0/0 - маска сети с которой можно подключаться
md5 - способ шифрования пароля

2. Vamos fazer as configurações necessárias em postgresql.conf (está na pasta /etc/postgresql/11/main) para que o pgbackrest funcione:

archive_command = 'pgbackrest --stanza=main archive-push %p' # Где main - название кластера. При установке postgres автоматически создает кластер main.
archive_mode = on
max_wal_senders = 3
wal_level = replica

3. Vamos fazer as configurações necessárias no arquivo de configuração do pgbackrest (/etc/pgbackrest/pgbackrest.conf):

[main]
pg1-path=/var/lib/postgresql/11/main

[global]
log-level-file=detail
repo1-host=<repository_server_ip>

4. Recarregue o postgresql:

sudo service postgresql restart

Configurando um servidor de repositório

Repositório (usuário pgbackrest):

Vamos fazer as configurações necessárias no arquivo de configuração encosto
(/etc/pgbackrest/pgbackrest.conf):

[main]
pg1-host=<postgres_server_ip>
pg1-path=/var/lib/postgresql/11/main

[global]
repo1-path=/var/lib/pgbackrest
repo1-retention-full=2 # Параметр, указывающий сколько хранить полных бэкапов. Т.е. если у вас есть два полных бэкапа и вы создаете третий, то самый старый бэкап будет удален. Можно произносить как "хранить не более двух бэкапов" - по аналогии с ротациями логов. Спасибо @Aytuar за исправление ошибки.
start-fast=y # Начинает резервное копирование немедленно, прочитать про этот параметр можно тут https://postgrespro.ru/docs/postgrespro/9.5/continuous-archiving

Criando um repositório

Repositório (usuário pgbackrest):

Crie um novo armazenamento para o cluster principal:

sudo mkdir -m 770 /var/lib/pgbackrest
sudo chown -R pgbackrest /var/lib/pgbackrest/
sudo -u pgbackrest pgbackrest --stanza=main stanza-create

Проверка

Servidor Postgres (usuário sudo ou root):

Verificamos no servidor postgres:

sudo -u postgres pgbackrest --stanza=main --log-level-console=info check

Repositório (usuário pgbackrest):

Verificamos no servidor do repositório:

sudo -u pgbackrest pgbackrest --stanza=main --log-level-console=info check

Certificamo-nos de que na saída vemos a linha “verificar comando final: concluído com sucesso”.

Cansado? Vamos passar para a parte mais interessante.

Fazendo um backup

Repositório (usuário pgbackrest):

1. Faça um backup:

sudo -u pgbackrest pgbackrest --stanza=main backup

2. Certifique-se de que um backup foi criado:

ls /var/lib/pgbackrest/backup/main/

O Pgbackrest criará o primeiro backup completo. Se desejar, você pode executar o comando backup novamente e certificar-se de que o sistema cria um backup incremental.

Se você quiser fazer um backup completo novamente, especifique um sinalizador adicional:

sudo -u pgbackrest pgbackrest --stanza=main --type=full backup

Se você quiser uma saída detalhada do console, especifique também:

sudo -u pgbackrest pgbackrest --stanza=main --type=full --log-level-console=info backup

Restaurando um backup

Servidor Postgres (usuário sudo ou root):

1. Pare o cluster em execução:

sudo pg_ctlcluster 11 main stop

2. Restaurando do backup:

sudo -u postgres pgbackrest --stanza=main --log-level-console=info --delta --recovery-option=recovery_target=immediate restore

Para restaurar o banco de dados para o estado do último backup COMPLETO, use o comando sem especificar recovery_target:

sudo -u postgres pgbackrest --stanza=main --log-level-console=info --delta restore

Importante! Após a recuperação, pode acontecer que o banco de dados fique preso no modo de recuperação (haverá erros como ERRO: não é possível executar DROP DATABASE em uma transação somente leitura). Para ser sincero, ainda não entendi a que isso está relacionado. A solução é a seguinte (você precisará esperar um pouco após a execução do comando):

sudo -u postgres psql -c "select pg_wal_replay_resume()"

Na verdade, é possível restaurar um backup específico pelo seu nome. Aqui estou eu apenas Fornecerei um link para a descrição desse recurso na documentação. Os desenvolvedores aconselham usar esta opção com cautela e explicam o porquê. Posso acrescentar por mim mesmo que o usei. Se realmente precisar, certifique-se de que após a recuperação o banco de dados saia do modo de recuperação (selecione pg_is_in_recovery() deve mostrar “f”) e, por precaução, faça um backup completo após a recuperação.

3. Inicie o cluster:

sudo pg_ctlcluster 11 main start

Após restaurar o backup, precisamos realizar um segundo backup:

Repositório (usuário pgbackrest):

sudo pgbackrest --stanza=main backup

Isso é tudo. Concluindo, gostaria de lembrar que não estou de forma alguma tentando fingir ser um dba sênior e usarei as nuvens na menor oportunidade. Atualmente, eu mesmo estou começando a estudar diversos temas como backup, replicação, monitoramento, etc. e escrevo pequenos relatórios sobre os resultados para dar uma pequena contribuição à comunidade e deixo pequenas dicas para mim.

Nos artigos a seguir tentarei falar sobre recursos adicionais - recuperação de dados para um cluster limpo, criptografia de backups e publicação no S3, backups via rsync.

Fonte: habr.com

Adicionar um comentário