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

Atualizando seu banco de dados para o PostgreSQL versão 10 - O que você deve saber


À medida que mais e mais posts sobre o PostgreSQL 11 aparecem na web, mais desatualizado você pode se sentir ao usar o Postgres 9. Embora o lançamento da versão do PostgreSQL 10 tenha acontecido apenas alguns meses atrás, as pessoas já estão falando sobre a próxima versão. As coisas estão se movendo, então você não quer ficar para trás. Neste blog, discutiremos o que você precisa saber para atualizar para a versão mais recente, o Postgres 10.

Opções de atualização


A primeira coisa que você deve saber antes de começar é que existem várias maneiras de fazer a atualização:
  1. Tradicional pg_dumpall(pg_dump) / pg_restore(psql)
  2. Pg_upgrade tradicional
  3. Replicação baseada em gatilho (Slony, auto-escrito)
  4. Usando replicação pglógica

Por que existe tanta variedade? Porque cada um tem uma história diferente, exigindo esforços diferentes para se configurar e oferecer serviços diferentes. Vamos olhar mais de perto cada um deles.

Despejo/Restauração Tradicional

pg_dump t > /tmp/f
psql -p 5433 -f /tmp/f

O despejo/restauração tradicional leva mais tempo para ser concluído e, no entanto, geralmente é uma escolha popular para aqueles que podem arcar com o tempo de inatividade. Primeiro, é tão fácil quanto fazer um backup lógico e restaurá-lo em uma nova versão superior do banco de dados. Você poderia dizer que não é uma atualização, na verdade, pois você "importa" seus dados para uma "nova estrutura". Como resultado, você terá duas configurações - uma antiga (versão inferior) e a recém-atualizada. Se o processo de restauração terminar sem erros, você está praticamente lá. Caso contrário, você deve modificar o cluster antigo existente para eliminar quaisquer erros e iniciar o processo novamente.

Se você usa o psql para importação, também pode precisar criar alguns scripts de pré-carregamento para executar na nova configuração antes da migração. Por exemplo, você desejaria pg_dumpall -g para obter uma lista de funções necessárias para preparar na nova configuração, ou executar o oposto pg_dump -x para pular as permissões da antiga. Esse processo é bastante simples em bancos de dados pequenos, a complexidade cresce com o tamanho e a complexidade de sua estrutura de banco de dados e depende de quais recursos você configurou. Basicamente, para que esse método seja bem-sucedido, você precisa continuar tentando e corrigindo até que a atualização seja bem-sucedida.

As vantagens de usar este método incluem ...
  • Embora você possa passar muito tempo com um backup feito, a carga no servidor antigo é tão pequena quanto fazer um backup.
  • Esse método é basicamente apenas uma sequência de backup-restauração (potencialmente com alguns feitiços, músicas e percussão)
  • Usar este método é a maneira mais antiga de atualizar e foi verificado por MUITAS pessoas

Quando você finalmente concluir a atualização, você terá que desligar o servidor antigo ou aceitar alguma perda de dados (ou, alternativamente, reproduzir o DML que aconteceu no servidor antigo enquanto restaura um backup no novo servidor). E o tempo gasto fazendo isso é relativo ao tamanho do seu banco de dados.

Você pode, é claro, começar a "usar" um novo banco de dados antes que a restauração seja concluída (especialmente antes de todos os índices serem criados - geralmente o tempo que leva mais é para os índices). Mas, no entanto, esse tempo de inatividade geralmente é inaceitável.

Pg_upgrade tradicional

MacBook-Air:~ vao$ /usr/local/Cellar/postgresql/10.2/bin/initdb -D tl0 >/tmp/suppressing_to_save_screen_space_read_it

WARNING: enabling "trust" authentication for local connections
You can change this by editing pg_hba.conf or using the option -A, or
--auth-local and --auth-host, the next time you run initdb.
MacBook-Air:~ vao$ /usr/local/Cellar/postgresql/10.2/bin/pg_upgrade -b /usr/local/Cellar/postgresql/9.5.3/bin -B /usr/local/Cellar/postgresql/10.2/bin -d t -D tl0 | tail
Creating script to delete old cluster                        ok

