Долгий запрос в 1С завис: как остановить его и не навредить данным

· 10 мин

Содержание

Прервать запрос в 1С быстрее всего сочетанием Ctrl+Break в окне, где он запущен. Если клиент не отвечает, запрос останавливают в консоли кластера (прерывают серверный вызов или завершают сеанс), а в крайнем случае — на стороне СУБД командой KILL в MS SQL или pg_cancel_backend() в PostgreSQL.

Типичная история: бухгалтер запустил оборотно-сальдовую ведомость за три года без отбора, и через десять минут у коллег начали «висеть» проведения документов. Ждать нельзя, но и рубить всё подряд опасно. Ниже способы прерывания разложены от самого мягкого к самому жёсткому, с тем, чем каждый рискует для базы данных.

Штатное прерывание запроса из самой 1С

Начинайте отсюда. Это единственный способ, при котором платформа сама аккуратно откатывает начатую операцию и сеанс пользователя остаётся живым.

Сочетание Ctrl+Break

  1. Переключитесь в окно 1С, где идёт долгая операция (отчёт, обработка, консоль запросов).
  2. Нажмите Ctrl+Break. На ноутбуках без клавиши Break обычно работает Ctrl+Fn+B или Ctrl+Fn+Pause — зависит от производителя.
  3. Платформа предложит прервать выполнение. Подтвердите.
  4. Дождитесь сообщения о прерывании. Если операция шла в транзакции, изменения откатятся.

💡 Прерывание срабатывает не мгновенно. Платформа проверяет его между обращениями к серверу и СУБД. Если сам SQL-запрос выполняется десять минут, Ctrl+Break подействует только после возврата управления на сервер 1С.

Закрыть форму фонового отчёта

В БП 3.0, ЗУП 3.1 и УТ 11 многие отчёты формируются фоновым заданием: в форме крутится индикатор ожидания, а остальной интерфейс доступен. Такое формирование привязано к форме. Закройте форму отчёта — и фоновое задание получит команду на отмену.

Отменить фоновое задание вручную

Если долгая операция идёт в фоне (обновление, перепроведение, загрузка данных), её видно в списке заданий:

  1. Откройте Администрирование → Обслуживание.
  2. В группе регламентных операций перейдите к списку регламентных и фоновых заданий.
  3. На закладке фоновых заданий найдите активное задание по имени и времени начала.
  4. Выделите его и отмените командой в командной панели списка.

Нужны полные права. Отмена — тот же мягкий механизм, что и Ctrl+Break: транзакция откатывается штатно.

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

Если окно клиента «Не отвечает» или пользователь ушёл домой с запущенным отчётом, переходите на сервер. Консоль администрирования серверов 1С показывает, что именно выполняет каждый сеанс.

