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

В отличие от обычных блокировок, которые возникают при одновременном доступе к одной записи, эскалация — это автоматическое расширение уровня блокировки с строк на целые таблицы или даже базу данных. Например, вместо блокировки одной строки в документе РеализацияТоваровУслуг система может заблокировать всю таблицу Document123, а затем и всю базу. Последствия? Пользователи не могут провести ни одного документа, отчёты не формируются, а попытки перезапустить сервер только усугубляют ситуацию.

В этой статье разберём:

  • 🔍 Как распознать эскалацию по симптомам и логам
  • ⚙️ Причины — от неоптимизированных запросов до ошибок конфигурации
  • 🛠️ Способы диагностики с помощью SQL Profiler, 1С:Технология промежуточного слоя и встроенных инструментов
  • 🚀 Методы решения — от ручной разблокировки до изменения настроек СУБД
  • 📊 Профилактика: как настроить систему, чтобы эскалация не повторялась

Что такое эскалация блокировок и почему она опасна

Эскалация блокировок — это автоматический процесс повышения уровня блокировки в СУБД (например, Microsoft SQL Server или PostgreSQL), когда количество мелких блокировок (на уровне строк или страниц) превышает установленный порог. Вместо того чтобы держать тысячи блокировок на отдельные записи, система «поднимает» их до уровня таблицы или даже всей базы. Это снижает нагрузку на сервер, но блокирует доступ ко всем данным, а не только к тем, с которыми работает текущая транзакция.

Опасность эскалации в заключается в трёх ключевых моментах:

  • 🕒 Невидимость: пользователи видят только «зависание» системы, не понимая, что проблема на уровне СУБД.
  • 🔄 Каскадный эффект: одна эскалированная блокировка может спровоцировать дедлоки в других транзакциях.
  • 💥 Трудность восстановления: иногда требуется перезагрузка сервера или откат транзакций вручную.

Например, если в базе 1С:Управление торговлей одновременно проводятся 50 документов Заказ покупателя, и каждый из них блокирует строки в таблице Document123_ВТ_Товары, СУБД может эскалировать блокировки до уровня всей таблицы. В результате даже просмотр справочника Номенклатура станет невозможен.

📊 С какой СУБД вы работаете в 1С?
Microsoft SQL Server
PostgreSQL
Oracle
IBM DB2
Другая

Признаки эскалации блокировок в 1С

Как понять, что проблема именно в эскалации, а не в зависании сервера или сетевых проблемах? Обратите внимание на следующие симптомы:

  • Зависание операций: документы не проводятся, отчёты не формируются, но ошибок нет — просто бесконечное ожидание.
  • 📛 Сообщения в логах: в журнале SQL Server или pg_stat_activity появляются записи о блокировках уровня TABLE или DATABASE.
  • 🔄 Циклические дедлоки: транзакции взаимно блокируют друг друга, и единственный выход — принудительный откат.
  • 📉 Резкое падение производительности: даже простые операции (например, открытие справочника) занимают минуты.

Чтобы подтвердить эскалацию, проверьте:

  1. Журналы SQL Server на наличие событий LOCK_ESCALATION.
  2. Текущие блокировки через запрос:
    SELECT
    

    resource_type,

    resource_database_id,

    resource_associated_entity_id,

    request_mode,

    request_session_id

    FROM sys.dm_tran_locks;

  3. В — журнал регистрации (1CV8Log) на ошибки типа Таймаут блокировки.

💡

Если в логах SQL Server вы видите блокировки типа SCH-M (схема модификации), это признак эскалации на уровне структуры таблицы. Такие блокировки часто возникают при изменении метаданных или реорганизации индексов.

Основные причины эскалации в 1С

Эскалация редко возникает сама по себе — обычно её провоцируют ошибки в конфигурации, неоптимизированные запросы или неправильные настройки СУБД. Рассмотрим самые распространённые причины:

Причина Пример Как диагностировать
Массовые транзакции Пакетное проведение 1000 документов за раз Мониторинг длительных транзакций в sys.dm_tran_active_transactions
Неэффективные запросы Запрос с ПОМЕСТИТЬ, сканирующий миллионы строк Анализ плана выполнения в SQL Server Management Studio
Отсутствие индексов Поиск по неиндексированному полю в большой таблице Просмотр статистики Missing Indexes в СУБД
Длинные блокирующие операции Обновление справочника с триггерами, запускающими каскадные изменения Журнал блокировок sp_who2 или pg_locks