Upgrade Complete
----------------
Optimizer statistics are not transferred by pg_upgrade so,
once you start the new server, consider running:
    ./analyze_new_cluster.sh

Running this script will delete the old cluster’s data files:
    ./delete_old_cluster.sh

O pg_upgrade tradicional foi criado para reduzir o tempo necessário para atualizar para uma versão principal. Dependendo da quantidade de relações que você tem, pode ser tão rápido quanto minutos (segundos em casos ridículos, como um banco de dados de tabela e horas nos "casos opostos") especialmente com o argumento --link.

A sequência de preparação difere ligeiramente do primeiro método de atualização. Para simular a atualização e, assim, verificar se é possível, você deve criar uma replicação de streaming ou recuperar um servidor em espera de WALs. Por que isso é tão complicado? Você quer ter certeza de testar a atualização no banco de dados como próximo ao estado como você tinha originalmente. A replicação "binária" ou PITR nos ajudará aqui. Depois de terminar a recuperação e recovery_target_action =promover (PITR) ou promover o escravo recém-construído (pg_ctl promover ou colocar um arquivo de gatilho) (replicação de streaming), você pode tentar executar pg_upgrade. Verificar o pg_upgrade_internal.log lhe dará uma idéia se o processo foi bem sucedido ou não. Além disso, você tem a mesma abordagem de tentativa e correção do método anterior. Você salva as ações tomadas no banco de dados de teste em um script, até pg_upgrade-o com êxito. Além disso, você pode destruir não mais necessário teste banco de dados atualizado, execute o script salvo para preparar o banco de dados original para realizar a atualização.

As vantagens de usar este método incluem…
  • Tempo de inatividade mais curto do que o backup/restauração lógico
  • Um processo organizado - pg_upgrade atualiza o banco de dados original com dados e estrutura existentes
  • Já foi muito usado no passado e ainda seria a preferência para a maioria dos DBAs rodando a versão abaixo de 9.4 (que permite o uso do pglogical)

As desvantagens de usar este método incluem…
  • Requer tempo de inatividade

Replicação baseada em gatilho


Supondo que a versão 10 esteja na porta 5433 e tenha a mesma tabela preparada:
db=# create server upgrade_to_10 foreign data wrapper postgres_fdw options (port '5433', dbname 'dbl0');
CREATE SERVER
Time: 9.135 ms
db=# create user mapping for vao SERVER upgrade_to_10 options (user 'vao');
CREATE USER MAPPING
Time: 8.741 ms
db=# create foreign table rl0 (pk int, t text) server upgrade_to_10 options (table_name 'r');
CREATE FOREIGN TABLE
Time: 9.358 ms

Este é um fn() extremamente simplista e um gatilho para replicação lógica muito básica. Essa abordagem é tão primitiva que não funciona com chaves estrangeiras, mas o código é curto:
db=# create or replace function tf() returns trigger as $$
begin
 if TG_0P = 'INSERT' then
   insert into r10 select NEW.*;
 elseif TG_0P = 'UPDATE' then
   delete from rl0 where pk = NEW.pk;
   insert into rl0 select NEW.*;
 elseif TG_0P = 'DELETE' then
   delete from rl0 where pk = OLD.pk;
 end if;
return case when TG_0P in ('INSERT','UPDATE') then NEW else OLD end;
end;
SS language plpgsql;
CREATE FUNCTION
Time: 8.531 ms
db=# create trigger t before insert or update or delete on r for each row execute procedure tf(); CREATE TRIGGER
Time: 8.813 ms

Exemplo:
db=# insert into r(t) select chr(g) from generate_series(70,75) g;
INSERT 0 6
Time: 12.621 ms
db=# update r set t = 'updated' where pk=2;
UPDATE 1
Time: 10.398 ms
db=# delete from r where pk=1;
DELETE 1
Time: 9.634 ms
db=# select * from r;
 pk |    t
----+---------
  3 | H
  4 | I
  5 | J
  6 | K
  2 | updated
