Atualizar o Postgres no Servidor de Produção sem tempo de inatividade

6

Eu tenho um servidor de produção executando o Postgres 9.4. O banco de dados é > 10 GB. É possível atualizar para o Postgres 9.5 sem tempo de inatividade e sem perder dados?

Tutoriais de atualização recomendam parar o Postgres durante a execução de sudo pg_upgradecluster 9.4 main , mas isso pode levar muito tempo. A atualização de um cluster de 10 GB pode levar várias horas!

Eu também tentei pg_dump mydb > db.sql . Eliminar o banco de dados e inserir o dump novamente no PG 9.4 ( psql -d mydb -f db.sql ) levou cerca de 50 minutos.

Mas inserir o despejo no PG 9.5 terminado somente depois de mais de 7 horas. Especialmente criando o índice foi muito lento ...

2016-07-18 00:13:55 CEST [60358-5] ERROR:  canceling autovacuum task
2016-07-18 00:13:55 CEST [60358-6] CONTEXT:  automatic analyze of table ...
2016-07-18 00:36:20 CEST [60366-1] ERROR:  canceling autovacuum task
2016-07-18 00:36:20 CEST [60366-2] CONTEXT:  automatic analyze of table ...
2016-07-18 04:21:40 CEST [60361-1] ERROR:  canceling autovacuum task
2016-07-18 04:21:40 CEST [60361-2] CONTEXT:  automatic analyze of table ...
2016-07-18 07:55:19 CEST [61316-1] ERROR:  canceling autovacuum task
2016-07-18 07:55:19 CEST [61316-2] CONTEXT:  automatic analyze of table ...

Portanto, nem pg_upgradecluster nem pg_dump é uma solução aceitável. Mesmo com o PG 4, você teria um tempo de inatividade de pelo menos 50 minutos. Portanto: Como os bancos de dados podem ser atualizados em servidores de produção ou em grandes clusters master-slave sem tempo de inatividade e dataloss?

    
por Barmi 18.07.2016 / 11:36

3 respostas

6

Nenhum tempo de inatividade não é possível sem alguma mágica de agrupamento.

Algumas outras possibilidades:

  1. use pg_upgrade com a opção --link . Com essa opção, os arquivos DB originais não são copiados, em vez disso, eles são vinculados ao novo diretório, acelerando bastante o processo. Por favor, preste atenção que este irá alterar permanentemente os arquivos DB de origem.
  2. use pg_dump e restaure no novo banco de dados. Você pode reduzir bastante o tempo necessário desabilitando gravações síncronas no novo banco de dados ( fsync = false no novo arquivo de configuração da instância do PG)
  3. instala de lado uma nova instância do PG e permite que ela seja executada em uma porta diferente. Em seguida, use pg_dump para carregar, via rede, o dump para a nova instância. Quando terminar, troque as portas e use a nova instância.
por 18.07.2016 / 12:19
1

Acho que você já resolveu isso, talvez para outras pessoas com problemas semelhantes.

Após vários anos de trabalho com o postgresql da versão 8.4 para a mais recente 9.6, eu recomendaria para esses casos - não "atualizar". Se for possível, crie uma nova máquina ou uma nova instância de nuvem com a versão mais recente do SO que você usa (muito importante - evita muitos problemas) e a versão mais recente do pg e os dados duplicados.

Como duplicar dados depende da sua aplicação, versão do PostgreSQL e ambiente circundante. Database ~ 10 GB não é tão grande, então é bom para você. Eu trabalho com dbs > 400 GB, então imagine a multiplicidade de problemas aqui ...

    O
  • Pg_dump 9.4 já permite que você faça o dump no formato de diretório com múltiplas tarefas usando múltiplos núcleos de CPU que podem diminuir o tempo de despejo de forma muito significativa - a menos que você tenha tudo em uma grande tabela: -)
  • Ou para o pg 9.4+ você pode usar a extensão pglogical como mencionado anteriormente, o que é realmente uma ótima solução, mas esteja ciente - para fazer uma execução em master você deve reiniciar postgres porque a extensão deve ser adicionada ao arquivo postgresql.conf em shared_preload_libraries = ' pglogical '- veja aqui: link Então eu recomendo testar em alguma outra instância com a mesma versão antes! E para mudar para a nova instância agendar alguma pequena janela de manutenção para mudar os clientes para o novo banco de dados - se a string de conexão não for codificada no aplicativo :-) - mas nesse caso você pode preparar pgbouncer na máquina antiga com conexões configuradas para nova máquina, pare o banco de dados antigo, mude a porta pg (presume 5432) para pgbouncer e lide com as strings de conexão mais tarde, se possível ...
  • Ou talvez seu aplicativo não tenha tantos novos dados chegando e você possa usar as mais recentes inserções / atualizações de garfo e backup em seu aplicativo para ambas as máquinas? E troque os clientes quando tiver certeza de que tudo está funcionando?

Eu vi variantes de todos esses cenários na vida real. Então se divirta! Eu cruzo os dedos: -)

    
por 08.12.2016 / 17:49
1

A atualização (quase) sem tempo de inatividade deve ser possível com pglogical . Pelo menos para o PostgreSQL > = 9.4 e mais recente, deve funcionar.

É um projeto relativamente novo (2016) baseado no código da Replicação bidirecional para o PostgreSQL . Para a instalação, você precisará do repositório do 2ndQuadrant .

O uso é descrito no README , uma reinicialização do banco de dados é necessária (você precisa atualizar a configuração de replicação), mas pelo menos não deve t causar várias horas de inatividade.

Ao contrário de repmgr , pglogical é destinado à replicação de banco de dados única, que levará muito mais tempo do que a cópia arquivos binários WAL.

Primeiramente, habilite a extensão para cada banco de dados que precisa ser copiado (atualizado):

CREATE EXTENSION pglogical;

Atualmente, todos os comandos precisam ser executados como superusuário ( postgres ). Comece com a criação de um "nó mestre" ( provider ):

SELECT pglogical.create_node(
    node_name := 'provider1',
    dsn := 'host=providerhost port=5432 dbname=db'
);

e marca esquema (s) para replicação:

SELECT pglogical.replication_set_add_all_tables('default', ARRAY['public']);

e replicação de sequências:

SELECT pglogical.replication_set_add_all_sequences('default', ARRAY['public']);

Observe que cada tabela requer uma chave primária; caso contrário, a replicação não será iniciada. Ao contrário de outros métodos de backup, aqui a consistência da tabela é importante.

Continue com "nó de espera" ( subscriber )

SELECT pglogical.create_node(
    node_name := 'subscriber1',
    dsn := 'host=thishost port=5432 dbname=db'
);

e finalmente iniciar a replicação:

SELECT pglogical.create_subscription(
    subscription_name := 'subscription1',
    provider_dsn := 'host=providerhost port=5432 dbname=db'
);
    
por 29.11.2016 / 23:57