Eu tenho duas tabelas: "machines" e "magictools". "magictools" refere-se a "máquinas" com uma chave estrangeira.
Eu enfrento um problema de deadlock ao executar muitas dessas solicitações:
//this will produce an "AccessExclusiveLock" of type "tuple" on machines
SELECT FROM * machines FOR UPDATE where id = :id;
//this will produce a "RowExclusiveLock" on magictools and a "RowShareLock" on machines
UPDATE magictools SET collections = "large-json" where id = :id
Até onde eu entendi, executar muitas dessas solicitações produz deadlocks. Talvez sejam apenas as atualizações que estão realizando isso, não sei. Como devo evitar os impasses neste caso?
Eu tenho muitos índices nessas tabelas, talvez eu tenha muitos índices?
Abaixo está o relatório do pg_activity quando o problema aconteceu. Eu não entendo os diferentes modos e tipos de bloqueio e, apenas, o que acontece aqui? É possível que apenas uma atualização sem nenhuma transação cause um deadlock?
Não há determinismo
ORDER BY
em:Portanto, várias transações podem tentar obter bloqueios de linha em ordem e intertravamento diferentes (arbitrários).
Além disso, por que você bloquearia a tabela inteira
machines
para uma única atualização emmagictools
? Se for realmente um únicoUPDATE
pormagictools
transação, não há necessidade de bloquearmachines
as linhas manualmente. Basta soltar o comando. (Se houver vários, sua pergunta está faltando.)Se houver um bom motivo para bloquear muitas ou todas as linhas em
machines
, faça-o em ordem determinística, como:Ou bloqueie a mesa inteira, também é mais barato:
SHARE MODE
é suficiente para o caso FK que você tem. Existe até um exemplo no manual sugerindo isso.Bloquear a tabela também não permite
INSERT
, é claro, ao contrário dos bloqueios de nível de linha em seu exemplo.