Как затормозить и оптимизировать восстановление последовательности документов по времени в 1С 7.7

Программист 1С v7.7
← На главную

При обслуживании крупных и давно эксплуатируемых баз данных на платформе 1С:Предприятие 7.7 администраторы и разработчики часто сталкиваются с проблемой долгого восстановления границы последовательности (ГП). Стандартный механизм восстановления последовательности работает в монопольном режиме и "до победного конца". Если база большая, а пользователи залезли "задним числом" на год или два назад, процесс проведения документов может затянуться на десятки часов.

Главная сложность заключается в том, что прервать стандартное восстановление безболезненно нельзя: Точка Актуальности (ТА) останется смещенной назад, итоги "поплывут", и базу нельзя будет открыть для полноценной работы пользователей в начале рабочего дня. В этой статье мы подробно рассмотрим, как программно контролировать процесс восстановления последовательности, останавливать его в заданное время без ущерба для итогов и существенно ускорять проведение документов.

Понимание механизмов: Граница последовательности (ГП) и Точка актуальности (ТА)

Прежде чем переходить к алгоритмам остановки, давайте разберем физику процесса в 1С 7.7. В платформе существуют два важнейших понятия:

Когда мы запускаем штатное восстановление последовательности, платформа временно сдвигает ТА назад, на позицию восстанавливаемого документа, и начинает последовательно проводить документы один за другим, постепенно двигая ТА вперед. Если мы грубо прервем этот процесс (например, снимем задачу в диспетчере задач), ТА останется глубоко в прошлом. При попытке пользователей работать в такой базе начнется хаос: выписка документов сегодняшним днем будет вызывать пересчет итогов "на лету" за весь пропущенный период, что намертво заблокирует базу данных.

Решение 1: Собственная обработка проведения с контролем времени

Самый надежный способ контролировать время проведения — отказаться от штатного монопольного восстановления последовательности и написать собственную обработку. Мы можем выбирать документы, входящие в последовательность, и проводить их поочередно. Перед проведением каждого документа мы будем проверять текущее системное время компьютера. Если лимит времени исчерпан (например, наступило 07:30 утра), обработка прекратит работу, корректно перенесет ТА на последний успешно проведенный документ и завершит работу системы.

Проанализируем пример кода для такой обработки. Для этого мы используем объект Последовательность и метод УстановитьТаНаДокумент().


Процедура ВосстановитьПоследовательностьСКонтролемВремени()
    
    // Определяем время, когда необходимо гарантированно завершить работу
    ВремяОстанова = "07:30:00";
    
    // Получаем последовательность по ее идентификатору (например, Основная)
    Послед = Последовательности.Получить("Основная");
    
    // Определяем документ границы последовательности
    ДокГраницы = Послед.ПолучитьГраницу();
    
    Если ПустоеЗначение(ДокГраницы) = 1 Тогда
        Предупреждение("Последовательность уже восстановлена!");
        Возврат;
    КонецЕсли;
    
    // Запоминаем исходную ТА, чтобы знать, куда нам нужно вернуться в идеале
    ИсходнаяТА = ПолучитьТА();
    
    // Создаем выборку документов, начиная с границы последовательности
    ВыборкаДоков = СоздатьОбъект("Документ");
    ВыборкаДоков.ВыбратьДокументы(ПолучитьДатуДокумента(ДокГраницы), РабочаяДата());
    
    Пока ВыборкаДоков.ПолучитьДокумент() = 1 Цикл
        
        // Проверяем, входит ли документ в нашу последовательность
        Если Послед.Принадлежит(ВыборкаДоков.ТекущийДокумент()) = 0 Тогда
            Продолжить;
        КонецЕсли;
        
        // Проверяем лимит времени перед проведением очередного документа
        Если ТекущееВремя() >= ВремяОстанова Тогда
            Сообщить("Достигнут лимит времени! Процесс останавливается.");
            Прервать;
        КонецЕсли;
        
        // Чтобы избежать нарушения итогов, перед проведением документа сдвигаем ТА
        // Параметр -1 означает установку ТА непосредственно ПЕРЕД документом
        УстановитьТаНаДокумент(ВыборкаДоков.ТекущийДокумент(), -1);
        
        // Проводим документ
        Попытка
            ВыборкаДоков.Провести();
            Сообщить("Успешно проведен документ: " + ВыборкаДоков.ТекущийДокумент());
        Исключение
            Сообщить("Ошибка проведения документа: " + ВыборкаДоков.ТекущийДокумент() + ". Восстановление прервано.");
            Прервать;
        КонецПопытки;
        
    КонецЦикла;
    
    // Корректно возвращаем ТА на место последнего проведенного документа
    // или на исходную ТА, если проведение завершилось полностью.
    // Это предотвратит "зависание" итогов в прошлом.
    Если ВыборкаДоков.Выбран() = 1 Тогда
        УстановитьТаНаДокумент(ВыборкаДоков.ТекущийДокумент(), 1);
    Иначе
        УстановитьТаНаДокумент(ИсходнаяТА, 1);
    EndIf;
    
