Implementando Point-in-time Recovery (PITR) em PostgreSQL 9.6 - Blog 4Linux
6 de junho de 2018 Arlindo Neto 4452 Views
como implementar um simples sistema de replicação através dos xlog.
como recuperar o seu banco PostgreSQL em qualquer ponto no tempo.
Sobre backups PITR
Quando o seu banco de dados perde informações, devido a ocorrência de um problema ou remoção por engano, é importante recuperar estes dados exatamente como eram antes do desastre. Se utilizado o Dump (cópias full), tradicional método de backup, haverá um período sem dados copiados, entre um backup e outro.
O PITR, ou Point-in-time recovery, preenche essa lacuna. Permite fazer com sucesso, cópias automáticas de cada transição realizada, ou seja, dos arquivos transacionais WAL. Possibilita também recuperar dados gravados em qualquer ponto do tempo, segundos, minutos, horas, dias, até mesmo, semanas atrás. O tempo retroativo do backup dependerá do período em que as transições copiadas serão mantidas, período de retenção do PITR.
Arquivos transacionais WAL?
Cada transação realizada no PostgreSQL, antes de ser inserida na memória RAM, primeiramente é escrita em logs de transação chamados: "arquivos WAL". Posteriormente, as transações serão gravadas em disco. Estes arquivos WAL, por padrão, ocupam 16MB de espaço e, para fins de replicação, serão neste exemplo, transferidos para um diretório acessível pelo backup binário.
Prepare o ambiente de teste
1. Criaremos um cluster PostgreSQL através do utilitário initdb em um diretório vazio. Execute os comandos:
[postgres@localhost ~]$ mkdir teste
[postgres@localhost ~]$ /usr/lib/postgresql/9.6/bin/initdb -D teste
[postgres@localhost ~]$ /usr/lib/postgresql/9.6/bin/pg_ctl -D teste -l teste/teste.log start
2. No arquivo de configuração do PostgreSQL (teste/postgresql.conf), altere a variável archive_mode para on:
# Arquivo teste/postgresql.conf
archive mode = on
3. Em seguida, configure a variável archive_command que indica como e onde os arquivos WALs serão armazenados:
archive_command = 'rsync %p diretorio_destino/%f'
A variável %p simboliza o arquivo de origem e não requer o caminho. Já %f, representa o arquivo de origem, precedido pelo diretório de nossa escolha. Em ambiente de produção, o ideal é armazenar estes arquivos em hardware diferente do servidor PostgreSQL principal onde os arquivos são gerados.
4. Altere o parâmetro seguinte:
Este último parâmetro altera a estrutura do arquivo WAL que será consumido pelo backup.
5. Para que as alterações sejam aplicadas é necessário reiniciar o servidor.
[postgres@localhost ~]$ /usr/lib/postgresql/9.6/bin/pg_ctl -D teste -l teste/teste.log restart
6. A fim de testar os arquivos WAL, podemos gerar uma tabela com números sequenciais através do seguinte comando:
teste=# CREATE TABLE t_test AS SELECT * FROM generate_series(1, 1000000);
Este comando deve gerar um número razoável de arquivos WAL. Ao acessar o diretório de destino, você poderá visualizar um grande numero destes arquivos, todos com 16MB de tamanho.
Ative o backup PITR
A partir da versão 9.1 do PostgreSQL, fazemos backups binários de nosso cluster através do comando pg_basebackup. Para tal, é necessário um usuário com permissão de replicação, por padrão, o usuário postgres já possui essa permissão. É preciso habilitar a conexão deste usuário no arquivo pg_hba.conf.
7. Veja uma configuração válida para fins de replicação:
#Arquivo: teste/pg_hba.conf
#TYPE DATABASE USER  ADDRESS METHOD
host         replication  postgres 192.168.0.1/24  md5
host         replication  postgres localhost       md5
Com esta configuração, serão aceitas conexões de IPs que comecem com 192.168.0.*, como também a partir do localhost.
Habilite essa configuração de acordo com as suas necessidades, atentando-se sempre à segurança do seu sistema.
Após alterar o arquivo pg_hba.conf, carregamos as mudanças no psql através deste comando:
teste=# SELECT pg_reload_conf();
Execute o backup
Somente então podemos executar o pg_basebackup.
9. Utilizando o usuário "postgres", geramos um backup binário de nosso cluster através do seguinte comando:
[postgres@localhost ~]$ /usr/lib/postgresql/9.6/bin/pg_basebackup -D <diretorio_backup> -h <host>
<diretorio_backup> especifica onde os dados do cluster serão armazenados. Em nosso exemplo de aplicação, nomeamos o diretório de armazenamento como backup.
<host> é o endereço a ser conectado pelo pg_basebackup
Recupere um backup
Em PostgreSQL, todo o processo de recuperação de dados é realizado através do arquivo recovery.conf, que deve residir no diretório principal do backup, neste exemplo, o diretório backup.
Este arquivo é lido assim que iniciamos o banco, indicando qual diretório será utilizado para que o backup se alimente dos arquivos WAL. Especifica também, até que ponto no tempo, esse abastecimento acontecerá.
10. Uma simples configuração para este arquivo pode ser a seguinte:
# Arquivo: backup/recovery.conf
restore_command = 'rsync diretorio_destino/%f %p'
recovery_target_time = '2018-03-06 13:43:12'
O restore_command constitui a contraparte do archive_command visto anteriormente. Este comando é executado para cada arquivo necessário na restauração do backup.
A opção recovery_target_time , indica até que ponto desejamos realizar o nosso replay. Por exemplo: caso tenhamos acidentalmente deletado uma tabela no dia 20 de março, às 22:00 horas, basta informar a este arquivo que desejamos restaurar o banco no dia 20 de março, às 21:59.
11. É sempre desejável limpar o diretório contendo logs de transação assim que estes sejam devidamente consumidos pelo backup. Opcionalmente, configuramos esse comportamento através do parâmetro archive_cleanup_command.
archive_cleanup_command = '/usr/lib/postgresql/9.6/bin/pg_archivecleanup diretorio_destino %r'
12. É necessário alterar a permissão do diretório contendo o backup para 700 através do comando a seguir. Caso contrário, será emitido um erro pelo PostgreSQL.
sudo chmod 700 <strong><diretorio_backup></strong>
Dado que estamos realizando o teste na mesma máquina, recomenda-se configurar o backup para execução em uma porta diferente da porta padrão (5432).
13. Neste exemplo, modificamos o arquivo backup/postgresql.conf para subir o backup na porta 5433:
# Arquivo backup/postgresql.conf
14. Depois destas configurações, só nos resta iniciar o cluster no diretório backup. Este se alimentará de todos os arquivos WAL, atingindo um estado consistente, pronto para leitura e escrita.
[postgres@localhost ~]$ /usr/lib/postgresql/9.6/bin/pg_ctl -D backup -l backup/backup.log start
O log do banco será armazenado no arquivo backup/backup.log
Observe que após a reconstrução do cluster, o mesmo atinge um ponto de consistência, podendo aceitar leituras e escritas.
A partir deste ponto, o banco de dados gera uma timeline diferente, daquela do cluster de origem, impossibilitando realimentar o mesmo cluster com arquivos WAL gerados pelo cluster teste.
É válido notar que, após a inicialização do banco, o arquivo recovery.conf é renomeado para recovery.done, indicando a restauração do cluster.