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

Guia do Lag em Jogos › L12 Banco de dados

Lock de alteração de schema (DDL) em produção Schema change lock (DDL / metadata lock)

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

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

Adicionar uma coluna ou um índice a uma tabela com o jogo no ar exige um lock por um instante, e só esse lock pode deixar esperando todas as requisições que usam a tabela.

Por quê Um hotfix adiciona coluna ou índice a uma tabela em produção → Efeito A alteração de schema espera uma transação longa aberta antes dela, e todas as requisições seguintes esperam a alteração de schema → Na tela Os recursos que usam essa tabela (inventário, correio etc.) param por inteiro e dão timeout

Sintomas
Input lag, Ação perdida / rollback, Não conecta / loading infinito
Fatores
Paralisação
Quem é afetado
Só um recurso específico, Servidor inteiro
Quando
Aleatoriamente, de vez em quando, Logo após login ou manutenção
Responsável
Responsável principal Infraestrutura de banco de dados (Equipe de infraestrutura) · Também envolvidos Desenvolvimento do servidor (Equipe de desenvolvimento)
O que fazer (Equipe de desenvolvimento)
Combinar com a infraestrutura de banco de dados o horário dos hotfixes que alteram o schema, fazer primeiro o deploy de um código que funcione mesmo sem a coluna nova.
O que fazer (Equipe de infraestrutura)
Definir um limite curto de espera por lock e tentar de novo se falhar, executar quando não houver transações longas, usar ferramentas de alteração online, deixar tabelas grandes para a janela de manutenção.
No gráfico
Degrau a partir de um momento · Sessões esperando lock, latência das queries daquela tabela
Onde olhar
No MySQL, contar no SHOW PROCESSLIST as sessões com State Waiting for table metadata lock e achar a sessão que está bloqueando (blocking_pid) com sys.schema_table_lock_waits. No PostgreSQL, ver no pg_locks as requisições com granted em false e os AccessExclusiveLock, e achar a sessão que está bloqueando com pg_blocking_pids()
Confirma se
A partir do horário em que a alteração de schema começou, todas as queries que usam aquela tabela se acumulam esperando lock, e na frente da fila há uma transação não terminada ou o próprio comando de alteração de schema
Descarta se
Espera concentrada em linhas específicas, com as outras linhas da mesma tabela processadas normalmente: hot row (db-hot-row)
Como verificar
Ferramentas de infra (sem precisar do código do jogo)
Saiba mais
Ao alterar o schema, o MySQL segura por um instante um metadata lock, e o PostgreSQL, o lock de tabela mais forte. Mesmo que a alteração em si seja instantânea, se houver na frente uma transação que ainda não terminou, todas as requisições seguintes ficam esperando.

Fontes

  1. Online DDL Performance and Concurrency MySQL
    Mesmo o DDL online precisa de um metadata lock exclusivo por um instante no final; se houver uma transação longa, ele espera, e o pedido de lock em espera bloqueia todas as transações seguintes
  2. Server System Variables MySQL
    lock_wait_timeout: limite de espera por metadata lock, padrão de 31.536.000 segundos (1 ano)
  3. ALTER TABLE (PostgreSQL Documentation) PostgreSQL
    ALTER TABLE sem especificação em contrário pega o lock mais forte, ACCESS EXCLUSIVE
  4. Client Connection Defaults (PostgreSQL Documentation) PostgreSQL
    lock_timeout: interrompe o comando se a espera pelo lock passar desse tempo
  5. General Thread States MySQL
    Waiting for table metadata lock: estado da thread que espera um metadata lock
  6. The schema_table_lock_waits and x$schema_table_lock_waits Views MySQL
    Sessão que espera o metadata lock (waiting_query) e sessão que está bloqueando (blocking_pid)
  7. pg_locks (PostgreSQL Documentation) PostgreSQL
    granted em false indica espera pelo lock; mode mostra o tipo de lock, como AccessExclusiveLock
  8. System Information Functions and Operators (PostgreSQL Documentation) PostgreSQL
    pg_blocking_pids(): lista das sessões que impedem a sessão indicada de obter o lock

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