Tenho um processo que insere registros em uma tabela.
A tabela é definida com um gatilho como este...
CREATE TRIGGER myTrig AFTER INSERT ON myTable FOR EACH ROW EXECUTE PROCEDURE myProcedure();
O processo que faz o INSERT
myTable está fora do meu controle, basicamente apenas despeja registros na tabela ao longo do dia 24 horas por dia, 7 dias por semana.
A funcionalidade myProcedure()
requer recursos de banco de dados. Durante os períodos de maior movimento, a taxa de chegada dos registros é maior do que o banco de dados pode suportar (cerca de 500 registros por segundo é o limite). Se eu desabilitar o gatilho usando ALTER TABLE myTable DISABLE TRIGGER myTrig
, o sistema pode lidar com talvez 1.000 registros por segundo.
Posso então reativar o gatilho quando o sistema não estiver tão ocupado, mas obviamente os registros adicionados enquanto o gatilho estava desativado não foram processados corretamente.
Existe alguma maneira de executar novamente o gatilho nos registros selecionados JÁ na tabela?
Meu melhor palpite atual é que, durante os períodos de maior movimento, devo desviar os registros recebidos para uma cópia myTable
idêntica ao original (mas sem o acionador) e, quando o sistema se acalmar mais tarde, posso inserir da cópia, de volta ao original, onde eles devem ser processados pelo gatilho (embora mais tarde do que deveriam)
Uma função de gatilho requer a ação de gatilho. Quando acionado
FOR EACH ROW
, também normalmente precisa da linha de acionamento como entrada. Mas uma função simples pode reproduzir quase tudo que uma função de gatilho faz.O melhor curso de ação depende se a função de gatilho
myProcedure()
altera a própria linha inserida .Nesse caso , sua ideia com uma mesa de preparação separada parece boa. Um posterior
UPDATE
escreveria uma nova versão de linha de qualquer maneira. Portanto, em geral, é eficiente gravar primeiro em uma tabela de preparação eINSERT
depois na tabela de destino. Se for aceitável perder dados em caso de falha do servidor, você pode até usar umaUNLOGGED
tabela para isso e lidar com ainda mais linhas por segundo.O eventual
INSERT
para a mesa principal também disparará o gatilho, tudo feito.Caso contrário (e se uma
UNLOGGED
tabela não for uma opção), eu escreveria diretamente na tabela de destino. Tudo o que a função de gatilho faz agora pode ser reproduzido com uma função simples. Se você não puder duplicar a funcionalidade da função de gatilho, a próxima melhor ideia seria gravar em uma cópia demyTable
, com o mesmo gatilho. Apenas faça issoRETURN NULL;
em vez deRETURN NEW;
pular a própria linha de acionamento. (Portanto, nada é gravado na cópia.)Se você não puder ou não quiser fazer uma cópia modificada da função do gatilho, como alternativa, adicione outro gatilho na tabela temporária como esta:
Isso também ignora a própria inserção de acionamento. Mas tudo o que é executado a
myProcedure()
partir do gatilho anterior ainda permanece.O manual: