Как настроить технологический журнал 1С для анализа блокировок и почему при ошибке SQL Server нет событий TTIMEOUT?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

В процессе администрирования и оптимизации крупных информационных систем на платформе 1С:Предприятие специалисты часто сталкиваются с проблемами производительности, вызванными блокировками. Основным инструментом для их расследования является технологический журнал (ТЖ) 1С. Однако при его базовой настройке легко совершить ошибки: либо перегрузить дисковую подсистему избыточным логированием, либо упустить критически важные данные.

В этой статье мы подробно разберем, как правильно составить конфигурационный файл технологического журнала, проанализируем поведение системы при различных типах таймаутов, выясним причину отсутствия событий TTIMEOUT при блокировках СУБД и соберем оптимальный «джентльменский набор» настроек для постоянного использования на рабочем сервере.

---

Почему при ошибке SQL Server (native=1222) отсутствуют события TTIMEOUT?

Рассмотрим ситуацию, с которой часто сталкиваются администраторы 1С (описанную в сообщении 10 форума): при возникновении ошибки превышения времени ожидания блокировки в технологическом журнале фиксируется только событие EXCP с текстом:

«Конфликт блокировок при выполнении транзакции: Microsoft SQL Server Native Client: Превышено время ожидания запроса на блокировку... native=1222»

При этом специализированные события TTIMEOUT, настроенные для отслеживания таймаутов, в логах полностью отсутствуют. Чтобы понять, почему так происходит, проанализируем разницу между двумя принципиально разными механизмами блокировок в 1С:

  1. Управляемые блокировки (уровень платформы 1С). Когда транзакция на сервере 1С пытается наложить управляемую блокировку на какой-либо объект, этот запрос обрабатывается внутренним менеджером блокировок кластера 1С. Если требуемый ресурс уже заблокирован другим сеансом, текущий сеанс переходит в режим ожидания. Если время ожидания превышает значение, заданное в конфигураторе (свойство «Время ожидания блокировки данных», по умолчанию 20 секунд), платформа принудительно прерывает операцию и генерирует событие TTIMEOUT. В этом случае в логах ТЖ все прозрачно: фиксируется жертва, виновник и контекст кода 1С.
  2. Транзакционные блокировки на уровне СУБД (например, MS SQL Server). Когда рабочий процесс 1С (rphost) отправляет SQL-запрос к базе данных, СУБД пытается наложить собственные блокировки на таблицы или строки СУБД. Если СУБД обнаруживает конфликт (например, другая транзакция изменяет те же строки), она приостанавливает выполнение SQL-запроса от 1С. Для платформы 1С в этот момент процесс просто находится в ожидании ответа по сети от СУБД. Платформа не «знает», что внутри MS SQL Server происходит конфликт блокировок. Когда на уровне СУБД истекает таймаут ожидания блокировки (в 1С для MS SQL Server при подключении устанавливается таймаут в 20 секунд), СУБД возвращает клиенту критическую ошибку с кодом native=1222. Платформа воспринимает это как стандартный сбой СУБД и генерирует исключение EXCP. Событие TTIMEOUT при этом не регистрируется, так как менеджер управляемых блокировок 1С не контролировал этот процесс.

Таким образом, для расследования блокировок на уровне СУБД стандартных настроек ТЖ, ориентированных только на управляемые блокировки, недостаточно. Требуется настроить сбор событий СУБД и правильно связать их с контекстом исполнения кода 1С.

---

Анализ и критика типовых шаблонов технологического журнала

Рассмотрим популярные варианты настроек ТЖ, которые часто используются администраторами, и разберем их слабые и сильные стороны.

Вариант 1. Шаблон со сбором DBMSSQL по фильтру lkp

В первом сообщении темы представлен шаблон, ориентированный на раздельный сбор логов:


<?xml version="1.0" encoding="UTF-8"?>
<ns:config xmlns:ns="http://v8.1c.ru/v8/tech-log">
    <ns:log history="48" location="D:\1C_log\Base1C\SQLlocks">
        <ns:event>
            <ns:eq property="Name" value="DBMSSQL"/>
            <ns:eq property="p:processName" value="Base1C"/>
            <ns:eq property="lkp" value="1"/>
        </ns:event>
        <ns:property name="p:processName"/>
        <ns:property name="Context"/>
        <ns:property name="Sql"/>
        <ns:property name="lkp"/>
        <!-- Остальные свойства -->
    </ns:log>
</ns:config>

