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

Atualizando para o PostgreSQL 11 com replicação lógica


Está na hora.

Há cerca de um ano, publicamos o PostgreSQL 10 com suporte para replicação lógica nativa. Um dos usos da replicação lógica é permitir a atualização com baixo ou nenhum tempo de inatividade entre as versões principais do PostgreSQL. Até agora, o PostgreSQL 10 era a única versão do PostgreSQL com replicação lógica nativa, então não havia muitas oportunidades de atualização dessa maneira. (A replicação lógica também pode ser usada para mover dados entre instâncias em diferentes sistemas operacionais ou arquiteturas de CPU ou com diferentes definições de configuração de baixo nível, como tamanho de bloco ou localidade — sidegrading, se desejar.) Agora que o PostgreSQL 11 está próximo, haverá mais razões para fazer uso desta funcionalidade.

Vamos primeiro comparar as três principais maneiras de atualizar uma instalação do PostgreSQL:
  • pg_dump e restauração
  • pg_upgrade
  • replicação lógica

Podemos comparar esses métodos em termos de robustez, velocidade, tempo de inatividade necessário e restrições (e mais, mas temos que parar em algum lugar para este artigo).

pg_dump and restore é sem dúvida o método mais robusto, pois é o mais testado e está em uso há décadas. Ele também tem muito poucas restrições em termos do que pode manipular. É possível construir bancos de dados que não podem ser despejados e restaurados, principalmente envolvendo relacionamentos de dependência de objetos específicos, mas esses são raros e geralmente envolvem práticas desencorajadas.

O problema com o método de despejo e restauração é que ele efetivamente requer tempo de inatividade durante todo o tempo em que as operações de despejo e restauração são executadas. Embora o banco de dados de origem ainda seja legível e gravável durante a execução do processo, todas as atualizações no banco de dados de origem após o início do dump serão perdidas.

O pg_upgrade melhora o processo pg_dump movendo os arquivos de dados diretamente sem ter que despejá-los em um formato textual lógico. Observe que pg_upgrade ainda usa pg_dump internamente para copiar o esquema, mas não os dados. Quando o pg_upgrade era novo, sua robustez era questionada e ele atualizava alguns bancos de dados incorretamente. Mas o pg_upgrade agora está bastante maduro e bem testado, então não é mais necessário hesitar em usá-lo por esse motivo. Enquanto o pg_upgrade é executado, o sistema de banco de dados está inativo. Mas pode-se fazer uma escolha sobre quanto tempo o pg_upgrade é executado. No modo de cópia padrão, o tempo total de execução é composto pelo tempo de despejo e restauração do esquema (que geralmente é muito rápido, a menos que haja milhares de tabelas ou outros objetos) mais o tempo para copiar os arquivos de dados, que depende quão grande é o banco de dados (e o sistema de E/S, sistema de arquivos, etc.).

No modo de link opcional, os arquivos de dados são vinculados fisicamente ao novo diretório de dados, de modo que o tempo é apenas o tempo para executar uma operação de kernel curta por arquivo em vez de copiar cada byte. A desvantagem é que, se algo der errado com a atualização ou você precisar retornar à instalação antiga, essa operação destruirá seu banco de dados antigo. (Estou trabalhando em uma solução melhor dos dois mundos para o PostgreSQL 12 usando reflinks ou operações de clone de arquivo em sistemas de arquivos suportados.)

A replicação lógica é a mais nova do grupo aqui, então provavelmente levará algum tempo para resolver os problemas. Se você não tiver tempo para explorar e investigar, esse pode não ser o caminho a seguir agora. (É claro que as pessoas têm usado outras soluções de replicação lógica não essenciais, como Slony, Londiste e pglogical para atualizar o PostgreSQL por muitos anos, então há muita experiência com os princípios, se não com os detalhes.)

A vantagem de usar a replicação lógica para atualizar é que o aplicativo pode continuar sendo executado na instância antiga enquanto ocorre a sincronização de dados. Só precisa haver uma pequena interrupção enquanto as conexões do cliente são alternadas. Portanto, embora uma atualização usando replicação lógica seja provavelmente mais lenta do início ao fim do que usar pg_upgrade no modo de cópia (e definitivamente mais lenta do que usar o modo hardlink), isso não importa muito, pois o tempo de inatividade real pode ser muito menor.

