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

Evolução da tolerância a falhas no PostgreSQL:commit síncrono


PostgreSQL é um projeto incrível e evolui a uma velocidade incrível. Vamos nos concentrar na evolução dos recursos de tolerância a falhas no PostgreSQL em todas as suas versões com uma série de postagens no blog. Este é o quarto post da série e falaremos sobre commit síncrono e seus efeitos na tolerância a falhas e confiabilidade do PostgreSQL.

Se você quiser testemunhar o progresso da evolução desde o início, confira as três primeiras postagens do blog da série abaixo. Cada postagem é independente, então você não precisa ler uma para entender a outra.
  1. Evolução da tolerância a falhas no PostgreSQL 
  2. Evolução da tolerância a falhas no PostgreSQL:fase de replicação 
  3. Evolução da tolerância a falhas no PostgreSQL:viagem no tempo

Compromisso síncrono


Por padrão, o PostgreSQL implementa a replicação assíncrona, onde os dados são transmitidos sempre que conveniente para o servidor. Isso pode significar perda de dados em caso de failover. É possível solicitar ao Postgres que exija um (ou mais) standbys para reconhecer a replicação dos dados antes do commit, isso é chamado de replicação síncrona (commit síncrono ) .

Com a replicação síncrona, o atraso da replicação diretamente afeta o tempo decorrido das transações no mestre. Com a replicação assíncrona, o mestre pode continuar a toda velocidade.

A replicação síncrona garante que os dados sejam gravados em pelo menos dois nós antes que o usuário ou aplicativo seja informado de que uma transação foi confirmada.

O usuário pode selecionar o modo de confirmação de cada transação , para que seja possível ter transações de confirmação síncronas e assíncronas em execução simultaneamente.

Isso permite trocas flexíveis entre desempenho e certeza de durabilidade da transação.

Configurando a confirmação síncrona


Para configurar a replicação síncrona no Postgres, precisamos configurar o synchronous_commit parâmetro em postgresql.conf.

O parâmetro especifica se a confirmação da transação aguardará que os registros WAL sejam gravados no disco antes que o comando retorne um sucesso indicação ao cliente. Os valores válidos estão ativadosremote_applyremote_write , local e desativado . Discutiremos como as coisas funcionam em termos de replicação síncrona quando configurarmos o synchronous_commit parâmetro com cada um dos valores definidos.

Vamos começar com a documentação do Postgres (9.6):

Aqui entendemos o conceito de commit síncrono, como descrevemos na parte de introdução do post, você é livre para configurar a replicação síncrona, mas se não fizer isso, sempre há o risco de perder dados. Mas sem risco de criar inconsistência no banco de dados, ao contrário de desativar fsync off – porém isso é assunto para outro post -. Por fim, concluímos que, se precisarmos, não queremos perder nenhum dado entre atrasos de replicação e queremos ter certeza de que os dados são gravados em pelo menos dois nós antes que o usuário/aplicativo seja informado de que a transação foi confirmada , precisamos aceitar perder algum desempenho.

Vamos ver como diferentes configurações funcionam para diferentes níveis de sincronização. Antes de começarmos, vamos falar como o commit é processado pela replicação do PostgreSQL. O cliente executa consultas no nó mestre, as alterações são gravadas em um log de transações (WAL) e copiadas pela rede para o WAL no nó em espera. O processo de recuperação no nó de espera lê as alterações do WAL e as aplica aos arquivos de dados como durante a recuperação de falhas. Se o modo de espera estiver em espera ativa modo, os clientes podem emitir consultas somente leitura no nó enquanto isso está acontecendo. Para obter mais detalhes sobre como a replicação funciona, confira a postagem do blog de replicação nesta série.


Fig.1 Como funciona a replicação

synchronous_commit =desativado


Quando definimos sychronous_commit = off, o COMMIT não espera que o registro da transação seja liberado para o disco. Isso é destacado na Fig.2 abaixo.


Fig.2 synchronous_commit =off

synchronous_commit =local


Quando definimos synchronous_commit = local, o COMMIT espera até que o registro da transação seja liberado para o disco local. Isso é destacado na Fig.3 abaixo.


Fig.3 synchronous_commit =local

synchronous_commit =ativado (padrão)


Quando definimos synchronous_commit = on, o COMMIT aguardará até que o(s) servidor(es) especificado(s) por synchronous_standby_names confirme se o registro da transação foi gravado com segurança no disco. Isso é destacado na Fig.4 abaixo.

Observação: Quando synchronous_standby_names está vazio, esta configuração se comporta da mesma forma que synchronous_commit = local .


Fig.4 synchronous_commit =ativado

synchronous_commit =remote_write


Quando definimos synchronous_commit = remote_write, o COMMIT aguardará até que o(s) servidor(es) especificado(s) por synchronous_standby_names confirme a gravação do registro da transação no sistema operacional, mas não necessariamente atingiu o disco. Isso é destacado na Fig.5 abaixo.


Fig.5 synchronous_commit =remote_write

synchronous_commit =remote_apply


Quando definimos synchronous_commit = remote_apply, o COMMIT aguardará até que o(s) servidor(es) especificado(s) por synchronous_standby_names confirmar que o registro da transação foi aplicado ao banco de dados. Isso é destacado na Fig.6 abaixo.


Fig.6 synchronous_commit =remote_apply

Agora, vamos ver sychronous_standby_names parâmetro em detalhes, que é referido acima ao definir synchronous_commit como onremote_apply ou remote_write .

synchronous_standby_names =‘standby_name [, …]’


A confirmação síncrona aguardará a resposta de um dos standbys listados na ordem de prioridade. Isso significa que, se o primeiro standby estiver conectado e transmitindo, o commit síncrono sempre aguardará a resposta dele, mesmo que o segundo standby já tenha respondido. O valor especial de  * pode ser usado como stanby_name que corresponderá a qualquer espera conectada.

synchronous_standby_names ='num (standby_name [, …])'


A confirmação síncrona aguardará a resposta de pelo menos num número de standbys listados na ordem de prioridade. As mesmas regras acima se aplicam. Então, por exemplo, definindo synchronous_standby_names = '2 (*)' fará com que a confirmação síncrona aguarde a resposta de quaisquer 2 servidores em espera.

synchronous_standby_names está vazio


Se este parâmetro estiver vazio como mostrado, ele altera o comportamento da configuração de synchronous_commit para on , remote_write ou remote_apply para se comportar da mesma forma que local (ou seja, o COMMIT apenas aguardará a liberação para o disco local).

Conclusão


Nesta postagem do blog, discutimos a replicação síncrona e descrevemos os diferentes níveis de proteção disponíveis no Postgres. Continuaremos com a replicação lógica na próxima postagem do blog.

Referências


Agradecimentos especiais ao meu colega Petr Jelinek por me dar a ideia das ilustrações.

Documentação do PostgreSQL
Livro de receitas de administração do PostgreSQL 9 – segunda edição