Анализ настройки: Это грамотный подход для отслеживания проблем на стороне СУБД. Свойство lkp (Lock Postponed) принимает значение 1, когда SQL-запрос не может быть выполнен немедленно и встает в очередь ожидания блокировки на уровне СУБД. Фильтрация по этому свойству позволяет отсечь миллиарды быстрых и успешных запросов, записывая в ТЖ только те обращения к СУБД, которые реально испытывали проблемы с параллельным доступом.

Минус: Использование пространства имен ns: в тегах XML может приводить к сбоям чтения конфигурации на некоторых релизах платформы. Рекомендуется использовать стандартный синтаксис без префиксов.

Вариант 2. Шаблон тотального сбора управляемых блокировок

Часто в статьях встречается рекомендация собирать события TLOCK следующим образом:


<event>
    <eq property="Name" value="TLOCK"/>
</event>
<property name="all"/>

Критика настройки: Сбор события TLOCK в чистом виде без дополнительных фильтров на продуктивной базе с активной работой пользователей гарантированно приведет к деградации производительности сервера. Событие TLOCK регистрирует каждую установку управляемой блокировки, даже если она прошла мгновенно за микросекунду. За несколько часов работы лог разрастется до сотен гигабайт, забив дисковую систему операциями записи.

Вариант 3. Шаблон «Включить всё» для быстрой диагностики

В сообщении 4 предлагается радикальный шаблон:


<log history="72" location="C:\Program Files\1cv8\log">
    <event>
        <ne property="Name" value=""/>
    </event>
    <property name="all"/>
</log>

Критика настройки: Этот шаблон собирает абсолютно все события технологического журнала. Как справедливо отмечает автор сообщения, включать такую настройку на продуктивном сервере можно не более чем на 3-5 минут для локального выявления плавающей проблемы. Постоянная работа ТЖ в таком режиме вызовет полный отказ дисковой подсистемы сервера приложений 1С.

---

Оптимальный «джентльменский набор» настроек технологического журнала

Для того чтобы иметь возможность расследовать как управляемые блокировки, так и блокировки СУБД, не снижая производительность сервера и экономя место на жестком диске, мы рекомендуем использовать оптимизированный шаблон logcfg.xml. Рассмотрим его структуру:


<?xml version="1.0" encoding="UTF-8"?>
<config xmlns="http://v8.1c.ru/v8/tech-log">
    
    <!-- Основной лог для сбора критических ошибок и блокировок -->
    <log history="48" location="D:\1C_log\LocksAndExceptions">
        
        <!-- Фиксируем все исключения (включая ошибки СУБД native=1222) -->
        <event>
            <eq property="Name" value="EXCP"/>
        </event>
        
        <!-- Фиксируем таймауты и взаимоблокировки управляемых блокировок -->
        <event>
            <eq property="Name" value="TTIMEOUT"/>
        </event>
        <event>
            <eq property="Name" value="TDEADLOCK"/>
        </event>
        
        <!-- Фиксируем только те управляемые блокировки, которые вызвали реальное ожидание -->
        <event>
            <eq property="Name" value="TLOCK"/>
            <ne property="WaitConnections" value=""/>
        </event>
        
        <!-- Фиксируем запросы к СУБД, которые встали в очередь ожидания блокировки -->
        <event>
            <eq property="Name" value="DBMSSQL"/>
            <eq property="lkp" value="1"/>
        </event>
        
        <!-- Дополнительно: фиксируем аномально долгие SQL-запросы (дольше 15 секунд) -->
        <event>
            <eq property="Name" value="DBMSSQL"/>
            <gt property="Duration" value="15000000"/>
        </event>
        
        <!-- Выгружаем все доступные свойства для отслеживаемых событий -->
        <property name="all"/>
    </log>
    
    <!-- Сбор дампов при аварийном завершении рабочих процессов rphost -->
    <dump create="true" location="D:\1C_log\dumps" type="3" />
    
</config>

Преимущества данного шаблона:

---

Как расследовать блокировки СУБД (MS SQL Server) по шагам

