Как правильно свернуть крупную базу 1С:УПП на MS SQL Server и чем опасны прямые манипуляции с таблицами СУБД?

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

Когда информационная база 1С приближается к объему в терабайт, регламентные операции и обслуживание СУБД начинают требовать значительных ресурсов. Возникает закономерный вопрос: можно ли ускорить процесс свертки, обойдя длительные стандартные механизмы 1С и выполнив манипуляции напрямую на уровне MS SQL Server? Разберем, какие риски несет подмена таблиц СУБД в обход платформы и какие практические сценарии свертки являются надежными и эффективными.

Почему нельзя просто подменить таблицы регистров на уровне MS SQL Server

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

  1. Рассинхронизация таблиц движений и итогов. У регистров накопления и бухгалтерии в структуре СУБД физически разделены таблицы движений и таблицы итогов (а также агрегатов). Если подменить только таблицу движений, таблицы итогов останутся со старыми данными. Любые виртуальные таблицы платформы (Остатки, ОстаткиИОбороты) продолжат выдавать неверные данные, пока не будет выполнен полный технологический пересчет итогов.
  2. Потеря целостности служебных механизмов платформы. При прямом удалении или подмене данных нарушается целостность в таблицах регистрации изменений планов обмена, таблицах границ последовательностей документов и индексах полнотекстового поиска. В планах обмена останутся миллионы «мертвых» ссылок на удаленные документы, что может полностью заблокировать синхронизацию.
  3. Специфика учета в УПП (РАУЗ и НДС). Если в конфигурации включен режим РАУЗ (расширенная аналитика учета затрат), регистры учета затрат оперируют не прямыми ссылками на номенклатуру, а ключами аналитики. Отрезав движения без сохранения связей в регистрах сведений ключей аналитики, мы получим неработоспособный расчет себестоимости. В подсистеме НДС незакрытые цепочки авансовых счетов-фактур и распределения входящего НДС при удалении прошлых документов приведут к ошибкам в регламентных операциях закрытия месяца.
  4. Поведение MS SQL при удалении данных. Простое удаление строк оператором DELETE или копирование таблиц не возвращает место операционной системе. Страницы помечаются как свободные внутри файлов данных .mdf. Попытка уменьшить файл через DBCC SHRINKFILE вызовет экстремальную фрагментацию индексов (до 90–99%), а последующая дефрагментация или перестроение индексов (REBUILD) снова увеличит файл базы. Кроме того, массовое удаление в модели восстановления Full приведет к лавинообразному росту файла транзакционного лога .ldf.

Предварительный анализ: действительно ли нужна свертка?

Прежде чем приступать к удалению учетных данных, проанализируем реальное распределение объема внутри базы. Практика показывает, что свертка редко уменьшает базу более чем на 20–30%, при этом пользователи лишаются оперативного доступа к ретроспективным отчетам. Проверим альтернативные источники разрастания базы:

  1. Хранение файлов в теле базы данных. В УПП сканы документов и файлы нередко хранятся в двоичном виде непосредственно в таблицах информационной базы. Перенос файлов в сетевые тома на диск разгружает базу без удаления учетных данных.
  2. Журнал регистрации и версионирование. Убедимся, что база не раздута за счет хранения миллионов записей версий объектов или некорректно настроенного журнала регистрации.
  3. Сжатие данных на уровне СУБД (Page Compression). Включение страничного сжатия таблиц и индексов средствами MS SQL Enterprise позволяет уменьшить фактический размер базы на диске в 2–3 раза без изменения метаданных и удаления истории.

Сценарий 1. Свертка через перенос в чистую базу или планы обмена

Наиболее безопасный и рекомендуемый способ сокращения размера рабочей базы — оставить текущую базу в качестве архивной (только для чтения), а рабочую среду сформировать заново:

  1. Создаем документ ввода остатков (корректировки записей регистров) на дату свертки в исходной базе.
  2. Настраиваем план обмена или перенос через универсальный обмен данными в новую чистую базу.
  3. Переносим нормативно-справочную информацию, сформированные документы ввода остатков и документы за актуальный несвернутый период.
  4. Переключаем пользователей в новую компактную базу. В этом случае мы получаем чистые индексы, отсутствие фрагментации и гарантированную ссылочную целостность без «зависших» записей.

Сценарий 2. Гибридная свертка внутри текущей базы

Если создание новой базы невозможно, свертку выполняют непосредственно в рабочей базе, комбинируя штатные механизмы 1С для сохранения целостности и порционную обработку:

  1. Установка запрета редактирования. Устанавливаем дату запрета изменения данных в 1С до момента свертки, чтобы зафиксировать состояние прошлых периодов.
  2. Формирование остатков средствами 1С. Формируем документы ввода остатков (корректировки записей регистров) на выбранную дату с отключенной активностью движений, чтобы они не влияли на текущие итоги во время подготовки.
  3. Отключение итогов на время манипуляций. При массовом изменении регистров накопления и бухгалтерии временно отключаем итоги через встроенный язык: РегистрыНакопления.УчетЗатрат.УстановитьИспользованиеИтогов(Ложь); Это позволяет многократно ускорить запись новых документов и удаление старых движений.
  4. Порционное удаление движений и документов. Массовое удаление объектов штатными средствами должно выполняться небольшими порциями (транзакциями по 5 000 – 30 000 записей), чтобы избежать разрастания журнала транзакций и блокировок:
    
    Выборка = Документы.РеализацияТоваровУслуг.Выбрать(ДатаНачала, ДатаСвертки);
    Счетчик = 0;
    НачатьТранзакцию();
    Пока Выборка.Следующий() Цикл
        ДокументОбъект = Выборка.ПолучитьОбъект();
        // Очищаем движения или помечаем на удаление
        ДокументОбъект.Движения.Очистить();
        ДокументОбъект.Записать(РежимЗаписиДокумента.Запись);
        
        Счетчик = Счетчик + 1;
        Если Счетчик % 1000 = 0 Тогда
            ЗафиксироватьТранзакцию();
            НачатьТранзакцию();
        КонецЕсли;
    КонецЦикла;
    ЗафиксироватьТранзакцию();
    
  5. Включение и пересчет итогов. После активации сформированных документов ввода остатков и очистки движений прошлых периодов выполняем обратное включение и пересчет итогов:
    
    РегистрыНакопления.УчетЗатрат.УстановитьИспользованиеИтогов(Истина);
    РегистрыНакопления.УчетЗатрат.ПересчитатьИтоги();
    
  6. Очистка и реиндексация на уровне СУБД. После завершения операций в 1С выполняем регламентное перестроение индексов (ALTER INDEX ... REBUILD) и обновление статистик на SQL Server, чтобы СУБД перестроила планы запросов с учетом изменившегося объема данных.
← На главную