ID da causa db-deadlock · Responsável principal Desenvolvimento do servidor (Equipe de desenvolvimento) · Também envolvidos Infraestrutura de banco de dados (Equipe de infraestrutura)
Quando duas transações (operações do BD processadas como um bloco único) esperam, cada uma, pela linha em que a outra pôs lock, o BD cancela uma delas à força.
Por quê A troca A pega os locks na ordem item→moeda, e a B na ordem moeda→item → Efeito O BD detecta o deadlock e faz rollback de um dos lados → Na tela Trocas e crafting falham de vez em quando, e itens voltam
Quando junta muita gente, Ao fazer ações específicas
Responsável
Responsável principal Desenvolvimento do servidor (Equipe de desenvolvimento) · Também envolvidos Infraestrutura de banco de dados (Equipe de infraestrutura)
O que fazer (Equipe de desenvolvimento)
Padronizar a ordem dos locks, manter as transações curtas, repetir automaticamente em caso de falha.
O que fazer (Equipe de infraestrutura)
Manter a detecção de deadlock ligada, coletar e compartilhar os registros de deadlock, reduzir o limite de espera por lock (padrão de 50 s) nos servidores MySQL com a detecção desligada.
Números de referência
A detecção é quase imediata no MySQL (InnoDB), leva 1 s por padrão no PostgreSQL e até cerca de 5 s no SQL Server. Enquanto isso, as duas requisições ficam paradas. Em servidores MySQL com a detecção desligada por causa de concorrência muito alta, a espera vai até o limite de espera por lock (padrão de 50 s).
No gráfico
Picos aleatórios · Número de deadlocks, falhas de troca
Onde olhar
No MySQL, ver o LATEST DETECTED DEADLOCK do SHOW ENGINE INNODB STATUS (só o mais recente, 1 registro), todos os deadlocks gravados no log de erros com innodb_print_all_deadlocks ativado e o lock_deadlocks do INFORMATION_SCHEMA.INNODB_METRICS. No PostgreSQL, ver deadlocks em pg_stat_database; no SQL Server, o xml_deadlock_report da sessão system_health, ativa por padrão. Códigos de erro do lado do servidor do jogo: MySQL 1213, PostgreSQL 40P01, SQL Server 1205
Confirma se
O número de deadlocks sobe nos horários das falhas de troca e crafting, e as duas transações registradas põem lock nas mesmas tabelas em ordens opostas
Descarta se
Número de deadlocks estável, mas com falhas: estouro do limite de espera por lock (erro 1205 do MySQL) ou hot row (db-hot-row)
Como verificar
Ferramentas de infra (sem precisar do código do jogo)
Fontes
InnoDB Startup Options and System VariablesMySQL Com a detecção ligada (padrão), o InnoDB detecta o deadlock na hora e faz rollback; innodb_lock_wait_timeout com padrão de 50 segundos
Deadlock DetectionMySQL Com concorrência muito alta, a própria detecção pode ficar lenta; às vezes ela é desligada, e o limite de espera por lock assume o papel
Lock Management (PostgreSQL Documentation)PostgreSQL deadlock_timeout com padrão de 1 segundo: só depois de esperar esse tempo pelo lock é feita a verificação de deadlock
Deadlocks guideMicrosoft SQL Server Intervalo padrão de verificação de deadlock de 5 segundos, que cai até 100 ms se os deadlocks forem frequentes; a sessão system_health, ativa por padrão, coleta o xml_deadlock_report; o lado sacrificado recebe o erro 1205
How to Minimize and Handle DeadlocksMySQL Alterar várias linhas e tabelas sempre na mesma ordem, tentar de novo em caso de falha, registrar todos os deadlocks com innodb_print_all_deadlocks
InnoDB Standard Monitor and Lock Monitor OutputMySQL LATEST DETECTED DEADLOCK: as duas transações do deadlock mais recente, os locks que seguravam e os que esperavam, e o lado que sofreu rollback