Проанализируем ситуацию, когда на сервере произошел сбой из-за конфликта блокировок СУБД, и выясним причину с помощью собранных логов ТЖ:

  1. Поиск точки сбоя. Открываем файлы логов в каталоге ТЖ и ищем событие EXCP, содержащее текст native=1222 или фразу Превышено время ожидания запроса на блокировку. Из этого события мы получаем:
    • Точное время возникновения ошибки с точностью до микросекунд.
    • Идентификатор сеанса 1С (свойство t:connectID).
    • Имя рабочего процесса (p:processName) и контекст выполнения (Context), указывающий на конкретную строку модуля 1С, на которой произошел сбой.
  2. Поиск заблокированного запроса. По полученному времени и номеру соединения t:connectID переходим к анализу событий DBMSSQL с признаком lkp=1, произошедших незадолго до падения транзакции. Здесь мы увидим фактический SQL-текст запроса (свойство Sql), который СУБД не смогла выполнить вовремя.
  3. Использование элемента dbmslocks. Если стандартных свойств недостаточно для определения того, какой именно процесс СУБД выступил в роли виновника блокировки, мы можем временно включить в файл logcfg.xml специализированный корневой тег: <dbmslocks/> Важно: Начиная с версии платформы 8.3.8, при наличии этого тега платформа 1С автоматически опрашивает системные таблицы MS SQL Server при возникновении ожиданий на уровне базы данных. В ТЖ запишется подробная информация о блокирующем и заблокированном соединениях СУБД. Включайте данный тег исключительно на период расследования, так как он создает дополнительную нагрузку на СУБД.

---

Почему возникают блокировки на СУБД при работе в управляемом режиме 1С?

Многие разработчики ошибочно полагают, что перевод конфигурации на «Управляемый режим блокировок» полностью исключает появление конфликтов на уровне СУБД. Выясним основные причины, почему транзакционные блокировки MS SQL Server продолжают возникать и приводить к ошибкам native=1222:

1. Отсутствие подходящих индексов в СУБД

Рассмотрим ситуацию: при записи документа или выполнении запроса СУБД должна прочитать или обновить определенные строки таблицы. Если для используемых в условии ГДЕ полей отсутствует индекс, СУБД не может быстро найти нужные записи. Вместо этого MS SQL Server выполняет операцию Table Scan (сканирование всей таблицы) или Index Scan (сканирование всего индекса).

Чтобы гарантировать целостность данных во время сканирования всей таблицы, СУБД накладывает блокировку на всю таблицу целиком, а не на конкретные строки. В этот момент любая другая транзакция, пытающаяся записать данные в эту таблицу, встает в очередь ожидания и в итоге падает по таймауту.

2. Эскалация блокировок (Lock Escalation) в MS SQL Server

СУБД расходует оперативную память на поддержание каждой блокировки строки. Если транзакция изменяет или считывает очень большой объем данных (порог в MS SQL Server обычно составляет более 5000 блокировок строк на одну таблицу), СУБД в целях оптимизации ресурсов выполняет эскалацию блокировок — заменяет множество мелких блокировок строк одной монопольной блокировкой всей таблицы (Table Lock). Все параллельные транзакции к этой таблице мгновенно блокируются.

3. Не включен режим версионирования строк (RCSI)

Для корректной параллельной работы управляемых блокировок 1С на СУБД MS SQL Server критически важно активировать параметр базы данных Read Committed Snapshot Isolation (RCSI). Разберем по шагам, как проверить и включить данный режим:

  1. Убедитесь, что к базе данных нет активных подключений.
  2. Выполните в MS SQL Server Management Studio следующий SQL-запрос:
    
    ALTER DATABASE [Имя_Вашей_Базы] SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
    ALTER DATABASE [Имя_Вашей_Базы] SET READ_COMMITTED_SNAPSHOT ON;
    ALTER DATABASE [Имя_Вашей_Базы] SET MULTI_USER;
    

Если режим RCSI отключен, любые операции чтения (даже обычные отчеты) будут накладывать разделяемые блокировки (S-блокировки) на таблицы СУБД, которые будут конфликтовать с транзакциями записи, вызывая массовые ожидания и таймауты.

4. Использование смешанного режима блокировок

Если в конфигурации у части объектов метаданных свойство «Режим управления блокировкой данных» установлено в значение «Автоматический», а у других — в «Управляемый», платформа будет использовать смешанный режим. В автоматическом режиме СУБД накладывает избыточные жесткие транзакционные блокировки, которые будут конфликтовать с транзакциями управляемого режима, сводя на нет всю оптимизацию.

---

Заключение

Мы проанализировали особенности настройки технологического журнала 1С для выявления причин блокировок. Понимание разницы между управляемыми блокировками и механизмами СУБД позволяет администратору быстро локализовать источник проблемы, не тратя время на поиск несуществующих событий TTIMEOUT при системных сбоях базы данных. Используйте предложенный «джентльменский набор» настроек ТЖ для постоянного мониторинга ваших баз данных, своевременно проводите аудит индексов и следите за настройками СУБД.

← На главную