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

Libro blanco del lag en juegos › L12 Base de datos

Contención de bloqueos en una fila caliente Hot row lock contention

ID de la causa db-hot-row · Responsable principal Desarrollo de servidor (Equipo de desarrollo) · También Infraestructura de BD (Equipo de infraestructura)

Abrir la ficha interactiva con gráficos y simulaciones →

Si todos intentan modificar la misma fila (el almacén del gremio, un objeto popular de la casa de subastas, un contador global del servidor), el bloqueo solo lo consigue uno cada vez.

Por qué Un evento o un objeto popular concentra las modificaciones en la misma fila → Efecto Las solicitudes esperan hasta conseguir el bloqueo → En pantalla Intercambios fallidos, “Inténtalo de nuevo más tarde”, timeouts

Síntomas
Acción perdida / rollback, Input lag
Factores
Detención, Latencia
A quién afecta
Solo una función
Cuándo
Cuando se junta mucha gente
Responsable
Responsable principal Desarrollo de servidor (Equipo de desarrollo) · También Infraestructura de BD (Equipo de infraestructura)
Tareas (Equipo de desarrollo)
Dividir la fila (contadores fragmentados), acortar las transacciones, acumular los cambios en memoria y aplicarlos de una vez.
Tareas (Equipo de infraestructura)
Monitorear el tiempo y el número de esperas por bloqueo de fila para localizar las filas con más contención y compartirlas.
Cifras de referencia
Si cada solicitud retiene el bloqueo 10 ms, esa fila solo se puede modificar como máximo 100 veces por segundo. Si dentro de la transacción hay idas y vueltas a otros servidores, la cifra baja todavía más.
En el gráfico
Sube con la carga · Número y tiempo de esperas por bloqueo de fila
Dónde mirar
En MySQL, el incremento de Innodb_row_lock_waits e Innodb_row_lock_time, Innodb_row_lock_current_waits, y sys.innodb_lock_waits para ver quién espera a quién. En PostgreSQL, las sesiones de pg_stat_activity con wait_event_type Lock y las solicitudes de pg_locks con granted en false; con log_lock_waits activado (desactivado por defecto), los bloqueos con esperas largas quedan en el log
Se confirma si
Las esperas por bloqueo crecen con fuerza al ritmo de los eventos y del número de jugadores, y la mayoría de las solicitudes en espera apuntan a la misma fila (la misma clave) de la misma tabla
Se descarta si
Si las esperas están repartidas por igual entre muchas tablas y filas, apunta a saturación de disco o CPU. Si una sesión retiene un bloqueo mucho tiempo sin soltarlo: transacciones abiertas durante mucho tiempo (db-long-tx)
Se verifica con
Con herramientas de infraestructura (no hace falta código del juego)

Fuentes

  1. InnoDB Locking MySQL
    Cuando una transacción bloquea una fila (registro de índice), las demás transacciones no pueden modificarla y esperan
  2. How to Minimize and Handle Deadlocks MySQL
    Recomendación de mantener las transacciones pequeñas y cortas, y de hacer commit justo después de los cambios relacionados para reducir los conflictos
  3. Server Status Variables MySQL
    Innodb_row_lock_waits e Innodb_row_lock_time dan el número y el tiempo de las esperas por bloqueo de fila; Innodb_row_lock_current_waits, cuántas hay en este momento
  4. The innodb_lock_waits and x$innodb_lock_waits Views MySQL
    La consulta que espera (waiting_query), la sesión que bloquea (blocking_pid) y el tiempo de espera (wait_age)
  5. The Cumulative Statistics System (PostgreSQL Documentation) PostgreSQL
    wait_event_type de pg_stat_activity: si es Lock, la sesión está esperando un bloqueo pesado (heavyweight lock)
  6. pg_locks (PostgreSQL Documentation) PostgreSQL
    Si granted es false, ese proceso está esperando para conseguir el bloqueo
  7. Error Reporting and Logging (PostgreSQL Documentation) PostgreSQL
    log_lock_waits: registra en el log las esperas por bloqueo que superan deadlock_timeout; desactivado por defecto

Ver también

Misma capa: L12 Base de datos

Causas de otras capas con el mismo síntoma (Acción perdida / rollback)

Ver la ficha interactiva con gráficos y simulaciones