---
metadata:
  - name: generator
    content: Diplodoc Platform v5.52.0
alternate:
  - https://ydb.tech/docs/en/troubleshooting/performance/queries/tli-logging.md
  - https://ydb.tech/docs/ru/troubleshooting/performance/queries/tli-logging.md
  - href: ru/troubleshooting/performance/queries/tli-logging.md
    type: text/markdown
    title: Markdown version
  - href: ../../../llms.txt
    type: text/markdown
    title: llms.txt
sourcePath: ru/core/troubleshooting/performance/queries/tli-logging.md
---
> **Documentation Index:** Fetch the complete configuration index at https://ydb.tech/docs/ru/llms.txt

# Логирование TLI

Логирование [инвалидации блокировок транзакций](https://ydb.tech/docs/ru/concepts/glossary.md#tli) (TLI) позволяет установить, у какого запроса были сломаны блокировки **(жертва)** и какой запрос их сломал **(нарушитель)**.

## Включение логирования

Для получения детальных [логов](https://ydb.tech/docs/ru/devops/observability/logging.md) о конфликтах блокировок установите уровень `INFO` (числовое значение `6`) для компонента `TLI`.

Добавьте в конфигурацию кластера:

```yaml
log_config:
  entry:
    - component: "TLI"
      level: 6  # INFO
```

Параметр `log_config` [поддерживает динамическое обновление](https://ydb.tech/docs/ru/devops/configuration-management/configuration-v1/dynamic-config.md) без перезапуска узлов.

После включения сервер записывает логи при каждой сломанной блокировке, а `VictimQuerySpanId` начинает появляться в сообщении об ошибке SDK.

{% note info %}

Базовый размер лога для одного TLI-события составляет 10–20 КБ. Фактический объем зависит от размера текста логируемых запросов (виновника и жертвы) и транзакций, частью которых они являются, поскольку все эти данные записываются в лог.
Если конфликты редки, нагрузка на логирование незначительна. При высокой частоте TLI суммарный объём логов может быть существенным.

Чтобы исключить таблицы с ожидаемыми конфликтами из TLI-диагностики, используйте параметр [`tli_config.ignored_table_regexes`](https://ydb.tech/docs/ru/reference/configuration/tli_config.md).

{% endnote %}

## Структура логов

Когда происходит 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):**

```text
Component: DataShard, TabletId: <tablet-id>,
BreakerQuerySpanId: 2222222222222222, VictimQuerySpanIds: [1111111111111111],
Message: Write transaction broke other locks
```

**Лог нарушителя (SessionActor):**

```text
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):**

```text
Component: DataShard, TabletId: <tablet-id>,
VictimQuerySpanId: 1111111111111111, CurrentQuerySpanId: 3333333333333333,
Message: Write transaction was a victim of broken locks
```

**Лог жертвы (SessionActor):**

```text
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 можно найти все связанные события:

1. **Поиск запроса-жертвы**: поле `VictimQuerySpanId` в логах жертвы показывает, какой SELECT установил сломанные блокировки, и его текст в поле `VictimQueryText`.

2. **Поиска запроса-нарушитель**: в логе нарушителя DataShard поле `VictimQuerySpanIds` содержит то же значение. Из этого лога извлекается `BreakerQuerySpanId` и находится лог SessionActor нарушителя — он содержит `BreakerQueryText` с полным текстом запроса.

3. **Получение полного контекста транзакций**: `VictimQueryTexts` и `BreakerQueryTexts` содержат все запросы соответствующих транзакций в порядке выполнения.

## Утилита find_tli_chain

Для автоматического анализа логов TLI в репозитории YDB есть утилита [find_tli_chain.py](https://github.com/ydb-platform/ydb/tree/main/ydb/tools/tli_analysis).

Данная утилита принимает на вход параметры:

- `VictimQuerySpanId` - идентификатор сломанного запроса из сообщения об ошибке SDK;
- `LogFile` - имя лог-файла для анализа логов.

Подразумевается, что логирование TLI было предварительно включено в [конфигурации](https://ydb.tech/docs/ru/reference/configuration/log_config.md), лог файлы собраны с узлов базы данных и объединены в один файл.

```bash
python3 find_tli_chain.py <VictimQuerySpanId> <LogFile>
```

**Пример:**

```bash
python3 find_tli_chain.py 1111111111111111 ydb.log
```

```text
================================================
  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` | Отключить цветной вывод |

{% note info %}

Утилита корректно обрабатывает несортированные и смешанные лог-файлы: фильтрация основана на значениях временных меток, а не на позициях строк.

{% endnote %}
