Dimensionamento de TRIGGER (s) PostgreSQL

14

Como o Postgres aciona escalas de mecanismo?

Temos uma instalação grande do PostgreSQL e estamos tentando implementar um sistema baseado em eventos usando tabelas de log e TRIGGER (s).

Basicamente, gostaríamos de criar um TRIGGER para cada tabela que queremos ser notificados para uma operação UPDATE / INSERT / DELETE. Quando esse gatilho for acionado, ele executará uma função que simplesmente anexará uma nova linha (codificando o evento) a uma tabela de log que, em seguida, pesquisaremos em um serviço externo.

Antes de abordarmos o (s) TRIGGER (s) do Postgres, gostaríamos de saber como eles escalam: quantos gatilhos podemos criar em uma única instalação do Postgres? Eles afetam o desempenho da consulta? Alguém antes tentou isso?

Ugo Matrangolo
fonte
Você pode achar útil verificar o PgQ , ele usa gatilhos C para registrar os eventos de modificação de dados.
Dezso
Ter um olhar para escutar / notificar você pode não precisar de gatilhos em tudo: postgresql.org/docs/current/static/sql-listen.html
a_horse_with_no_name

Respostas:

17

Basicamente, gostaríamos de criar um TRIGGER para cada tabela que queremos ser notificados para uma operação UPDATE / INSERT / DELETE. Quando esse gatilho for acionado, ele executará uma função que simplesmente anexará uma nova linha (codificando o evento) a uma tabela de log que, em seguida, pesquisaremos em um serviço externo.

Esse é um uso bastante padrão para um gatilho.

Antes de abordarmos o (s) TRIGGER (s) do Postgres, gostaríamos de saber como eles escalam: quantos gatilhos podemos criar em uma única instalação do Postgres?

Se você continuar criando-os, eventualmente ficará sem espaço em disco.

Não há limite específico para gatilhos.

Os limites do PostgreSQL estão documentados na página sobre .

Eles afetam o desempenho da consulta?

Depende do tipo de gatilho, idioma do gatilho e o que o gatilho faz.

Um simples BEFORE ... FOR EACH STATEMENTgatilho PL / PgSQL que não faz nada tem sobrecarga quase zero.

FOR EACH ROWgatilhos têm maior sobrecarga do que FOR EACH STATEMENTgatilhos. Dimensionar, obviamente, com a contagem de linhas afetadas.

AFTERgatilhos são mais caros do que BEFOREgatilhos, porque devem ser colocados na fila até que a instrução termine de fazer seu trabalho e depois executados. Eles não são derramados no disco se a fila ficar grande (pelo menos na 9.4 e abaixo, pode mudar no futuro), portanto, AFTERfilas enormes de acionadores podem causar a sobrecarga da memória disponível, resultando na interrupção da instrução.

Um gatilho que modifica a NEWlinha antes da inserção / atualização é mais barato que um gatilho que faz DML.

O caso de uso específico que você deseja teria melhor desempenho com um aprimoramento em andamento que pode chegar ao PostgreSQL 9.5 (se tivermos sorte), onde os FOR EACH STATEMENTgatilhos podem ver tabelas OLDe virtuais NEW. Isso não é possível nas versões atuais do PostgreSQL, portanto, você deve usar FOR EACH ROWgatilhos.

Alguém antes tentou isso?

Claro. É um uso bastante padrão para gatilhos, juntamente com auditoria, verificação de sanidade etc.

Você deve procurar LISTENe encontrar NOTIFYuma boa maneira de acordar seu trabalhador quando ocorrerem alterações na tabela de tarefas.

Você já está fazendo a coisa mais importante, evitando falar com sistemas externos diretamente a partir de gatilhos. Isso tende a ser problemático para desempenho e confiabilidade. As pessoas geralmente tentam fazer coisas como enviar email diretamente de um gatilho, e isso é uma má notícia.

Craig Ringer
fonte
1

É uma resposta um pouco tardia, mas pode ser útil para futuros leitores

Agora, dias (nas versões 10,11,12), não precisamos armazenar os mesmos dados duas vezes (no WAL pelo PG e manualmente). Podemos usar a mecânica de decodificação lógica do Postgre (o mesmo que a replicação lógica) para rastrear todas ou algumas alterações em nossos dados (ou enviar esses eventos para uma fila como kafka para analisar posteriormente)

Alexandr Latushkin
fonte