Observe que a replicação lógica atualmente não replica as alterações de esquema. Neste procedimento de atualização proposto, o esquema ainda é copiado via pg_dump, mas as alterações de esquema subsequentes não são transportadas. A atualização com replicação lógica também tem algumas outras restrições. Certas operações não são capturadas pela replicação lógica:objetos grandes, TRUNCATE, alterações de sequência. Discutiremos soluções alternativas para esses problemas mais tarde.

Se você tiver algum standby físico (e se não tiver, por que não tem?), também existem algumas diferenças a serem consideradas entre os métodos. Com qualquer um dos métodos, você precisa criar novas esperas físicas para a instância atualizada. Com o dump e a restauração, bem como com a replicação lógica, eles podem ser implementados antes do início da atualização para que o modo de espera esteja praticamente pronto quando a sincronização inicial da restauração ou da replicação lógica for concluída, sujeita ao atraso da replicação.

Com o pg_upgrade, os novos standbys devem ser criados após a conclusão do upgrade do primário. (A documentação pg_upgrade descreve isso com mais detalhes.) Se você depende de esperas físicas para alta disponibilidade, as esperas devem estar em vigor antes de alternar para a nova instância, portanto, a configuração das esperas pode afetar seus cálculos gerais de tempo.

Mas voltando à replicação lógica. Veja como a atualização com replicação lógica pode ser feita:

0. A instância antiga deve ser preparada para replicação lógica. Isso requer algumas configurações conforme descrito em http://www.postgresql.org/docs/10/static/logical-replication-config.html (principalmente wal_level = logical . Se você precisar fazer essas alterações, elas exigirão a reinicialização do servidor. Portanto, verifique isso com bastante antecedência. Verifique também se pg_hba.conf na instância antiga está configurado para aceitar conexões da nova instância. (Alterar isso requer apenas uma recarga.)

1. Instale a nova versão do PostgreSQL. Você precisa pelo menos do pacote do servidor e do pacote do cliente que contém o pg_dump. Muitos pacotes agora permitem a instalação de várias versões lado a lado. Se você estiver executando máquinas virtuais ou instâncias de nuvem, vale a pena considerar a instalação da nova instância em um novo host.

2. Configure uma nova instância, ou seja, execute initdb. A nova instância pode ter configurações diferentes da antiga, por exemplo, localidade, tamanho do segmento WAL ou soma de verificação. (Por que não usar esta oportunidade para ativar as somas de verificação de dados?)

3. Antes de iniciar a nova instância, pode ser necessário alterar algumas definições de configuração. Se a instância for executada no mesmo host da instância antiga, você precisará definir um número de porta diferente. Além disso, carregue todas as alterações personalizadas que você fez no postgresql.conf em sua instância antiga, como configurações de memória, max_connections , etc. Da mesma forma, faça pg_hba.conf configurações adequadas ao seu ambiente. Normalmente você pode começar copiando o pg_hba.conf arquivo da instância antiga. Se você quiser usar SSL, configure isso agora.

4. Inicie a nova instância (vazia) e verifique se ela funciona a contento. Se você configurar a nova instância em um novo host, verifique neste ponto se pode fazer uma conexão de banco de dados (usando psql) do novo host para a instância de banco de dados antiga. Precisaremos disso nas etapas subsequentes.

5. Copie as definições de esquema com pg_dumpall. (Ou você pode fazer isso com pg_dump para cada banco de dados separadamente, mas não se esqueça de objetos globais, como funções.)
pg_dumpall -s >schemadump.sql
psql -d postgres -f schemadump.sql

Quaisquer alterações de esquema após esse ponto não serão migradas. Você teria que gerenciar esses você mesmo. Em muitos casos, você pode simplesmente aplicar a alteração do DDL em ambos os hosts, mas executar comandos que alteram a estrutura da tabela durante uma atualização provavelmente é um desafio muito grande.

6. Em cada banco de dados na instância de origem, crie uma publicação que capture todas as tabelas:
CREATE PUBLICATION p_upgrade FOR ALL TABLES;

A replicação lógica funciona separadamente em cada banco de dados, portanto, isso precisa ser repetido em cada banco de dados. Por outro lado, você não precisa atualizar todos os bancos de dados de uma só vez, então você pode fazer um banco de dados por vez ou até mesmo não atualizar alguns bancos de dados.

