Долгий запрос в 1С завис: как остановить его и не навредить данным
Содержание
Прервать запрос в 1С быстрее всего сочетанием Ctrl+Break в окне, где он запущен. Если клиент не отвечает, запрос останавливают в консоли кластера (прерывают серверный вызов или завершают сеанс), а в крайнем случае — на стороне СУБД командой KILL в MS SQL или pg_cancel_backend() в PostgreSQL.
Типичная история: бухгалтер запустил оборотно-сальдовую ведомость за три года без отбора, и через десять минут у коллег начали «висеть» проведения документов. Ждать нельзя, но и рубить всё подряд опасно. Ниже способы прерывания разложены от самого мягкого к самому жёсткому, с тем, чем каждый рискует для базы данных.
Штатное прерывание запроса из самой 1С
Начинайте отсюда. Это единственный способ, при котором платформа сама аккуратно откатывает начатую операцию и сеанс пользователя остаётся живым.
Сочетание Ctrl+Break
- Переключитесь в окно 1С, где идёт долгая операция (отчёт, обработка, консоль запросов).
- Нажмите
Ctrl+Break. На ноутбуках без клавиши Break обычно работаетCtrl+Fn+BилиCtrl+Fn+Pause— зависит от производителя. - Платформа предложит прервать выполнение. Подтвердите.
- Дождитесь сообщения о прерывании. Если операция шла в транзакции, изменения откатятся.
💡 Прерывание срабатывает не мгновенно. Платформа проверяет его между обращениями к серверу и СУБД. Если сам SQL-запрос выполняется десять минут, Ctrl+Break подействует только после возврата управления на сервер 1С.
Закрыть форму фонового отчёта
В БП 3.0, ЗУП 3.1 и УТ 11 многие отчёты формируются фоновым заданием: в форме крутится индикатор ожидания, а остальной интерфейс доступен. Такое формирование привязано к форме. Закройте форму отчёта — и фоновое задание получит команду на отмену.
Отменить фоновое задание вручную
Если долгая операция идёт в фоне (обновление, перепроведение, загрузка данных), её видно в списке заданий:
- Откройте
Администрирование → Обслуживание. - В группе регламентных операций перейдите к списку регламентных и фоновых заданий.
- На закладке фоновых заданий найдите активное задание по имени и времени начала.
- Выделите его и отмените командой в командной панели списка.
Нужны полные права. Отмена — тот же мягкий механизм, что и Ctrl+Break: транзакция откатывается штатно.
Как прервать долгий запрос в консоли кластера 1С
Если окно клиента «Не отвечает» или пользователь ушёл домой с запущенным отчётом, переходите на сервер. Консоль администрирования серверов 1С показывает, что именно выполняет каждый сеанс.
Найти виновника
- Запустите консоль администрирования серверов 1С и раскройте кластер →
Информационные базы→ нужная база →Сеансы. - Добавьте в список колонки времени: текущий вызов, время, захваченное СУБД, и соединение с СУБД. Набор колонок меняется через контекстное меню списка.
- Отсортируйте по времени текущего вызова. Сеанс с вызовом в сотни секунд и есть ваш кандидат.
- Запишите значение колонки соединения с СУБД — это номер процесса (SPID в MS SQL, pid в PostgreSQL). Он пригодится, если придётся идти в СУБД.
Три действия от мягкого к жёсткому
| Действие | Что происходит | Когда применять | Риски |
|---|---|---|---|
| Прервать текущий серверный вызов | Платформа останавливает текущую серверную операцию, пользователь получает ошибку с вашим текстом, сеанс остаётся | Первое, что пробовать | Минимальные: транзакция откатывается |
| Завершить сеанс | Сеанс удаляется, клиент получает сообщение о разрыве | Вызов не прерывается, пользователь недоступен | Несохранённые данные пользователя теряются |
| Остановить процесс rphost | Убиваются все сеансы этого рабочего процесса | Процесс целиком завис, остальное не помогло | Оборвутся сеансы всех пользователей на этом процессе |
Прерывание серверного вызова появилось в платформе 8.3 не сразу, поэтому в старых сборках его в контекстном меню сеанса нет. В актуальных версиях оно есть и в консоли, и в утилите rac.
То же самое через rac
На серверах без графической консоли удобнее командная строка. Нужен запущенный сервис ras.
rac cluster list
rac session list --cluster=<uuid-кластера>
rac session interrupt-current-server-call --cluster=<uuid-кластера> --session=<uuid-сеанса> --error-message="Запрос остановлен администратором"
rac session terminate --cluster=<uuid-кластера> --session=<uuid-сеанса>
Если кластер защищён паролем, добавьте --cluster-user и --cluster-pwd. Точный набор параметров для вашей сборки платформы смотрите в rac session help.
Диспетчер задач Windows: когда процесс уже не жалко
rphost.exe в диспетчере задач обслуживает десятки сеансов одновременно. Завершить его ради одного запроса — то же, что выключить свет во всём офисе, чтобы погасить одну лампу.
Перед остановкой rphost предупредите пользователей: оборвутся все сеансы на этом процессе, несохранённые документы пропадут. Делайте это вне пиковых часов или после рассылки.
Если решились:
- В консоли кластера на узле рабочих процессов посмотрите PID процесса, в котором висит сеанс.
- Остановите именно его:
taskkill /PID 1234 /F. - Менеджер кластера сам поднимет новый рабочий процесс. Пользователи переподключатся.
В файловой базе сервера нет. Там зависший клиент — это процесс 1cv8.exe или 1cv8c.exe на компьютере пользователя. Его снимают через диспетчер задач, но это самый рискованный вариант из всех (см. раздел о рисках).
Прерывание запросов на уровне СУБД
Иногда сервер 1С показывает, что сеанс ждёт ответа от СУБД, а прерывание вызова не срабатывает, потому что SQL-запрос ещё не вернул управление. Тогда запрос останавливают в самой СУБД.
MS SQL Server
Найдите долгие запросы в SQL Server Management Studio:
SELECT r.session_id,
r.status,
r.wait_type,
r.blocking_session_id,
r.total_elapsed_time / 1000 AS sec,
t.text
FROM sys.dm_exec_requests r
CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) t
WHERE r.session_id <> @@SPID
ORDER BY r.total_elapsed_time DESC;
Сверьте session_id с номером соединения из консоли кластера и остановите запрос:
KILL 87;
-- проверить ход отката:
KILL 87 WITH STATUSONLY;
KILL не отменяет работу мгновенно. Если запрос успел изменить много строк, SQL Server откатывает транзакцию, и откат может идти столько же, сколько шла запись. Блокировки держатся до конца отката.
PostgreSQL
SELECT pid, state, now() - query_start AS duration, left(query, 120) AS query
FROM pg_stat_activity
WHERE state <> 'idle'
ORDER BY duration DESC;
Дальше два уровня:
- 🟢
SELECT pg_cancel_backend(12345);— отменяет текущий запрос, соединение остаётся. Начните с него. - 🔴
SELECT pg_terminate_backend(12345);— разрывает соединение целиком. Сеанс 1С получит ошибку обращения к СУБД.
Не завершайте соединения, номера которых не сверили с консолью кластера. Можно попасть в процесс регламентного обслуживания или в чужую базу на том же сервере СУБД.
Тайм-ауты и автоматическое прерывание долгих запросов
Если долгие запросы повторяются, ловить их руками надоедает. Есть два уровня автоматики.
Ограничения потребления ресурсов в кластере
В консоли кластера есть узлы счётчиков и ограничений потребления ресурсов. Логика такая:
- Создайте счётчик: что считать (например, длительность серверного вызова или время, захваченное СУБД) и по какому признаку группировать (пользователь, информационная база, имя приложения).
- Создайте ограничение на этот счётчик: порог и действие при превышении.
- Среди действий есть запись в технологический журнал, прерывание текущего серверного вызова и завершение сеанса.
💡 Первые две недели держите действие «записать в журнал». Посмотрите, кто реально упирается в порог. Иначе ограничение начнёт обрывать закрытие месяца или ночное обновление, которые законно идут долго.
Тайм-ауты на стороне СУБД
- PostgreSQL — параметр
statement_timeout. Ставить его глобально или пользователю, под которым ходит 1С, нельзя: оборвутся длинные штатные операции. Разумное применение — отдельная роль для внешних отчётных подключений (BI, выгрузки):
ALTER ROLE report_reader SET statement_timeout = '10min';
- MS SQL Server — серверного тайм-аута на выполнение запроса нет. Тайм-аут задаёт клиентское приложение, а у 1С он не настраивается. Ограничивать время выполнения в MS SQL приходится через консоль кластера.
Ожидание блокировок
Отдельный случай — запрос не считает, а ждёт, пока другой сеанс снимет блокировку. Для управляемых блокировок у платформы своё время ожидания, по истечении которого пользователь видит Конфликт блокировок при выполнении транзакции. Прерывать такой запрос бессмысленно: прерывать нужно того, кто держит блокировку. Его видно в MS SQL по колонке blocking_session_id из запроса выше.
Чем рискует база при прерывании запроса и как снизить риски
Сам по себе запрос на чтение (отчёт) прерывать безопасно: он ничего не пишет. Проблемы начинаются, когда в момент прерывания идёт запись.
Что может случиться
- 🔄 Долгий откат. Прерванная транзакция откатывается целиком. Перепроведение за квартал, прерванное на 90%, откатит все 90%, и это займёт время.
- 🔒 Блокировки на время отката. Пока СУБД откатывает изменения, заблокированные таблицы недоступны. Повторный
KILLничего не ускоряет. - 📄 Потеря несохранённых данных. При завершении сеанса пользователь теряет открытые несохранённые формы.
- 🧩 Логическая неполнота. Если обработка проводит документы по одному, каждый в своей транзакции, прерывание остановит её на середине: часть документов проведена, часть нет. Структура базы цела, но учёт неполный.
- 💥 Повреждение файловой базы. В клиент-серверном варианте целостность данных обеспечивает СУБД. В файловом снятие процесса во время записи в
1Cv8.1CDспособно повредить файл.
Как снизить риски
- Сначала мягкие способы:
Ctrl+Break, прерывание вызова,pg_cancel_backend. Жёсткие — только если мягкие не сработали. - Перед прерыванием пишущей операции выясните, что она делает и сколько успела. Посмотрите время начала вызова и операцию в консоли кластера.
- Если откат уже идёт — ждите. Перезапуск службы СУБД откат не отменит, а запустит восстановление при старте, и база будет недоступна ещё дольше.
- После жёсткого прерывания в файловой базе сделайте копию каталога базы и запустите
Конфигуратор → Администрирование → Тестирование и исправление. Для быстрой проверки физической целостности есть утилитаchdbfl.exeв каталогеbinплатформы.
Тестирование и исправление требует монопольного доступа и может удалить битые объекты. Перед запуском — резервная копия каталога базы.
Отладчик и внешние инструменты
Когда запрос «висит» в собственной доработке, полезно не просто его прервать, а увидеть, на какой строке кода он стоит.
Отладчик конфигуратора
- Включите отладку на сервере: в клиент-серверном варианте служба агента запускается с ключом
-debug. - В конфигураторе откройте
Отладка → Подключениеи подключитесь к сеансу пользователя. - Остановите выполнение командой остановки в меню
Отладка. Отладчик покажет стек вызовов и строку модуля.
Отладка на рабочем сервере добавляет нагрузку. Включайте её на время разбора, а не постоянно.
Код, который можно прервать
Если вы пишете обработку с длинным циклом, вставьте в тело цикла вызов ОбработкаПрерыванияПользователя(). Без него Ctrl+Break в клиентском цикле может не сработать до конца перебора:
Для Каждого Строка Из ТаблицаДанных Цикл
ОбработкаПрерыванияПользователя();
// обработка строки
КонецЦикла;
Для серверных операций лучше вынести работу в фоновое задание — его можно отменить штатно.
Внешние инструменты
- 📊 Технологический журнал с событиями
DBMSSQLилиDBPOSTGRSи отбором по длительности показывает, какие запросы долгие и из какого модуля они пришли. - 🧰 Activity Monitor в SSMS и представление
pg_stat_activity— быстрый взгляд на текущие запросы и блокировки. - 🔍 Сторонние системы мониторинга производительности 1С собирают те же данные из журнала и СУБД в удобные графики. Они полезны при регулярных проблемах, а для разового случая хватает консоли кластера.
Профилактика: как не доводить до прерывания
Каждое прерывание — это потерянное время и риск. Дешевле убрать причину долгих запросов.
Пользовательские отчёты
- 📅 Отборы по периоду и организации. Ведомость за три года по всем счетам — частый источник зависаний.
- ⏳ Тяжёлые отчёты — в конце дня или в обед, а не в разгар проведения документов.
- 🔁 Если отчёт нужен регулярно, вынесите его формирование в регламентное задание с рассылкой.
Доработки и запросы в коде
- Запросы внутри циклов заменяйте одним пакетным запросом с временными таблицами.
- Отборы по реквизитам составного типа и через точку («Документ.Контрагент.ИНН») порождают лишние соединения таблиц. Получайте данные явным соединением.
- Используйте виртуальные таблицы регистров с условиями в параметрах (
Остатки(&Дата, Склад = &Склад)), а не вГДЕпосле. - Проверяйте план запроса в СУБД, если запрос долгий на больших объёмах.
Обслуживание СУБД
- Регулярное обновление статистики и перестроение индексов в MS SQL.
VACUUMиANALYZEв PostgreSQL (autovacuum должен быть включён).- Свёртка или архивирование старых периодов, если база разрослась и отчёты по истории не нужны.