한국어English日本語简体中文繁體中文DeutschไทยTiếng ViệtРусскийPortuguês (Brasil)EspañolBahasa Indonesia

Guia do Lag em Jogos › L12 Banco de dados

Transação aberta por muito tempo Long-running transaction / MVCC purge lag

ID da causa db-long-tx · Responsável principal Desenvolvimento do servidor (Equipe de desenvolvimento) · Também envolvidos Infraestrutura de banco de dados (Equipe de infraestrutura)

Abrir o card interativo, com figuras e simulações →

Uma transação aberta por muito tempo continua segurando locks, e o BD não consegue limpar as versões antigas dos dados (purge), então tudo vai ficando mais lento.

Por quê Uma transação fica aberta enquanto espera a resposta de outro servidor, ou uma query de agregação longa roda no BD primário durante a operação → Efeito Os locks não são liberados, e as versões antigas que precisam ser limpas continuam se acumulando → Na tela Timeout nos recursos que usam aquela linha; ao longo de horas, salvamentos e consultas ficam lentos de modo geral

Sintomas
Input lag, Ação perdida / rollback
Fatores
Latência, Paralisação
Quem é afetado
Só um recurso específico, Servidor inteiro
Quando
Quanto mais tempo ligado, Aleatoriamente, de vez em quando
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)
Não esperar chamadas de rede nem input do usuário dentro de uma transação, rodar queries de agregação na réplica.
O que fazer (Equipe de infraestrutura)
Criar alerta para transações abertas por muito tempo e encerrá-las à força, oferecer uma réplica para agregações, monitorar o crescimento do undo log e das linhas mortas.
No gráfico
Subida lenta · Tamanho do undo log (History list length), linhas mortas
Onde olhar
No MySQL, achar a transação mais antiga pelo trx_started do INFORMATION_SCHEMA.INNODB_TRX e ver o History list length (undo log ainda não limpo) na seção TRANSACTIONS do SHOW ENGINE INNODB STATUS. No PostgreSQL, ver o xact_start e as sessões com state idle in transaction no pg_stat_activity, e o n_dead_tup no pg_stat_user_tables
Confirma se
Há uma transação aberta há minutos ou horas, e durante esse tempo o History list length ou o n_dead_tup sobem sem parar; depois que a transação termina e a limpeza (purge, VACUUM) roda, eles caem
Descarta se
Nenhuma transação antiga, mas tudo lento: mais provável, checkpoint (db-checkpoint) ou disco
Como verificar
Ferramentas de infra (sem precisar do código do jogo)
Saiba mais
O BD guarda versões antigas para que quem lê possa ver os dados como eram antes da alteração (MVCC). Esse histórico só pode ser apagado quando a transação mais antiga termina, então, se uma transação fica aberta por horas, acumula-se undo log no MySQL e linhas mortas (dead tuples) que o VACUUM não conseguiu limpar no PostgreSQL. No SQL Server, o log de transações não diminui e pode até encher o disco.

Fontes

  1. InnoDB Multi-Versioning MySQL
    Enquanto houver transações que podem ver versões antigas, o undo log de update não pode ser descartado e o rollback segment cresce; recomenda-se fazer commit com frequência mesmo em transações só de leitura
  2. Routine Vacuuming (PostgreSQL Documentation) PostgreSQL
    Versões antigas de linhas não podem ser apagadas enquanto outras transações puderem vê-las; transações abertas por muito tempo precisam ser finalizadas ou ter a sessão encerrada
  3. Client Connection Defaults (PostgreSQL Documentation) PostgreSQL
    idle_in_transaction_session_timeout: encerra sessões ociosas com transação aberta para que não segurem locks por muito tempo
  4. Troubleshoot a full transaction log (SQL Server Error 9002) Microsoft SQL Server
    Transações ativas de longa duração impedem a limpeza do log de transações
  5. The INFORMATION_SCHEMA INNODB_TRX Table MySQL
    TRX_STARTED: horário de início da transação
  6. Purge Configuration MySQL
    O purge limpa a lista de undo logs das transações confirmadas (history list); o volume pendente aparece como History list length na seção TRANSACTIONS do SHOW ENGINE INNODB STATUS
  7. The Cumulative Statistics System (PostgreSQL Documentation) PostgreSQL
    xact_start (início da transação) e state (idle in transaction) do pg_stat_activity, n_dead_tup (estimativa de linhas mortas) do pg_stat_user_tables

Veja também

Mesma camada: L12 Banco de dados

Mesmo sintoma (Input lag) em outras camadas

Ver o card interativo, com figuras e simulações