7. Em cada banco de dados na instância de destino, crie uma assinatura que assine a publicação recém-criada. Certifique-se de corresponder os bancos de dados de origem e destino corretamente.
CREATE SUBSCRIPTION s_upgrade CONNECTION 'host=oldhost port=oldport dbname=dbname ...' PUBLICATION p_upgrade;

Defina os parâmetros de conexão conforme apropriado.

8. Agora você espera até que as assinaturas tenham copiado os dados iniciais e estejam totalmente atualizados com o editor. Você pode verificar o status de sincronização inicial de cada tabela em uma assinatura no catálogo do sistema pg_subscription_rel (procure por r =pronto na coluna srsubstate ). O status geral da replicação pode ser verificado em pg_stat_replication no lado de envio e pg_stat_subscription no lado receptor.

9. Conforme mencionado acima, as alterações de sequência não são replicadas. Uma solução possível para isso é copiar os valores de sequência usando pg_dump. Você pode obter um despejo dos valores de sequência atuais usando algo assim:
pg_dump -d dbname --data-only -t '*_seq' >seq-data.sql

(Isto pressupõe que todos os nomes de sequência correspondem a *_seq e nenhuma tabela corresponde a esse nome. Em casos mais complicados, você também pode seguir o caminho de criar um dump completo e extrair os dados de sequência do índice do dump.)

Como as sequências podem avançar enquanto você faz isso, talvez mude o seq-data.sql para adicionar um pouco de folga aos números.

Em seguida, restaure esse arquivo no novo banco de dados usando o psql.

10. Showtime:Mude os aplicativos para as novas instâncias. Isso requer algum pensamento antes do tempo. No cenário mais simples, você interrompe seus programas de aplicativos, altera as configurações de conexão, reinicia. Se você usar um proxy de conexão, poderá alternar a conexão nesse local. Você também pode alternar os aplicativos clientes um por um, talvez para testar um pouco as coisas ou aliviar a carga no novo sistema. Isso funcionará desde que os aplicativos que ainda apontam para o servidor antigo e aqueles que apontam para o novo servidor não façam gravações conflitantes. (Nesse caso, você estaria executando um sistema multimaster, pelo menos por um curto período de tempo, e essa é outra ordem de complexidade.)

11. Quando a atualização estiver concluída, você poderá desmontar a configuração de replicação. Em cada banco de dados na nova instância, execute
DROP SUBSCRIPTION s_upgrade;

Se você já encerrou a instância antiga, isso falhará porque não poderá alcançar o servidor remoto para descartar o slot de replicação. Consulte a página man DROP SUBSCRIPTION para saber como proceder nesta situação.

Você também pode descartar as publicações na instância de origem, mas isso não é necessário, pois uma publicação não retém nenhum recurso.

12. Por fim, remova as instâncias antigas se não precisar mais delas.

Alguns comentários adicionais sobre soluções alternativas para coisas que a replicação lógica não oferece suporte. Se você estiver usando objetos grandes, você pode movê-los usando pg_dump, claro, desde que eles não mudem durante o processo de atualização. Essa é uma limitação significativa, portanto, se você é um usuário pesado de objetos grandes, esse método pode não ser para você. Se seu aplicativo emitir TRUNCATE durante o processo de atualização, essas ações não serão replicadas. Talvez você possa ajustar seu aplicativo para evitar que ele faça isso no momento da atualização ou substituir um DELETE. O PostgreSQL 11 suportará replicação de TRUNCATE, mas isso só funcionará se a instância de origem e de destino for PostgreSQL 11 ou mais recente.

Alguns comentários finais que realmente se aplicam a todos os empreendimentos de atualização:
  • Aplicativos e todos os programas clientes de banco de dados devem ser testados em relação a uma nova versão principal do PostgreSQL antes de serem colocados em produção.
  • Para isso, você também deve testar o procedimento de atualização antes de executá-lo no ambiente de produção.
  • Anote as coisas ou crie um script melhor e automatize o máximo possível.
  • Certifique-se de que sua configuração de backup, sistemas de monitoramento e quaisquer ferramentas e scripts de manutenção sejam ajustados adequadamente durante o procedimento de atualização. Idealmente, eles devem estar em vigor e verificados antes que a transição seja concluída.

Com isso em mente, boa sorte e compartilhe suas experiências.