К статье
Практический материал

Администрирование · 10 мин

Как остановить выполнение запроса в 1С

Как остановить зависший запрос в 1С: прерывание в консоли, отмена на сервере СУБД, администрирование сеансов, ограничение времени выполнения и профилактика тяжёлых запросов.

Долго выполняющийся запрос в 1С — типичная ситуация и для разработчика, и для администратора. Отчёт «завис» на полчаса, консоль запросов не отвечает, а пользователи жалуются на блокировки. Умение корректно остановить такой запрос экономит часы рабочего времени и предотвращает каскадные проблемы на сервере.

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

Ниже разобраны все рабочие методы: от простого прерывания в клиенте до принудительного снятия процесса на уровне MS SQL Server или PostgreSQL, а также способы предотвратить появление бесконечных запросов.

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

Прежде чем «убивать» процесс, убедитесь, что запрос действительно проблемный. Признаки зависшего запроса: интерфейс не отвечает более 5–10 минут при операции, которая обычно занимает секунды; в мониторе СУБД виден процесс со статусом ожидания блокировки (suspended / waiting); нарастает очередь заблокированных сеансов других пользователей.

Отличайте три ситуации. Первая — запрос реально выполняется: процессор сервера СУБД загружен, идёт чтение данных. Такой запрос можно либо дождаться, либо прервать. Вторая — запрос ждёт снятия блокировки: он почти не потребляет ресурсов, но стоит в очереди. Тут останавливать нужно либо его, либо сеанс-блокировщик. Третья — взаимоблокировка (deadlock): СУБД обычно сама выбирает «жертву» и откатывает одну из транзакций.

Процессор СУБД загруженЗапрос активно выполняется

Проверьте план запроса — вероятно, сканирование большой таблицы без индекса

Процесс в ожиданииЗапрос ждёт снятия блокировки

Найдите сеанс-блокировщик через sp_who2 или pg_locks

Растёт tempdb / временные файлыЗапрос строит огромный промежуточный результат

Прерывайте — дальше будет только хуже, возможно переполнение диска

Много жалоб пользователейЗапрос блокирует работу других сеансов

Останавливайте немедленно, затем разбирайтесь с причиной

Прерывание запроса в клиенте 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 для автоматической отмены запросов, выполняющихся дольше заданного времени.

Со стороны разработки проверяйте планы запросов для отчётов и обработок: массовое сканирование таблиц без индексов, соединения без условий, выборка «левых» соединений по виртуальным таблицам без отборов — типичные причины зависаний. В запросах к виртуальным таблицам регистров всегда задавайте параметры периода и отборы в параметрах виртуальной таблицы, а не в секции ГДЕ.

Типичные ошибки
01
Завершение процесса 1cv8.exe на клиенте — запрос на сервере СУБД продолжает работать и держать блокировки
02
KILL сеанса с большой транзакцией — откат занимает столько же времени, сколько выполнение, и блокировки держатся до конца отката
03
Перезагрузка сервера СУБД вместо точечной остановки — страдают все пользователи, возможна длительная восстановительная фаза базы
04
Остановка запроса без анализа причины — через час тот же отчёт снова зависает
05
Попытка отменить фоновое задание методом Отменить() для задания из одного длинного запроса — метод не срабатывает, время теряется

Проверка результата после остановки

Контрольные точки

Как проверить результат

Процесс в мониторе СУБД
Норма

Процесс исчез из списка активных запросов

Тревожный признак

Процесс в статусе 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. Прервать откат невозможно, нужно дождаться завершения. Если отката нет, а блокировки висят — проверьте, нет ли другого сеанса с открытой транзакцией, и завершите его.

Опасно ли останавливать запросы регламентных заданий?

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