Особенно опасна эскалация в конфигурациях с большим количеством взаимосвязанных документов, например, в 1С:ERP или 1С:Комплексная автоматизация. Например, проведение документа Заказ на производство может блокировать связанные записи в Заказ покупателя, Складские запасы и План производства, что быстро приводит к эскалации.

Почему эскалация чаще происходит в конце месяца?

В период закрытия месяца пользователи массово проводят документы (накладные, акты, счета-фактуры), что создаёт пиковую нагрузку на базу. Кроме того, запускаются регламентные операции (например, расчёт себестоимости или закрытие затратных счетов), которые блокируют критические таблицы на долгое время.

Как диагностировать эскалацию блокировок

Для точной диагностики эскалации потребуются инструменты как со стороны , так и со стороны СУБД. Вот пошаговый план:

  1. Проверьте текущие блокировки в СУБД:
    • Для SQL Server:
      EXEC sp_who2;

      или более детальный запрос:

      SELECT
      

      t1.resource_type,

      t1.resource_database_id,

      t1.request_mode,

      t1.request_session_id,

      t2.blocking_session_id

      FROM sys.dm_tran_locks t1

      JOIN sys.dm_os_waiting_tasks t2 ON t1.lock_owner_address = t2.resource_address;

    • Для PostgreSQL:
      SELECT blocked_locks.pid AS blocked_pid,
      

      blocking_locks.pid AS blocking_pid,

      blocked_activity.usename AS blocked_user,

      blocking_activity.usename AS blocking_user,

      blocked_activity.query AS blocked_statement

      FROM pg_catalog.pg_locks blocked_locks

      JOIN pg_stat_activity blocked_activity ON blocked_activity.pid = blocked_locks.pid

      JOIN pg_catalog.pg_locks blocking_locks

      ON blocking_locks.locktype = blocked_locks.locktype

      AND blocking_locks.DATABASE IS NOT DISTINCT FROM blocked_locks.DATABASE

      AND blocking_locks.relation IS NOT DISTINCT FROM blocked_locks.relation

      AND blocking_locks.page IS NOT DISTINCT FROM blocked_locks.page

      AND blocking_locks.tuple IS NOT DISTINCT FROM blocked_locks.tuple

      AND blocking_locks.virtualxid IS NOT DISTINCT FROM blocked_locks.virtualxid

      AND blocking_locks.transactionid IS NOT DISTINCT FROM blocked_locks.transactionid

      AND blocking_locks.classid IS NOT DISTINCT FROM blocked_locks.classid

      AND blocking_locks.objid IS NOT DISTINCT FROM blocked_locks.objid

      AND blocking_locks.objsubid IS NOT DISTINCT FROM blocked_locks.objsubid

      AND blocking_locks.pid != blocked_locks.pid

      JOIN pg_stat_activity blocking_activity ON blocking_activity.pid = blocking_locks.pid

      WHERE NOT blocked_locks.GRANTED;

  2. Анализируйте журналы 1С:
    • Откройте файл 1CV8Log\YYYYMMDD.log и найдите строки с WaitTimeout или Deadlock.
    • Используйте Журнал регистрации в конфигураторе (Администрирование → Журнал регистрации).
  • Проверьте настройки эскалации в СУБД:
    • В SQL Server выполните:
      SELECT name, value, value_in_use
      

      FROM sys.configurations

      WHERE name = 'lock escalation';

      По умолчанию эскалация включена (value = 1).

    Проверьте текущие блокировки в СУБД|Проанализируйте журналы 1С на ошибки таймаутов|Убедитесь, что эскалация не отключена на уровне СУБД|Определите, какие транзакции удерживают блокировки дольше 30 секунд-->

    Как устранить эскалацию блокировок: пошаговые решения

    Если эскалация уже произошла, действуйте по следующему алгоритму:

    1. Прервите проблемные транзакции

    Найдите и принудительно завершите транзакции, которые удерживают эскалированные блокировки:

    • В SQL Server:
      KILL {session_id};

      где {session_id} — идентификатор сессии из sp_who2.

    • В PostgreSQL:
      SELECT pg_terminate_backend({pid});

    💡

    Прерывайте транзакции только в крайнем случае! Это может привести к потере данных или нарушению целостности. Всегда сначала пытайтесь завершить транзакции штатными средствами (например, через РАЗРЫВ СОЕДИНЕНИЯ в 1С).

    2. Оптимизируйте запросы и транзакции

    Чаще всего эскалацию вызывают длинные транзакции или неэффективные запросы. Проверьте:

    • 🔍 Запросы с ПОМЕСТИТЬ, обрабатывающие большие объёмы данных. Разбейте их на пакеты по 100–200 строк.
    • 📊 Отчёты, которые формируются в транзакции. Перенесите их за пределы транзакции или используйте НЕБЛОКИРУЮЩИЙ режим.
    • 🔄 Циклы по справочникам с обновлением записей. Замените их пакетными операциями.

    Пример оптимизации: Плохо:

    НачатьТранзакцию();
    

    Для Каждого Строка Из ТаблицаЦен Цикл

    Строка.Цена = НоваяЦена;

    Строка.Записать();

    КонецЦикла;

    ЗафиксироватьТранзакцию();

    Хорошо:
    НачатьТранзакцию();
    

    Запрос = Новый Запрос;

    Запрос.Текст = "ВЫБРАТЬ ССЫЛКА КАК Ссылка ИЗ ТаблицаЦен";

    Выборка = Запрос.Выполнить().Выбрать();

    Пока Выборка.Следующий() Цикл

    Объект = Выборка.Ссылка.ПолучитьОбъект();

    Объект.Цена = НоваяЦена;

    Объект.Записать();

    КонецЦикла;

    ЗафиксироватьТранзакцию();

    3. Настройте пороги эскалации в СУБД

    Вы можете изменить параметры эскалации или отключить её вовсе (не рекомендуется для производственных систем!).

    Для SQL Server:

    • Отключить эскалацию на уровне таблицы:
      ALTER TABLE [dbo].[YourTable] SET (LOCK_ESCALATION = DISABLE);
    • Изменить порог эскалации (требует перезапуска сервера):
      EXEC sp_configure 'show advanced options', 1;
      

      RECONFIGURE;

      EXEC sp_configure 'lock escalation threshold', 5000; -- Установить порог в 5000 блокировок

      RECONFIGURE;

    Для PostgreSQL эскалация управляется параметром max_locks_per_transaction (по умолчанию 64). Увеличьте его в postgresql.conf:

    max_locks_per_transaction = 256

    💡

    Если вы отключаете эскалацию, обязательно увеличьте объём памяти, выделенной под блокировки (locks в SQL Server или shared_buffers в PostgreSQL). Иначе система может начать тормозить из-за переполнения буфера блокировок.

    Профилактика эскалации: как настроить 1С и СУБД

    Лучший способ борьбы с эскалацией — предотвратить её возникновение. Вот ключевые меры профилактики:

    • Оптимизируйте транзакции:
      • Держите транзакции как можно короче. Не открывайте транзакцию в начале процедуры и не закрывайте в конце — разбивайте на логические блоки.
      • Используйте УРОВЕНЬИЗОЛИРОВАННОСТИ ТРАНЗАКЦИИ (например, ПОВТОРЯЕМОЕЧТЕНИЕ вместо СЕРИАЛИЗУЕМОЕ, если возможно).
    • 📊 Настройте индексы:
      • Добавьте индексы на поля, по которым часто идут выборки или обновления.
      • Используйте Database Engine Tuning Advisor (SQL Server) или EXPLAIN ANALYZE (PostgreSQL) для анализа запросов.
    • ⚙️ Конфигурируйте СУБД:
      • Увеличьте max degree of parallelism (для SQL Server), чтобы уменьшить конкуренцию за ресурсы.
      • Настройте cost threshold for parallelism (порог стоимости запроса, при котором включается параллелизм).
    • 🔄 Используйте технологию промежуточного слоя:
      • Включите 1С:Технология промежуточного слоя (ТПС) для распределения нагрузки.
      • Настройте пулы соединений в ras cluster.dll.

    Пример настройки индекса в :

    // Добавляем индекс на поле "Дата" в документе "РеализацияТоваровУслуг"
    

    Индекс = МенеджерВременныхТаблиц.СоздатьИндекс();

    Индекс.ДобавитьПоле("Дата");

    Индекс.Использовать();

    Как проверить, что индекс используется?

    В SQL Server Management Studio откройте план выполнения запроса (кнопка Include Actual Execution Plan). Если индекс используется, вы увидите оператор Index Seek вместо Table Scan. В PostgreSQL используйте EXPLAIN ANALYZE — в выводе должен быть Index Scan.

    Частые ошибки при работе с блокировками в 1С

    Даже опытные администраторы иногда усугубляют проблему эскалации неправильными действиями. Вот что нельзя делать:

    ⚠️ Внимание: Никогда не перезагружайте сервер СУБД или кластер без предварительного анализа блокировок. Это может привести к потере несохранённых транзакций или повреждению базы.
    • 🚫 Игнорировать таймауты:

      Если в логах появляются ошибки WaitTimeout, не увеличивайте значение таймаута блокировки (параметр lock_timeout в PostgreSQL или remote query timeout в SQL Server). Лучше найдите и оптимизируйте проблемный запрос.

    • 🚫 Отключать эскалацию глобально:

      Отключение эскалации на уровне сервера (sp_configure 'lock escalation', 0) может привести к переполнению памяти блокировками и падению производительности.

    • 🚫 Использовать WITH (NOLOCK) бездумно:

      Хинт WITH (NOLOCK) в SQL Server позволяет читать данные без блокировок, но может привести к грязному чтению (dirty read) — вы получите неактуальные или повреждённые данные.

    • 🚫 Забывать про тестирование:

      Любые изменения в настройках блокировок (пороги эскалации, уровни изолированности) сначала тестируйте на копии рабочей базы!

    Типичный пример ошибки:

    // ПЛОХО: длинная транзакция с блокировкой всей таблицы
    

    НачатьТранзакцию();

    Запрос = Новый Запрос("ВЫБРАТЬ * ИЗ Документ.РеализацияТоваровУслуг");

    Результат = Запрос.Выполнить();

    Пока Результат.Следующий() Цикл

    // ... обработка каждой строки

    КонецЦикла;

    ЗафиксироватьТранзакцию(); // Блокировка удерживается слишком долго!

    FAQ: Ответы на частые вопросы об эскалации блокировок

    Можно ли полностью отключить эскалацию блокировок в 1С?

    Технически да, но это не рекомендуется. Отключение эскалации может привести к:

    • Переполнению памяти сервера из-за большого количества мелких блокировок.
    • Замедлению работы системы, так как СУБД будет тратить ресурсы на управление тысячами блокировок.
    • Увеличению риска дедлоков из-за длительного удержания блокировок.

    Лучше оптимизировать запросы и настройку СУБД, чем отключать эскалацию.

    Как эскалация блокировок связана с репликацией данных в 1С?

    Эскалация может полностью парализовать репликацию, так как:

    • Репликационные процессы (например, в 1С:Распределённая информационная база) требуют блокировки системных таблиц.
    • Эскалированная блокировка на уровне таблицы или базы заблокирует и операции репликации.
    • В результате узлы РИБ перестанут синхронизироваться, а в логах появятся ошибки типа Replication timeout.

    Решение: настройте репликацию на отдельные периоды низкой нагрузки или используйте асинхронную репликацию.

    Какие настройки 1С влияют на вероятность эскалации?

    На эскалацию косвенно влияют следующие параметры:

    • MaxPoolSize в строке подключения к базе — ограничивает количество одновременно открытых соединений.
    • ConnectionTimeout — если слишком мал, пользователи будут чаще получать ошибки таймаута.
    • Transaction Isolation Level в настройках кластера — уровень изолированности транзакций.
    • Autocommit — если отключён, все операции выполняются в явных транзакциях, что увеличивает риск блокировок.

    Оптимальные значения зависят от конфигурации и нагрузки. Например, для 1С:ERP с 50+ пользователями рекомендуется:

    MaxPoolSize=100;ConnectionTimeout=30;Transaction Isolation Level=ReadCommitted;

    Что делать, если эскалация происходит ночью во время регламентных операций?

    Ночные регламентные операции (например, Закрытие месяца или Обновление итогов) часто становятся причиной эскалации из-за:

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

    Решения:

    • Разбейте регламентные операции на более мелкие пакеты (например, закрывайте счета по подразделениям, а не всей организацией).
    • Перенесите операции на время минимальной активности пользователей.
    • Используйте фоновые задания с пониженным приоритетом.
    Как эскалация блокировок проявляется в 1С:Зарплата и Управление Персоналом?

    В 1С:ЗУП эскалация чаще всего возникает при:

    • Массовом начислении зарплаты (блокировка таблиц РасчетЗарплаты и Начисления).
    • Обновлении справочника Сотрудники с большим количеством записей.
    • Формировании отчётов по ФОТ с детализацией по всем сотрудникам.

    Особенности:

    • В ЗУП часто используются ВременныеТаблицы, которые могут блокировать системные ресурсы.
    • Рекомендуется настраивать УРОВЕНЬИЗОЛИРОВАННОСТИ ТРАНЗАКЦИИ = ПОВТОРЯЕМОЕЧТЕНИЕ для отчётных форм.