КонецПроцедуры

Рассмотрим подробнее логику этого кода. Метод УстановитьТаНаДокумент(Документ, -1) сдвигает точку актуальности непосредственно перед проведением документа. После успешного проведения мы можем сдвинуть ТА на этот документ с параметром 1 (что означает "после документа"). Таким образом, в любой момент остановки наши итоги всегда будут рассчитаны строго на актуальный момент времени, и база останется в работоспособном состоянии.

Решение 2: Оптимизация процесса проведения (Исключение неактуальных документов)

Часто в последовательность включено слишком много типов документов, проведение которых не влияет на конечную себестоимость или взаиморасчеты (например, ЗаявкаПокупателя, СчетНаОплату и т.д.). Проведение таких документов отнимает драгоценное процессорное время.

Выясним причину замедления и применим "умный" пропуск:

  1. Проанализируем структуру конфигурации и определим, какие документы реально делают движения по регистрам остатков и влияют на партии товаров (например, РасходнаяНакладная, ПоступлениеТоваров).
  2. В нашей кастомной обработке добавим жесткий фильтр по видам документов. Если текущий документ из выборки не влияет на партионный учет, мы можем просто программно сдвинуть границу последовательности мимо него с помощью метода УстановитьТаНаДокумент(Документ, 1) без физического вызова метода Провести().

Решение 3: Перенос временных файлов базы данных на RAM-диск

Выясним еще одну важную техническую причину, по которой 1С 7.7 медленно проводит документы. При проведении документов и обращении к регистрам (так называемые "черные запросы") платформа 1С 7.7 очень активно работает со своим каталогом временных файлов (обычно это системный каталог Temp пользователя). Платформа постоянно создает, пишет и читает временные файлы с флагом отключения кэширования операционной системы.

Чтобы ускорить этот процесс в несколько раз, выполним следующие шаги:

  1. Создадим в оперативной памяти сервера так называемый RAM-диск (виртуальный диск, физически расположенный в оперативной памяти компьютера) объемом от 1 до 4 ГБ с помощью сторонних утилит (например, ImDisk).
  2. Перенаправим переменные окружения пользователя TEMP и TMP в сеансе, где запускается восстановление последовательности, на этот созданный RAM-диск.
  3. При перепроведении скорость дисковых операций чтения-записи временных файлов возрастет колоссально, что даст прирост скорости восстановления последовательности до 50–200% в зависимости от дисковой подсистемы сервера.

Решение 4: Проведение на копии с последующим переносом данных

Если база данных работает в режиме 24/7 и монопольного времени ночью критически не хватает, рассмотрим архитектурный обходной путь с использованием распределенных баз данных или копий:

  1. Делаем резервную копию рабочей базы данных после окончания рабочего дня.
  2. Разворачиваем копию базы на отдельном производительном сервере (желательно в файловом DBF-варианте на быстром локальном NVMe SSD или RAM-диске, так как файловая 1С 7.7 в один поток на высокой тактовой частоте процессора проводит документы быстрее, чем MS SQL).
  3. Запускаем восстановление последовательности на копии. Процесс может идти весь следующий рабочий день на отдельной машине, не мешая пользователям.
  4. После завершения восстановления мы можем перенести измененные таблицы итогов и последовательностей обратно в рабочую базу данных во время технологического окна (например, ночью за 5 минут), либо воспользоваться механизмами УРИБ (распределенных баз данных) для автообмена измененными объектами.

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

Решение 5: Работа в разделенном режиме с паузами

Если монопольно запустить базу нет никакой возможности, можно организовать проведение документов в разделенном (сетевом) режиме в фоновом режиме даже в рабочее время. Чтобы наша обработка не вешала базу и не вызывала постоянных ошибок блокировки таблиц (знаменитое Ожидание блокировки базы данных...), перед проведением каждого документа нужно вставлять контролируемую паузу.

В 1С 7.7 это можно сделать элегантным способом через открытие модального окна предупреждения с таймаутом:


// Пауза в 2 секунды между документами дает возможность СУБД обработать
// транзакции других пользователей и предотвращает эскалацию блокировок
Вопрос("Продолжить проведение?", "Да+Нет", 2);

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

Используя приведенные методики и комбинируя их под специфику вашей конфигурации, вы сможете полностью контролировать время работы регламентных процедур и минимизировать простои пользователей.

← На главную