Логирование TLI
Логирование инвалидации блокировок транзакций (TLI) позволяет установить, у какого запроса были сломаны блокировки (жертва) и какой запрос их сломал (нарушитель).
Включение логирования
Для получения детальных логов о конфликтах блокировок установите уровень INFO (числовое значение 6) для компонента TLI.
Добавьте в конфигурацию кластера:
log_config:
entry:
- component: "TLI"
level: 6 # INFO
Параметр log_config поддерживает динамическое обновление без перезапуска узлов.
После включения сервер записывает логи при каждой сломанной блокировке, а VictimQuerySpanId начинает появляться в сообщении об ошибке SDK.
Примечание
Базовый размер лога для одного TLI-события составляет 10–20 КБ. Фактический объем зависит от размера текста логируемых запросов (виновника и жертвы) и транзакций, частью которых они являются, поскольку все эти данные записываются в лог.
Если конфликты редки, нагрузка на логирование незначительна. При высокой частоте TLI суммарный объём логов может быть существенным.
Чтобы исключить таблицы с ожидаемыми конфликтами из TLI-диагностики, используйте параметр tli_config.ignored_table_regexes.
Структура логов
Когда происходит TLI, сервер записывает четыре записи — по одной от каждого компонента для каждой из сторон конфликта.
Пример сценария:
Устанавливается две сессии к СУБД: жертва и нарушитель.
| Время | QuerySpanId | Роль | Запрос |
|---|---|---|---|
| T1 | 1111111111111111 |
Жертва | SELECT * FROM Orders WHERE OrderId = 42 (устанавливает блокировку) |
| T2 | 2222222222222222 |
Нарушитель | UPDATE Orders SET Status = 'done' WHERE OrderId = 42 (ломает блокировку) |
| T3 | 3333333333333333 |
Жертва | UPDATE Orders SET Amount = 100 WHERE OrderId = 42 (коммит — падает) |
Лог нарушителя (DataShard):
Component: DataShard, TabletId: <tablet-id>,
BreakerQuerySpanId: 2222222222222222, VictimQuerySpanIds: [1111111111111111],
Message: Write transaction broke other locks
Лог нарушителя (SessionActor):
Component: SessionActor, Message: Query had broken other locks,
BreakerQuerySpanId: 2222222222222222,
BreakerQueryText: UPDATE Orders SET Status = 'done' WHERE OrderId = 42,
BreakerQueryTexts: [QuerySpanId=2222222222222222 QueryText=UPDATE Orders SET Status = 'done' WHERE OrderId = 42]
Лог жертвы (DataShard):
Component: DataShard, TabletId: <tablet-id>,
VictimQuerySpanId: 1111111111111111, CurrentQuerySpanId: 3333333333333333,
Message: Write transaction was a victim of broken locks
Лог жертвы (SessionActor):
Component: SessionActor, Message: Query was a victim of broken locks,
VictimQuerySpanId: 1111111111111111, CurrentQuerySpanId: 3333333333333333,
VictimQueryText: SELECT * FROM Orders WHERE OrderId = 42,
VictimQueryTexts: [QuerySpanId=1111111111111111 QueryText=SELECT * FROM Orders WHERE OrderId = 42 |
QuerySpanId=3333333333333333 QueryText=UPDATE Orders SET Amount = 100 WHERE OrderId = 42]
Поля логов
| Поле | Описание | Где встречается |
|---|---|---|
VictimQuerySpanId |
Идентификатор запроса, чьи блокировки были сломаны | Логи жертвы |
BreakerQuerySpanId |
Идентификатор запроса, который сломал блокировки | Логи нарушителя |
CurrentQuerySpanId |
Идентификатор запроса в момент ошибки (может отличаться от жертвы) | Логи жертвы |
VictimQuerySpanIds |
Массив идентификаторов всех запросов-жертв | Логи нарушителя DataShard |
VictimQueryText |
SQL запроса-жертвы, который установил блокировки | Логи жертвы SessionActor |
BreakerQueryText |
SQL запроса-нарушителя | Логи нарушителя SessionActor |
VictimQueryTexts |
Все запросы транзакции-жертвы | Логи жертвы SessionActor |
BreakerQueryTexts |
Все запросы транзакции-нарушителя | Логи нарушителя SessionActor |
Анализ логов
По VictimQuerySpanId из сообщения об ошибке SDK можно найти все связанные события:
-
Поиск запроса-жертвы: поле
VictimQuerySpanIdв логах жертвы показывает, какой SELECT установил сломанные блокировки, и его текст в полеVictimQueryText. -
Поиска запроса-нарушитель: в логе нарушителя DataShard поле
VictimQuerySpanIdsсодержит то же значение. Из этого лога извлекаетсяBreakerQuerySpanIdи находится лог SessionActor нарушителя — он содержитBreakerQueryTextс полным текстом запроса. -
Получение полного контекста транзакций:
VictimQueryTextsиBreakerQueryTextsсодержат все запросы соответствующих транзакций в порядке выполнения.
Утилита find_tli_chain
Для автоматического анализа логов TLI в репозитории YDB есть утилита find_tli_chain.py.
Данная утилита принимает на вход параметры:
VictimQuerySpanId- идентификатор сломанного запроса из сообщения об ошибке SDK;LogFile- имя лог-файла для анализа логов.
Подразумевается, что логирование TLI было предварительно включено в конфигурации, лог файлы собраны с узлов базы данных и объединены в один файл.
python3 find_tli_chain.py <VictimQuerySpanId> <LogFile>
Пример:
python3 find_tli_chain.py 1111111111111111 ydb.log
================================================
TLI Chain
================================================
VictimQuerySpanId: 1111111111111111
VictimQueryText: SELECT * FROM Orders WHERE OrderId = 42
BreakerQuerySpanId: 2222222222222222
BreakerQueryText: UPDATE Orders SET Status = 'done' WHERE OrderId = 42
================================================
VictimTx
================================================
SELECT * FROM Orders WHERE OrderId = 42
UPDATE Orders SET Amount = 100 WHERE OrderId = 42
================================================
BreakerTx
================================================
UPDATE Orders SET Status = 'done' WHERE OrderId = 42
Утилита выводит:
- TLI Chain —
VictimQuerySpanId,VictimQueryText,BreakerQuerySpanId,BreakerQueryText; - VictimTx — все запросы транзакции-жертвы в порядке выполнения;
- BreakerTx — все запросы транзакции-нарушителя.
Дополнительные параметры:
| Параметр | Описание |
|---|---|
--window-sec N |
Временное окно поиска вокруг события (по умолчанию 10 с) |
--no-color |
Отключить цветной вывод |
Примечание
Утилита корректно обрабатывает несортированные и смешанные лог-файлы: фильтрация основана на значениях временных меток, а не на позициях строк.