Transacciones abiertas durante mucho tiempo Long-running transaction / MVCC purge lag
ID de la causa db-long-tx · Responsable principal Desarrollo de servidor (Equipo de desarrollo) · También Infraestructura de BD (Equipo de infraestructura)
Si una transacción permanece abierta mucho tiempo, sigue reteniendo sus bloqueos y la BD no puede limpiar (purge) las versiones antiguas de los datos, así que todo se vuelve cada vez más lento.
Por qué Se espera la respuesta de otro servidor con la transacción abierta, o se ejecuta en producción una consulta de agregación larga en la BD principal → Efecto Los bloqueos retenidos no se liberan y las versiones antiguas pendientes de limpieza se siguen acumulando → En pantalla Timeouts en las funciones que usan esas filas; guardados y consultas cada vez más lentos en general a lo largo de varias horas
Cuanto más tiempo lleva encendido, De vez en cuando, al azar
Responsable
Responsable principal Desarrollo de servidor (Equipo de desarrollo) · También Infraestructura de BD (Equipo de infraestructura)
Tareas (Equipo de desarrollo)
No esperar llamadas de red ni respuestas del usuario dentro de una transacción, hacer las consultas de agregación en una réplica.
Tareas (Equipo de infraestructura)
Configurar alertas y cierre forzado para las transacciones abiertas demasiado tiempo, ofrecer una réplica para agregaciones, vigilar el crecimiento del undo log y de las filas muertas.
En el gráfico
Subida gradual · Longitud del undo log (History list length), número de filas muertas
Dónde mirar
En MySQL, buscar la transacción más antigua con trx_started de INFORMATION_SCHEMA.INNODB_TRX y revisar History list length (cantidad de undo log aún sin limpiar) en la sección TRANSACTIONS de SHOW ENGINE INNODB STATUS. En PostgreSQL, xact_start de pg_stat_activity y las sesiones con state idle in transaction, y n_dead_tup de pg_stat_user_tables
Se confirma si
Hay una transacción de minutos u horas de antigüedad; mientras tanto History list length o n_dead_tup no paran de subir, y bajan cuando se termina esa transacción y se ejecuta la limpieza (purge, VACUUM)
Se descarta si
Si no hay transacciones antiguas y todo va lento en general, apunta a checkpoints (db-checkpoint) o al disco
Se verifica con
Con herramientas de infraestructura (no hace falta código del juego)
Para saber más
La BD conserva versiones antiguas para que quien lee pueda ver los datos como estaban antes de modificarse (MVCC). Este registro solo se puede borrar cuando termina la transacción más antigua, así que si una transacción queda abierta varias horas, en MySQL se acumula el undo log y en PostgreSQL las filas muertas (dead tuples) que VACUUM no pudo limpiar. En SQL Server, el log de transacciones no se reduce y puede llegar a llenar el disco.
Fuentes
InnoDB Multi-VersioningMySQL Mientras quede una transacción que pueda ver versiones antiguas, no se puede descartar el undo log de update y el segmento de rollback crece; se recomienda hacer commit a menudo incluso en las transacciones de solo lectura
Routine Vacuuming (PostgreSQL Documentation)PostgreSQL Las versiones antiguas de las filas no se pueden borrar mientras otras transacciones puedan verlas; las transacciones abiertas mucho tiempo hay que terminarlas o cerrar la sesión
Purge ConfigurationMySQL Purge limpia la lista de undo logs de las transacciones confirmadas (history list); lo pendiente aparece como History list length en la sección TRANSACTIONS de SHOW ENGINE INNODB STATUS