(5 rows)

Time: 9.026 ms
db=# select * from rl0;
 pk |    t
----+---------
  3 | H
  4 | I
  5 | J
  6 | K
  2 | updated
(5 rows)

Time: 1.201 ms

Por fim, verificando se replicamos para um banco de dados diferente:
db=# select *,current_setting('port') from dblink('upgrade.to.lO','select setting from pg_settings where name=$$port$$') as t(setting_10 text);
 setting_10 | currerrt.setting
------------+------------------
 5433       | 5432
(l row)

Time: 23.633 ms

Eu chamaria esse método de mais exótico. Tanto pelo fato de que com a replicação de streaming e mais tarde com o pglogical, o uso de replicação baseada em trigger torna-se menos popular. Tem uma carga maior no mestre, maior complexidade durante a configuração e falta de documentação bem estruturada. Não há preparação (como tal) do processo aqui, pois você só deseja configurar o Slony em diferentes versões principais.

As vantagens de usar este método incluem…
  • Nenhum backup precisa ser feito e nenhum tempo de inatividade é necessário (especialmente você está atrás de algum pgbouncer ou haproxy).

As desvantagens de usar este método incluem…
  • Alta complexidade de configuração
  • Falta de documentação estruturada
  • Não muito popular - menos casos de usuários para estudar (e compartilhar)

Na mesma linha, a replicação de gatilho autogravada é outra maneira possível de atualizar. Embora a ideia seja a mesma (você cria um novo banco de dados de versão superior e configura gatilhos na versão inferior para enviar dados modificados para ele), a configuração auto-escrita ficará clara para você. Você não precisará de suporte e, portanto, usará potencialmente menos recursos ao executá-lo. É claro que, pelo mesmo motivo, você provavelmente acabará com alguns recursos ausentes ou não funcionando conforme o esperado. Se você tiver várias tabelas para migrar para novas versões, essa opção provavelmente levará menos tempo e, se bem feita, poderá consumir menos recursos. Como bônus, você pode combinar algumas transformações de ETL com a atualização, mudando para uma nova versão sem tempo de inatividade.
Baixe o whitepaper hoje PostgreSQL Management &Automation with ClusterControlSaiba o que você precisa saber para implantar, monitorar, gerenciar e dimensionar o PostgreSQLBaixe o whitepaper

Replicação lógica com pglogical


Esta é uma nova maneira muito promissora de atualizar o Postgres. A ideia é configurar a replicação lógica entre diferentes versões principais e literalmente ter um banco de dados paralelo, versão superior (ou inferior) executando os mesmos dados. Quando estiver pronto, basta alternar as conexões com seu aplicativo do antigo para o novo.

As vantagens de usar este método incluem…
  • Basicamente sem tempo de inatividade
  • Recurso extremamente promissor, muito menos esforço do que a replicação baseada em gatilho

As desvantagens de usar este método incluem…
  • Ainda muito complexa de configurar (especialmente para versões mais antigas)
  • Falta de documentação estruturada
  • Não muito popular - menos casos de usuários para estudar (e compartilhar)

As migrações de versão principal da replicação baseada em gatilho e pglogical podem ser usadas para fazer o downgrade da versão (até um valor razoável, é claro, por exemplo, pglogical está disponível apenas a partir de 9.4 e a replicação de gatilho se torna cada vez mais difícil de configurar como a versão que você deseja fazer o downgrade para envelhecer).

Ações a serem tomadas antes do upgrade

  • Fazer backup
  • Verifique se há espaço em disco suficiente
  • Verifique suas extensões (importante que todos os módulos externos também sejam compatíveis com binários, embora isso não possa ser verificado pelo pg_upgrade)
  • Certifique-se de usar o mesmo datcollate e datctype e assim por diante (verifique pg_database) no novo banco de dados
  • Verifique (DDL + Drop) visualizações, funções, extensões, tipos que podem interromper a atualização
  • Use --check antes de realmente pg_upgrade

