Fernando,

> A princípio nada mudou na aplicação e temos tido o mesmo volume de
> demanda então fiquei realmente surpreso.

_Talvez_ o volume de dados nas tabelas ou algum índice criado recentemente
tenha feito o otimizador mudar o plano de alguma consulta ou atualização,
tornando-a mais lenta.

> Recebo mensagem como esta abaixo no log ao mesmo tempo que o load do
> servidor salta de 0.90 para 4.xx e daí pra frente só piora:

Aumentar demais o tempo para o servidor conferir se houve deadlock só vai
fazer as outras conexões esperarem à toa. O valor padrão (1 segundo) me
parece bem sensato, e para melhorar o desempenho das operações que não
sofrem deadlocks eu sugiro que você teste um valor ainda *menor*. 

> Recorrendo à documentação vi que a checagem por deadlock pode degradar
> um pouco a performance. Resolvi alterar de 1.000 para 10.000 o
> deadlock_timeout para não ter checagens "desnecessárias" por
> deadlocks, mas também tenho receio de tornar ela insensível quando for
> realmente necessária.

O custo de checar se há um deadlock pode até ser considerável, porém é
*completamente desprezível* comparado ao tempo que os usuários ficam
esperando o servidor se dar ao trabalho de conferir. Se ocorrem deadlocks,
quanto menos tempo as transações ficarem travadas esperando o servidor matar
uma delas, melhor.

> Gostaria de saber se vocês tem alguma outra recomendação, pois mesmo
> assim ainda continuo com problemas, quando começo a passar de 5
> clientes conectados começam a surgir os deadlocks, sendo que até ontem
> (com deadlock_timeout =1000 inclusive) esse servidor segurava 20 e
> poucos clientes.

Minha sugestão de checklist:
1. Indentifique o processo (transação da aplicação) e tabela que sofreram
deadlock. Veja quais usuários e processos são envolvidos nos deadlocks e
tente estabelecer um padrão (sempre a mesma tabela, sempre os mesmos
processos);
2. Sabendo *o processo (transação)* que causa deadlock, verifique se há
outros processos gravando nas mesmas tabelas e garanta que a ordem em que as
tabelas são atualizadas dentro de uma transação é sempre a mesma. Isso
não é solução para todos os casos, mas ajuda *bastante*;
3. Sabendo qual *tabela* tem deadlocks frequentes:
3.1. Verifique se não há consultas excessivamente demoradas sobre essa
tabela que possam ser resolvidas *adicionando* índices. Dê especial
atenção a chaves estrangeiras em tabelas pais e filhas, que podem tornar
atualizações e exclusões muito lentas e potencializar a probabilidade de
deadlocks. Índices suficientes podem tornar suas transações curtas o
bastante para haver mínima concorrência, reduzindo drasticamente a chance de
um deadlock;
3.2. Se *adicionar* índices não adiantar, o jeito é *remover* os que você
usa com menos frequência ou aqueles que, mesmo usados, não melhoram muito o
desempenho. Um jeito simples de fazer isso é: remova *todos* os índices da
tabela e depois adicione, um a um, os índices estritamente necessários para
que sua aplicação funcione decentemente para um ou dois usuários.
4. Se nada disso adiantar, o jeito é enumerar pacientemente a lista de
comandos dentro de cada transação e processo da sua aplicação e procurar
por consultas inúteis (que poderiam ser colocadas antes ou depois do begin
transaction..commit) ou atualizações redundantes (dois UPDATEs sobre o mesmo
registro, sendo ou não sobre os mesmos campos, dentro da mesma transação).

Sem a estrutura das tabelas e comandos envolvidos nas suas transações, é o
que dá para sugerir.

Atenciosamente,

Mozart Hasse


_______________________________________________
pgbr-geral mailing list
[email protected]
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral

Responder a