Найти виновника

  1. Запустите консоль администрирования серверов 1С и раскройте кластер → Информационные базы → нужная база → Сеансы.
  2. Добавьте в список колонки времени: текущий вызов, время, захваченное СУБД, и соединение с СУБД. Набор колонок меняется через контекстное меню списка.
  3. Отсортируйте по времени текущего вызова. Сеанс с вызовом в сотни секунд и есть ваш кандидат.
  4. Запишите значение колонки соединения с СУБД — это номер процесса (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 предупредите пользователей: оборвутся все сеансы на этом процессе, несохранённые документы пропадут. Делайте это вне пиковых часов или после рассылки.

Если решились:

  1. В консоли кластера на узле рабочих процессов посмотрите PID процесса, в котором висит сеанс.
  2. Остановите именно его: taskkill /PID 1234 /F.
  3. Менеджер кластера сам поднимет новый рабочий процесс. Пользователи переподключатся.

В файловой базе сервера нет. Там зависший клиент — это процесс 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С получит ошибку обращения к СУБД.

Не завершайте соединения, номера которых не сверили с консолью кластера. Можно попасть в процесс регламентного обслуживания или в чужую базу на том же сервере СУБД.

Тайм-ауты и автоматическое прерывание долгих запросов

Если долгие запросы повторяются, ловить их руками надоедает. Есть два уровня автоматики.

Ограничения потребления ресурсов в кластере

В консоли кластера есть узлы счётчиков и ограничений потребления ресурсов. Логика такая:

  1. Создайте счётчик: что считать (например, длительность серверного вызова или время, захваченное СУБД) и по какому признаку группировать (пользователь, информационная база, имя приложения).
  2. Создайте ограничение на этот счётчик: порог и действие при превышении.
  3. Среди действий есть запись в технологический журнал, прерывание текущего серверного вызова и завершение сеанса.

💡 Первые две недели держите действие «записать в журнал». Посмотрите, кто реально упирается в порог. Иначе ограничение начнёт обрывать закрытие месяца или ночное обновление, которые законно идут долго.

Тайм-ауты на стороне СУБД

  • 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 способно повредить файл.

Как снизить риски

  1. Сначала мягкие способы: Ctrl+Break, прерывание вызова, pg_cancel_backend. Жёсткие — только если мягкие не сработали.
  2. Перед прерыванием пишущей операции выясните, что она делает и сколько успела. Посмотрите время начала вызова и операцию в консоли кластера.
  3. Если откат уже идёт — ждите. Перезапуск службы СУБД откат не отменит, а запустит восстановление при старте, и база будет недоступна ещё дольше.
  4. После жёсткого прерывания в файловой базе сделайте копию каталога базы и запустите Конфигуратор → Администрирование → Тестирование и исправление. Для быстрой проверки физической целостности есть утилита chdbfl.exe в каталоге bin платформы.

Тестирование и исправление требует монопольного доступа и может удалить битые объекты. Перед запуском — резервная копия каталога базы.

Отладчик и внешние инструменты

Когда запрос «висит» в собственной доработке, полезно не просто его прервать, а увидеть, на какой строке кода он стоит.

Отладчик конфигуратора

  1. Включите отладку на сервере: в клиент-серверном варианте служба агента запускается с ключом -debug.
  2. В конфигураторе откройте Отладка → Подключение и подключитесь к сеансу пользователя.
  3. Остановите выполнение командой остановки в меню Отладка. Отладчик покажет стек вызовов и строку модуля.

Отладка на рабочем сервере добавляет нагрузку. Включайте её на время разбора, а не постоянно.

Код, который можно прервать

Если вы пишете обработку с длинным циклом, вставьте в тело цикла вызов ОбработкаПрерыванияПользователя(). Без него Ctrl+Break в клиентском цикле может не сработать до конца перебора:

Для Каждого Строка Из ТаблицаДанных Цикл
    ОбработкаПрерыванияПользователя();
    // обработка строки
КонецЦикла;

Для серверных операций лучше вынести работу в фоновое задание — его можно отменить штатно.

Внешние инструменты

  • 📊 Технологический журнал с событиями DBMSSQL или DBPOSTGRS и отбором по длительности показывает, какие запросы долгие и из какого модуля они пришли.
  • 🧰 Activity Monitor в SSMS и представление pg_stat_activity — быстрый взгляд на текущие запросы и блокировки.
  • 🔍 Сторонние системы мониторинга производительности 1С собирают те же данные из журнала и СУБД в удобные графики. Они полезны при регулярных проблемах, а для разового случая хватает консоли кластера.

Профилактика: как не доводить до прерывания

Каждое прерывание — это потерянное время и риск. Дешевле убрать причину долгих запросов.

Пользовательские отчёты

  • 📅 Отборы по периоду и организации. Ведомость за три года по всем счетам — частый источник зависаний.
  • ⏳ Тяжёлые отчёты — в конце дня или в обед, а не в разгар проведения документов.
  • 🔁 Если отчёт нужен регулярно, вынесите его формирование в регламентное задание с рассылкой.

Доработки и запросы в коде

  • Запросы внутри циклов заменяйте одним пакетным запросом с временными таблицами.
  • Отборы по реквизитам составного типа и через точку («Документ.Контрагент.ИНН») порождают лишние соединения таблиц. Получайте данные явным соединением.
  • Используйте виртуальные таблицы регистров с условиями в параметрах (Остатки(&Дата, Склад = &Склад)), а не в ГДЕ после.
  • Проверяйте план запроса в СУБД, если запрос долгий на больших объёмах.

Обслуживание СУБД

  • Регулярное обновление статистики и перестроение индексов в MS SQL.
  • VACUUM и ANALYZE в PostgreSQL (autovacuum должен быть включён).
  • Свёртка или архивирование старых периодов, если база разрослась и отчёты по истории не нужны.
Регламент против долгих запросов
Выполнено: 0 / 5

Частые вопросы

Почему Ctrl+Break не прерывает запрос сразу?
Платформа проверяет прерывание между вызовами. Пока СУБД выполняет один тяжёлый SQL-запрос, управление на сервер 1С не возвращается, и прерывание сработает только после его окончания.
Можно ли прервать чужой запрос, не выкидывая пользователя из программы?
Да, в клиент-серверной базе: в консоли кластера прервите текущий серверный вызов сеанса. Пользователь увидит ошибку, но останется в программе.
Почему после KILL таблицы всё ещё заблокированы?
Идёт откат транзакции. Прогресс показывает KILL с параметром WITH STATUSONLY. Блокировки снимутся после завершения отката.
Опасно ли прерывать формирование отчёта?
Нет. Отчёт только читает данные, откатывать нечего. Риск есть у операций записи: проведения, перепроведения, загрузки, обновления.
Как понять, какой SQL-запрос относится к сеансу 1С?
В консоли кластера у сеанса есть колонка соединения с СУБД. Её значение совпадает с session_id в MS SQL или pid в PostgreSQL.