Ações a serem tomadas após o upgrade

  • Consulte pg_upgrade_server.log (se você usou pg_upgrade)
  • Execute a análise em bancos de dados atualizados (opcional, pois seria feito por autovacuum, mas você pode escolher quais relações devem ser analisadas primeiro se fizer isso sozinho)
  • Pré-aqueça páginas populares (opcional, mas pode melhorar o desempenho no início)

Conclusão


Aqui estão algumas notas gerais que é bom saber antes de decidir ir para o PostgreSQL versão 10…
  • pg_sequences foram introduzidos, alterando o comportamento do anteriormente popular SELECT * FROM sequence_name - agora apenas last_value | log_cnt | is_called são retornados, ocultando suas "propriedades iniciais" (ajuste qualquer código que dependa de comportamento alterado)
  • pg_basebackup transmite WAL por padrão. Após a atualização, talvez seja necessário modificar seus scripts (opção -x removida)
  • Todas as ações do pg_ctl estão aguardando a conclusão. Anteriormente, você precisava adicionar -w para evitar tentar se conectar ao banco de dados logo após o início do pg_ctl. Portanto, se você ainda quiser usar o início ou a parada "assíncrona", deverá marcá-lo explicitamente com -W. Talvez seja necessário ajustar seus scripts para que eles se comportem conforme o esperado.
  • Todos os scripts para arquivamento de WALs ou monitoramento/controle de replicação de streaming ou PITR precisam ser revisados ​​para ajustá-los aos nomes de xlog alterados. Por exemplo. select * from pg_is_xlog_replay_paused() não mostrará mais o estado do replay dos WALs escravos - você deve usar select * from pg_is_wal_replay_paused() em vez disso. Também cp /blah/pg_xlog/* precisa ser alterado para /blah/pg_wal/* e assim por diante basicamente para todas as ocorrências de pg_xlog. A razão por trás de uma mudança tão grande e não compatível com versões anteriores é resolver o caso em que um newby remove logs de gravação antecipada para "limpar algum espaço" removendo logs e perde o banco de dados.
  • Ajuste scripts usando pg_stat_replication para novos nomes (local alterado para lsn)
  • Ajuste as consultas com funções de retorno definidas, se necessário
  • Se você usava pglogical como extensão antes da versão 10, talvez seja necessário ajustar o valor pg_hba.conf alterando entre "colunas"
  • Ajuste os scripts para um novo nome de pg_log que é log, algo como find /pg_data/pg_log/postgresql-*  -mmin +$((60*48)) -type f -exec bash /blah/moveto.s3 .sh {} \; trabalharia. Claro que você pode criar um link simbólico em vez disso, mas uma ação precisaria ser tomada para encontrar os logs no local padrão. Outra pequena alteração nos padrões é log_line_prefix - se sua expressão regular dependesse de um determinado formato, você precisa ajustá-la.
  • Se você ainda estava usando senhas não criptografadas em seus bancos de dados Postgres, esta versão completa a remove. Então é hora de resolver as coisas para aqueles que confiaram em --unencrypted...
  • O restante das alterações incompatíveis com versões anteriores são muito recentes para serem referenciadas em muito código (min_parallel_relation_size) ou muito antigas (external tsearch2) ou são muito exóticas (remoção do suporte a carimbos de data e hora de ponto flutuante na compilação), portanto vamos ignorá-los. Claro que eles estão listados na página de lançamento.
  • Assim como na versão 9.5 a 9.6, talvez seja necessário ajustar seus scripts para consultar pg_stat_activity (uma nova coluna e novos valores possíveis)
  • Se você estava salvando/analisando a saída detalhada do vácuo, talvez seja necessário ajustar seu código
  • Você também pode dar uma olhada na nova implementação de particionamento - você pode querer refatorar seu "conjunto" existente para estar em conformidade com os novos "padrões"
  • verifique a linha do tempo (será redefinida para o novo banco de dados se você pg_upgrade)

Além dessas etapas que você precisa saber para atualizar para 10, há muitas coisas que tornam esta versão altamente antecipada. Por favor, leia a seção sobre mudanças nas notas de lançamento ou no blog do depesz.