База данных 1С:Предприятие внезапно перестаёт реагировать на запросы, транзакции зависают на часы, а в логах появляются сообщения о дедлоках или таймаутах? Скорее всего, вы столкнулись с эскалацией блокировок — одной из самых коварных проблем в многопользовательских системах. Этот механизм, изначально призванный защищать целостность данных, может превратиться в источник паралича всей учётной системы, если его не контролировать.
В отличие от обычных блокировок, которые возникают при одновременном доступе к одной записи, эскалация — это автоматическое расширение уровня блокировки с строк на целые таблицы или даже базу данных. Например, вместо блокировки одной строки в документе РеализацияТоваровУслуг система может заблокировать всю таблицу Document123, а затем и всю базу. Последствия? Пользователи не могут провести ни одного документа, отчёты не формируются, а попытки перезапустить сервер только усугубляют ситуацию.
В этой статье разберём:
- 🔍 Как распознать эскалацию по симптомам и логам
- ⚙️ Причины — от неоптимизированных запросов до ошибок конфигурации
- 🛠️ Способы диагностики с помощью SQL Profiler, 1С:Технология промежуточного слоя и встроенных инструментов
- 🚀 Методы решения — от ручной разблокировки до изменения настроек СУБД
- 📊 Профилактика: как настроить систему, чтобы эскалация не повторялась
Что такое эскалация блокировок и почему она опасна
Эскалация блокировок — это автоматический процесс повышения уровня блокировки в СУБД (например, Microsoft SQL Server или PostgreSQL), когда количество мелких блокировок (на уровне строк или страниц) превышает установленный порог. Вместо того чтобы держать тысячи блокировок на отдельные записи, система «поднимает» их до уровня таблицы или даже всей базы. Это снижает нагрузку на сервер, но блокирует доступ ко всем данным, а не только к тем, с которыми работает текущая транзакция.
Опасность эскалации в 1С заключается в трёх ключевых моментах:
- 🕒 Невидимость: пользователи видят только «зависание» системы, не понимая, что проблема на уровне СУБД.
- 🔄 Каскадный эффект: одна эскалированная блокировка может спровоцировать дедлоки в других транзакциях.
- 💥 Трудность восстановления: иногда требуется перезагрузка сервера или откат транзакций вручную.
Например, если в базе 1С:Управление торговлей одновременно проводятся 50 документов Заказ покупателя, и каждый из них блокирует строки в таблице Document123_ВТ_Товары, СУБД может эскалировать блокировки до уровня всей таблицы. В результате даже просмотр справочника Номенклатура станет невозможен.
Признаки эскалации блокировок в 1С
Как понять, что проблема именно в эскалации, а не в зависании сервера или сетевых проблемах? Обратите внимание на следующие симптомы:
- ⏳ Зависание операций: документы не проводятся, отчёты не формируются, но ошибок нет — просто бесконечное ожидание.
- 📛 Сообщения в логах: в журнале SQL Server или pg_stat_activity появляются записи о блокировках уровня
TABLEилиDATABASE. - 🔄 Циклические дедлоки: транзакции взаимно блокируют друг друга, и единственный выход — принудительный откат.
- 📉 Резкое падение производительности: даже простые операции (например, открытие справочника) занимают минуты.
Чтобы подтвердить эскалацию, проверьте:
- Журналы SQL Server на наличие событий
LOCK_ESCALATION. - Текущие блокировки через запрос:
SELECTresource_type,
resource_database_id,
resource_associated_entity_id,
request_mode,
request_session_id
FROM sys.dm_tran_locks;
- В 1С — журнал регистрации (
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;или более детальный запрос:
SELECTt1.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;
- Для SQL Server:
- Анализируйте журналы 1С:
- Откройте файл
1CV8Log\YYYYMMDD.logи найдите строки сWaitTimeoutилиDeadlock. - Используйте Журнал регистрации в конфигураторе (
Администрирование → Журнал регистрации).
- Откройте файл
- В SQL Server выполните:
SELECT name, value, value_in_useFROM 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.
Пример настройки индекса в 1С:
// Добавляем индекс на поле "Дата" в документе "РеализацияТоваровУслуг"
Индекс = МенеджерВременныхТаблиц.СоздатьИндекс();
Индекс.ДобавитьПоле("Дата");
Индекс.Использовать();
Как проверить, что индекс используется?
В SQL Server Management Studio откройте план выполнения запроса (кнопка Include Actual Execution Plan). Если индекс используется, вы увидите оператор Index Seek вместо Table Scan. В PostgreSQL используйте EXPLAIN ANALYZE — в выводе должен быть Index Scan.
Частые ошибки при работе с блокировками в 1С
Даже опытные администраторы иногда усугубляют проблему эскалации неправильными действиями. Вот что нельзя делать:
⚠️ Внимание: Никогда не перезагружайте сервер СУБД или кластер 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С:ЗУП эскалация чаще всего возникает при:
- Массовом начислении зарплаты (блокировка таблиц
РасчетЗарплатыиНачисления). - Обновлении справочника
Сотрудникис большим количеством записей. - Формировании отчётов по ФОТ с детализацией по всем сотрудникам.
Особенности:
- В ЗУП часто используются
ВременныеТаблицы, которые могут блокировать системные ресурсы. - Рекомендуется настраивать
УРОВЕНЬИЗОЛИРОВАННОСТИ ТРАНЗАКЦИИ = ПОВТОРЯЕМОЕЧТЕНИЕдля отчётных форм.