Зависший запрос в консоли: как прервать его, не роняя сервер 1С
Содержание
Чтобы остановить запрос в Консоли запросов 1С, сначала нажмите Ctrl+Break в окне консоли. Если он не реагирует, а база клиент-серверная, откройте консоль администрирования кластера. Там прервите текущий серверный вызов сеанса или завершите сам сеанс. Последний вариант — отменить запрос на стороне СУБД.
Главное, что нужно знать: если закрыть «Предприятие» через диспетчер задач, запрос на сервере не остановится. Клиент исчезнет, а рабочий процесс rphost продолжит гонять запрос, пока СУБД не вернёт результат. Поэтому действуйте сверху вниз, от мягкого способа к жёсткому.
Что происходит с запросом, пока консоль «висит»
Консоль запросов — обычная обработка: внешняя .epf или встроенная в конфигурацию. Она передаёт текст запроса на сервер, там вызывается Запрос.Выполнить(), и платформа ждёт ответа от СУБД. Где именно идёт работа, зависит от варианта базы.
| Вариант базы | Где выполняется запрос | Что поможет остановить |
|---|---|---|
| Файловая | В процессе клиента (1cv8c.exe, 1cv8.exe) | Ctrl+Break, при полном зависании — завершение процесса клиента |
| Клиент-серверная | В рабочем процессе rphost на сервере 1С и в СУБД | Ctrl+Break, консоль кластера, rac, отмена в СУБД |
В файловой базе всё проще: закрыли процесс клиента — закрыли и запрос. В клиент-серверной у запроса три «этажа»: клиент, сервер 1С, СУБД. Остановить его можно на любом, но последствия разные.
💡 Пока запрос «висит», сеанс держит соединение с СУБД. А если запрос выполняется в транзакции, ещё и блокировки. Другие пользователи могут упереться в эти блокировки и получить ошибку по таймауту.
Ctrl+Break: штатное прерывание из окна консоли
Первый и самый безопасный способ — сочетание клавиш Ctrl+Break в окне 1С, где запущена консоль.
- Сделайте окно 1С активным: кликните по заголовку, не по другим программам.
- Нажмите
Ctrl+Break. На ноутбуке без клавиши Break работаютCtrl+Fn+B,Ctrl+Fn+Pauseили экранная клавиатура Windows (osk) — зависит от модели. - Платформа спросит, прервать ли выполнение. Подтвердите.
- Дождитесь сообщения о прерывании. Запрос не вернёт результат, транзакция, если была, откатится.
Когда способ срабатывает плохо:
- 🔸 запрос — одна тяжёлая операция в СУБД. Платформа принимает сигнал, но прервать вызов может только после ответа от СУБД. Ожидание затягивается;
- 🔸 интерфейс клиента завис полностью и не обрабатывает нажатия;
- 🔸 в консоли включена обработка результата циклом, а в цикле нет проверки прерывания.
Если вы дорабатываете свою консоль или обработку, вставьте в длинные клиентские циклы вызов ОбработкаПрерыванияПользователя(). Он проверяет, не нажал ли пользователь Ctrl+Break, и прерывает цикл:
&НаКлиенте
Процедура ОбойтиСтроки(Команда)
Для Каждого Строка Из Объект.Результат Цикл
ОбработкаПрерыванияПользователя();
// обработка строки
КонецЦикла;
КонецПроцедуры
Метод работает только на клиенте. Внутри серверной процедуры его вызывать бессмысленно.
Отладчик Конфигуратора: остановка на нужной строке
Режим отладки полезен, когда запрос выполняет не только консоль, но и ваша обработка или модуль. Отладчик позволяет приостановить код и завершить отлаживаемый сеанс, не трогая остальных пользователей.
Порядок действий:
- В Конфигураторе запустите «Предприятие» в режиме отладки (
F5) или подключитесь к уже запущенному сеансу через менюОтладка → Подключение. - Для клиент-серверной базы на сервере 1С должна быть включена отладка. Иначе остановиться на серверной строке не получится.
- Когда запрос «висит», в меню
Отладкавыберите команду прерывания. Отладчик встанет на текущей строке — обычно этоЗапрос.Выполнить(). - Чтобы снять выполнение совсем, используйте
Отладка → Завершить отладку(Shift+F5). Отлаживаемый сеанс закроется.
Отладчик ещё и показывает, какой запрос на самом деле ушёл в СУБД. Встаньте на строку перед Выполнить() и посмотрите текст и параметры в табло. Часто выясняется, что параметр не заполнен, а отбор по &Организация превратился в выборку по всем организациям.
⚠️ Отладку на рабочем сервере не держите включённой постоянно: она добавляет нагрузку. Включайте на время разбора и выключайте после.
Консоль кластера и rac: как прервать выполнение запроса со стороны сервера 1С
Для клиент-серверной базы это основной способ. Права нужны соответствующие: администратор кластера или администратор информационной базы.
Через консоль администрирования серверов 1С
- Откройте оснастку «Администрирование серверов 1С Предприятия». Подключается она к агенту сервера (по умолчанию порт 1540).
- Раскройте ветку:
Кластеры → ваш кластер → Информационные базы → нужная база → Сеансы. - Найдите свой сеанс. Ориентируйтесь на имя пользователя, компьютер и колонки с временем текущего вызова и вызова СУБД — у зависшего запроса они растут.
- Кликните по сеансу правой кнопкой. Если в контекстном меню есть команда прерывания текущего серверного вызова, используйте её. Сеанс останется жив, а в клиенте появится ошибка.
- Если такой команды нет или она не помогла, выберите
Удалить. Сеанс завершится полностью, пользователь увидит сообщение о разрыве.
Прерывание вызова мягче: не теряются открытые формы и введённые данные в других окнах. Удаление сеанса — гарантированный способ, но человеку придётся переподключаться.
Через утилиту rac
Если оснастки под рукой нет, то же самое делают из командной строки. Нужен запущенный сервис ras.
rem список кластеров
rac cluster list
rem сеансы кластера (подставьте UUID кластера)
rac session list --cluster=<UUID-кластера>
rem завершить конкретный сеанс
rac session terminate --cluster=<UUID-кластера> --session=<UUID-сеанса>
В свежих версиях платформы у rac session есть и команда прерывания текущего серверного вызова. Точное имя и параметры для вашей версии смотрите в rac session help — набор команд меняется от релиза к релизу.
Из самой конфигурации
В типовых конфигурациях на БСП есть обработка «Активные пользователи». Найти её можно через Все функции → Обработки или в разделе администрирования. В ней видно сеансы и есть команда завершения выбранного сеанса. Это удобно, если у вас нет доступа к серверу, но есть полные права в базе.
Завершение сеанса обрывает работу человека в этом сеансе. Несохранённые документы пропадут. Если сеанс чужой, сначала предупредите владельца.
Отмена на уровне СУБД: SQL Server и PostgreSQL
Этот путь нужен, когда сервер 1С уже не может достучаться до вызова: сеанс удалён, а запрос в СУБД всё ещё идёт и держит блокировки. Работа на уровне СУБД — задача администратора баз данных или того, кто имеет такие права.
Microsoft SQL Server
Сначала найдите долгий запрос по нужной базе:
SELECT r.session_id, r.status, r.start_time, r.wait_type,
DB_NAME(r.database_id) AS db, s.host_name, s.program_name
FROM sys.dm_exec_requests r
JOIN sys.dm_exec_sessions s ON s.session_id = r.session_id
WHERE DB_NAME(r.database_id) = 'ИмяБазы'
ORDER BY r.start_time;
Соединения сервера 1С идут с машины, где работает rphost, поэтому в host_name будет имя сервера 1С, а не компьютера пользователя. Сопоставляйте по времени старта и по тексту запроса. Текст можно получить через sys.dm_exec_sql_text(r.sql_handle). Имена таблиц там вида _Document123, _AccumRg456.
Отмена соединения:
KILL 87; -- session_id из запроса выше
После KILL SQL Server откатывает транзакцию. Если запрос успел много изменить, откат идёт долго, и на это время блокировки сохраняются. Прогресс показывает команда KILL 87 WITH STATUSONLY.
PostgreSQL
SELECT pid, state, now() - query_start AS duration, left(query, 200)
FROM pg_stat_activity
WHERE datname = 'имя_базы' AND state = 'active'
ORDER BY query_start;
Дальше два варианта:
| Функция | Что делает | Когда применять |
|---|---|---|
SELECT pg_cancel_backend(pid); | Отменяет текущий запрос, соединение остаётся | Первым делом |
SELECT pg_terminate_backend(pid); | Закрывает соединение целиком | Если отмена не сработала |
Не убивайте процессы PostgreSQL командой kill -9 из операционной системы: сервер СУБД воспримет это как аварию, перезапустит все соединения и пройдёт восстановление. Пострадают все базы на этом сервере.
💡 После отмены на стороне СУБД сервер 1С получит ошибку от СУБД. Сеанс пользователя может уйти в ошибку или закрыться. Это нормально — данные не портятся, транзакция откатывается.
Как писать запросы, чтобы консоль не зависала
Остановка — лечение. Профилактика дешевле: большинство «вечных» запросов в консоли — это ошибки в тексте, которые видно заранее.
- 🎯 Ограничивайте выборку при пробе. Пока отлаживаете, ставьте
ВЫБРАТЬ ПЕРВЫЕ 100. Убедились, что результат правильный, — убирайте ограничение. - 🎯 Отборы — в параметры виртуальных таблиц.
Остатки(&Дата, Склад = &Склад)работает быстрее, чем та же таблица с условием вГДЕ: отбор применяется до расчёта итогов. - 🎯 Заполняйте все параметры. Пустой параметр-ссылка или незаданная дата превращает отбор в выборку за всё время.
- 🎯 Не соединяйте с подзапросами. Вынесите подзапрос во временную таблицу через
ПОМЕСТИТЬ. Для полей соединения добавьтеИНДЕКСИРОВАТЬ ПО, если таблица крупная. - 🎯 Осторожно с ИЛИ в условиях соединения. Такое условие часто мешает СУБД использовать индекс. Иногда лучше разбить запрос на два и объединить через
ОБЪЕДИНИТЬ ВСЕ. - 🎯 Не разыменовывайте составные поля через точку.
Регистратор.Датау регистра с десятками видов регистраторов даёт соединение с каждой таблицей документа. - 🎯 Не гоняйте тяжёлые отчётные запросы в рабочее время по рабочей базе. Для разбора возьмите копию.
Для системного поиска медленных запросов включите технологический журнал с событием DBMSSQL (или DBPOSTGRS для PostgreSQL) и фильтром по длительности. Он покажет запросы дольше заданного порога, контекст их вызова и пользователя.
Когда всё зависло: аварийный порядок действий
Бывает, что не отвечает ни консоль, ни клиент, а пользователи жалуются на тормоза. Тогда важен порядок: сначала самое локальное, потом всё шире.
Отдельно про завершение rphost. Рабочий процесс обслуживает сеансы многих пользователей сразу. Если снять его в диспетчере задач, оборвутся все сеансы, закреплённые за ним, а не только ваш. Этот шаг — крайний, только когда консоль кластера не помогает и пользователи предупреждены.
После аварийной остановки проверьте:
- В консоли кластера не осталось «висящих» сеансов вашего пользователя.
- В СУБД нет долгих активных соединений по базе.
- Базу открывают другие пользователи, документы записываются без ошибок блокировки.
Если запрос перед остановкой что-то записывал — например, вы запускали обработку, а не только чтение, — транзакция откатилась целиком. Частично записанных данных не будет, но и результата обработки тоже. Запустите её заново, уже исправив запрос.
Частые вопросы
Можно ли задать в консоли запросов таймаут, чтобы запрос сам останавливался?
Запрос встроенного языка нет параметра времени выполнения. Ограничение можно поставить на стороне СУБД, но оно подействует на всю работу 1С с этой базой. Поэтому таймаут на одну консоль обычно не настраивают, а ограничивают выборку в самом запросе.Повредится ли база, если прервать запрос посередине?
Почему после удаления сеанса нагрузка на сервер СУБД не падает сразу?
KILL <id> WITH STATUSONLY. Пока откат идёт, блокировки сохраняются.Кто может прервать чужой запрос в консоли кластера?
Ctrl+Break сработал, но консоль снова зависает на том же запросе. Что делать?
ПЕРВЫЕ 100, проверьте параметры и посмотрите план в технологическом журнале или в инструментах СУБД.