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

Анатомия игровых лагов › L12 База данных

Долго открытая транзакция Long-running transaction / MVCC purge lag

ID причины db-long-tx · Основной ответственный Команда разработки · Разработка сервера · Совместно Команда инфраструктуры · Инфраструктура БД

Открыть карточку в основной версии с иллюстрациями и экспериментами →

Если одна транзакция долго остаётся открытой, она продолжает держать блокировки, а БД не может очистить (purge) старые версии данных, и всё постепенно замедляется.

Почему Транзакция остаётся открытой, пока ждёт ответа другого сервера, или на основной БД в рабочее время идёт долгий агрегирующий запрос → Следствие Захваченные блокировки не освобождаются, старые версии данных, которые нужно удалить, продолжают копиться → На экране Таймауты в функциях, которые обращаются к этой строке, за несколько часов в целом замедляются сохранения и чтение данных

Симптомы
Задержка ввода, Съеденные действия / роллбэк
Факторы
Задержка, Остановка
У кого
Только одна функция, Весь сервер
Когда
Чем дольше без перезапуска, Изредка, случайно
Ответственные
Основной ответственный Команда разработки · Разработка сервера · Совместно Команда инфраструктуры · Инфраструктура БД
Команда разработки: задачи
Не ждать внутри транзакции сетевых вызовов и ввода пользователя, агрегирующие запросы выполнять на реплике.
Команда инфраструктуры: задачи
Настроить алерт на долго открытые транзакции и принудительно их завершать, выделить реплику для агрегации, следить за ростом undo-лога и мёртвых строк.
На графике
Плавный рост · длина undo-лога (History list length), число мёртвых строк
Где смотреть
В MySQL искать самую старую транзакцию по trx_started в INFORMATION_SCHEMA.INNODB_TRX и смотреть History list length (объём ещё не очищенного undo-лога) в секции TRANSACTIONS вывода SHOW ENGINE INNODB STATUS. В PostgreSQL смотреть xact_start в pg_stat_activity и сессии в состоянии idle in transaction, а также n_dead_tup в pg_stat_user_tables
Подтверждает
Есть транзакция возрастом от нескольких минут до нескольких часов, всё это время History list length или n_dead_tup растут, а после завершения этой транзакции очистка (purge, VACUUM) их снижает
Опровергает
Если старых транзакций нет, а в целом всё медленно, дело в контрольных точках (db-checkpoint) или в диске
Чем проверить
Инструменты инфраструктуры (игровой код не нужен)
Подробнее
Чтобы читающие видели данные в состоянии до изменения, БД хранит старые версии (MVCC). Удалить эти записи можно только после завершения самой старой транзакции, поэтому если одна транзакция открыта несколько часов, в MySQL копится undo-лог, а в PostgreSQL мёртвые строки (dead tuple), которые не может убрать VACUUM. В SQL Server журнал транзакций не сокращается и может заполнить диск.

Источники

  1. InnoDB Multi-Versioning MySQL
    Пока остаётся транзакция, которой могут понадобиться старые версии, update undo-лог нельзя удалить и rollback-сегмент растёт. Рекомендуется часто коммитить даже транзакции, которые только читают
  2. Routine Vacuuming (PostgreSQL Documentation) PostgreSQL
    Старые версии строк нельзя удалить, пока их может видеть другая транзакция, долго открытую транзакцию нужно завершить или закрыть её сессию
  3. Client Connection Defaults (PostgreSQL Documentation) PostgreSQL
    idle_in_transaction_session_timeout: обрывает сессии, которые простаивают с открытой транзакцией, чтобы они не держали блокировки долго
  4. Troubleshoot a full transaction log (SQL Server Error 9002) Microsoft SQL Server
    Долго выполняющаяся активная транзакция мешает очистке журнала транзакций
  5. The INFORMATION_SCHEMA INNODB_TRX Table MySQL
    TRX_STARTED: время начала транзакции
  6. Purge Configuration MySQL
    Purge очищает список undo-логов закоммиченных транзакций (history list), отставание показывает History list length в секции TRANSACTIONS вывода SHOW ENGINE INNODB STATUS
  7. The Cumulative Statistics System (PostgreSQL Documentation) PostgreSQL
    xact_start (время начала транзакции) и state (idle in transaction) в pg_stat_activity, n_dead_tup (оценка числа мёртвых строк) в pg_stat_user_tables

Смотрите также

Тот же слой: L12 База данных

Причины с тем же симптомом (Задержка ввода) на других слоях

Карточка в основной версии с иллюстрациями и экспериментами