Администрирование · 10 мин
Как остановить выполнение запроса в 1С
Как остановить зависший запрос в 1С: прерывание в консоли, отмена на сервере СУБД, администрирование сеансов, ограничение времени выполнения и профилактика тяжёлых запросов.
Долго выполняющийся запрос в 1С — типичная ситуация и для разработчика, и для администратора. Отчёт «завис» на полчаса, консоль запросов не отвечает, а пользователи жалуются на блокировки. Умение корректно остановить такой запрос экономит часы рабочего времени и предотвращает каскадные проблемы на сервере.
Способ остановки зависит от того, где именно выполняется запрос: в файловой базе, в клиент-серверном варианте на уровне СУБД или в фоновом задании. Важно понимать, что «зависший» запрос — это чаще всего не ошибка платформы, а тяжёлая выборка данных, которая либо выполняется слишком долго, либо ожидает снятия блокировки другим сеансом.
Ниже разобраны все рабочие методы: от простого прерывания в клиенте до принудительного снятия процесса на уровне MS SQL Server или PostgreSQL, а также способы предотвратить появление бесконечных запросов.
Как понять, что запрос нужно останавливать
Прежде чем «убивать» процесс, убедитесь, что запрос действительно проблемный. Признаки зависшего запроса: интерфейс не отвечает более 5–10 минут при операции, которая обычно занимает секунды; в мониторе СУБД виден процесс со статусом ожидания блокировки (suspended / waiting); нарастает очередь заблокированных сеансов других пользователей.
Отличайте три ситуации. Первая — запрос реально выполняется: процессор сервера СУБД загружен, идёт чтение данных. Такой запрос можно либо дождаться, либо прервать. Вторая — запрос ждёт снятия блокировки: он почти не потребляет ресурсов, но стоит в очереди. Тут останавливать нужно либо его, либо сеанс-блокировщик. Третья — взаимоблокировка (deadlock): СУБД обычно сама выбирает «жертву» и откатывает одну из транзакций.
Проверьте план запроса — вероятно, сканирование большой таблицы без индекса
Найдите сеанс-блокировщик через sp_who2 или pg_locks
Прерывайте — дальше будет только хуже, возможно переполнение диска
Останавливайте немедленно, затем разбирайтесь с причиной
Прерывание запроса в клиенте 1С
Если запрос запущен интерактивно — в консоли запросов, отладчике или толстом клиенте — самый простой способ остановки: нажмите Ctrl+Break (на клавиатурах без клавиши Break — Ctrl+Pause, на ноутбуках иногда Fn+Ctrl+B). Платформа прервёт выполнение кода на ближайшей безопасной точке.
Учтите ограничение: прерывание срабатывает не мгновенно. Если управление уже передано на сервер СУБД и выполняется один «атомарный» SQL-запрос, клиент дождётся ответа сервера. В этом случае останавливать нужно на стороне СУБД (см. разделы ниже).
В веб-клиенте и тонком клиенте прерывание пользователем недоступно: выполнение идёт на сервере, и закрытие вкладки браузера не остановит запрос — сеанс продолжит работать, пока не завершится или не будет снят администратором.
Остановка через консоль кластера серверов 1С
В клиент-серверном режиме основной инструмент администратора — консоль кластера (оснастка «Администрирование серверов 1С:Предприятия»). Через неё можно найти проблемный сеанс и завершить его принудительно.
Обратите внимание: завершение сеанса в консоли кластера разрывает соединение рабочего процесса с клиентом, но SQL-запрос на сервере СУБД может продолжить выполнение ещё некоторое время, пока СУБД не обнаружит обрыв соединения. Для немедленной остановки требуется команда на уровне СУБД.
Остановка запроса на уровне СУБД
MS SQL Server
Откройте SQL Server Management Studio и найдите проблемный процесс через Activity Monitor (Ctrl+Alt+A) или запросом к системным представлениям. Определите SPID сеанса и выполните команду KILL.
-- Найти долгие запросы
SELECT r.session_id, r.status, r.wait_type, r.command,
t.text AS query_text, r.start_time
FROM sys.dm_exec_requests r
CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) t
WHERE r.session_id > 50
ORDER BY r.total_elapsed_time DESC;
-- Остановить процесс с конкретным SPID
KILL 75;
После KILL транзакция откатывается. Если транзакция была большой (массовое изменение данных), откат может занять сопоставимое с выполнением время — процесс будет в статусе «killed/rollback». Прерывать откат нельзя, остаётся ждать.
PostgreSQL
-- Найти долгие запросы
SELECT pid, state, wait_event_type, now() - query_start AS duration, query
FROM pg_stat_activity
WHERE state <> 'idle'
ORDER BY duration DESC;
-- Мягкая отмена запроса (транзакция сохраняется)
SELECT pg_cancel_backend(12345);
-- Жёсткое завершение сеанса (транзакция откатывается)
SELECT pg_terminate_backend(12345);
Начинайте с pg_cancel_backend — он отменяет только текущий запрос, оставляя соединение живым. Если запрос не отменяется или сеанс завис полностью, используйте pg_terminate_backend.
Остановка фоновых заданий
Запрос может выполняться внутри фонового задания — например, регламентная обработка или отчёт, запущенный асинхронно. Такие задания видны в консоли кластера на вкладке «Фоновые задания» и в разделе «Сеансы» (тип сеанса — «Фоновое задание»).
Для остановки найдите задание в консоли кластера и завершите соответствующий сеанс. Программно фоновое задание отменяется методом ФоновыеЗадания.НайтиПоУникальномуИдентификатору() с последующим вызовом Отменить(). Метод работает только если код задания периодически возвращает управление платформе — «чёрный ящик» из одного длинного запроса отменить так не получится, поможет только остановка на уровне СУБД.
Как предотвратить бесконечные запросы
Лучший способ остановки — не допустить ситуацию. Настройте ограничения на уровне СУБД: в MS SQL — ресурсный governor (Resource Governor) для ограничения CPU и памяти сеансов 1С; в PostgreSQL — параметр statement_timeout для автоматической отмены запросов, выполняющихся дольше заданного времени.
Со стороны разработки проверяйте планы запросов для отчётов и обработок: массовое сканирование таблиц без индексов, соединения без условий, выборка «левых» соединений по виртуальным таблицам без отборов — типичные причины зависаний. В запросах к виртуальным таблицам регистров всегда задавайте параметры периода и отборы в параметрах виртуальной таблицы, а не в секции ГДЕ.
Проверка результата после остановки
Как проверить результат
Процесс исчез из списка активных запросов
Процесс в статусе killed/rollback долгое время — дождитесь отката
Очередь ожидающих сеансов рассосалась, пользователи работают
Блокировки остались — ищите другой сеанс-держатель
Прерванная транзакция откачена, данные в исходном состоянии
Частично записанные данные — признак того, что операция шла вне транзакции, нужна проверка целостности
После оптимизации запрос выполняется за приемлемое время
Запрос снова зависает — проблема не решена, нужен анализ плана запроса
После остановки обязательно проверьте, что блокировки сняты и работа пользователей восстановлена. Если запрос был частью транзакции с явным управлением, убедитесь, что транзакция откачена целиком — «подвисшая» открытая транзакция продолжит держать блокировки.
Что важно запомнить
Простые случаи решаются Ctrl+Break в клиенте. Серверные запросы останавливаются через консоль кластера (завершение сеанса) и, при необходимости, командами KILL в MS SQL или pg_cancel_backend/pg_terminate_backend в PostgreSQL. Останавливайте точечно, помните о времени отката больших транзакций и после остановки обязательно разбирайтесь с причиной зависания — иначе ситуация повторится.
Частые вопросы
Почему Ctrl+Break не останавливает запрос?
Прерывание срабатывает только когда управление находится в коде встроенного языка 1С. Если платформа отправила SQL-запрос на сервер СУБД и ждёт ответа, клиент не может прервать ожидание — останавливайте запрос на стороне СУБД или завершайте сеанс в консоли кластера.
Что произойдёт с данными, если убить процесс запроса?
Если запрос выполнялся внутри транзакции, СУБД откатит все её изменения — данные останутся в исходном состоянии. Риск частичной записи существует только для операций без транзакции, что в штатных механизмах 1С встречается редко.
Можно ли ограничить время выполнения запроса автоматически?
Да. В PostgreSQL используйте параметр statement_timeout. В MS SQL прямого таймаута запроса нет, но ограничения настраиваются через Resource Governor. Дополнительно в 1С можно программно контролировать длительность операций и выводить пользователю индикатор с возможностью отмены.
Как найти, кто именно заблокировал мой запрос?
В MS SQL выполните sp_who2 и смотрите колонку BlkBy — там SPID сеанса-блокировщика. В PostgreSQL используйте представление pg_locks в связке с pg_stat_activity. В консоли кластера 1С также видны сеансы с длительными вызовами СУБД.
Запрос остановили, но блокировки остались. Что делать?
Скорее всего, идёт откат большой транзакции — процесс в статусе killed/rollback. Прервать откат невозможно, нужно дождаться завершения. Если отката нет, а блокировки висят — проверьте, нет ли другого сеанса с открытой транзакцией, и завершите его.
Опасно ли останавливать запросы регламентных заданий?
Остановка безопасна для заданий, работающих в транзакции, — изменения откатятся. Осторожность нужна с заданиями обмена данными: прерывание в середине выгрузки может оставить несогласованное состояние, которое потребует повторной выгрузки. Перед остановкой посмотрите, что именно делает задание.