Как удалить помеченные объекты в большой базе 1С 7.7 на MS SQL при нехватке памяти и зависании выгрузки?

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

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

Почему зависает выгрузка и падает удаление объектов

Проанализируем технические ограничения платформы 1С 7.7, которые приводят к возникновению этих сбоев:

  1. Однопоточность и блокировка интерфейса: Платформа 1С 7.7 является 32-битным приложением с единым потоком выполнения. При обработке монопольной операции ядро процессора загружается на 100% (что на 4-ядерном ЦП отображается как 25–32% суммарной загрузки). В этот момент приложение перестает обрабатывать оконные сообщения операционной системы, статус в диспетчере задач переходит в режим «Не отвечает», а строка состояния замирает на последней операции — например, Установка соединения с сервером базы данных.
  2. Ограничение архиватора ZIP на отметке 2 Гб: В платформу 7.7 встроен архиватор старого формата без поддержки 64-битных расширений Zip64. Если суммарный объем выгружаемых таблиц или итоговый файл превышает лимит в 2 Гб, выгрузка завершится аварийным сбоем. Для базы объемом 70 Гб штатный механизм выгрузки неприменим.
  3. Лимит адресного пространства процесса 32-bit: При штатном поиске ссылок система строит в оперативной памяти единый граф ссылочной целостности по всем таблицам. 32-битному процессу Windows по умолчанию выделяет до 2 Гб виртуального адресного пространства (из-за фрагментации памяти крах происходит уже при достижении 1.2–1.5 Гб), в результате чего вызов штатного диалога поиска ссылок падает с сообщением о нехватке памяти.

Способ 1. Оптимизация среды и пакетное удаление штатными средствами

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

Посмотрим на пример пакетного удаления документов по временным интервалам с использованием компоненты 1CPP и встроенной функции УдалитьОбъекты():


лДата = глДатаЗапрета;
Пока лДата <= ПолучитьДатуТА() Цикл
    Текст = "
    |SELECT
    |   j.iddoc [Док $Документ],
    |   j.iddocdef Док_вид
    |FROM _1sjourn j (nolock)
    |WHERE
    |   j.ismark = 1
    |   AND j.date_time_iddoc <= :ВыбДата~
    |";
    ИТЗ = СоздатьОбъект("ИндексированнаяТаблица");
    Список = СоздатьОбъект("СписокЗначений");
    
    Запрос = СоздатьОбъект("ODBCRecordset");
    Запрос.УстановитьТекстовыйПараметр("ВыбДата", лДата);
    Состояние("Удаление документов за период до " + лДата);
    
    Запрос.ВыполнитьИнструкцию(Текст, ИТЗ);
    ИТЗ.Выгрузить(Список, , "Док");
    
    // Удаляем порцию объектов с контролем ссылочной целостности
    УдалитьОбъекты(Список, 1);
    
    лДата = ДобавитьМесяц(лДата, 12);
КонецЦикла;

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

Дополнительно на 64-битной серверной ОС можно расширить лимит оперативной памяти для процесса 1cv7s.exe с 2 Гб до 4 Гб, установив флаг IMAGE_FILE_LARGE_ADDRESS_AWARE в заголовке исполняемого файла с помощью системной утилиты. Это предотвратит вылеты по нехватке памяти при обработке средних объемов ссылок.

Способ 2. Прямое удаление данных средствами MS SQL Server

Когда база имеет огромный объем и штатное удаление работает недопустимо долго, эффективным решением становится удаление записей прямыми запросами к таблицам MS SQL Server с помощью компоненты прямого доступа (например, через внешнюю библиотеку 1cpp.dll).

Рассмотрим структуру прямого очищения таблиц документов, проводок, движений регистров и системных журналов 1С 7.7:


SQL_db = СоздатьОбъект("ODBCDatabase");
SQL_db.Attach1C(); 
рс = СоздатьОбъект("ODBCRecordset");

// 1. Очистка строк документов заданного вида
ТекстЗапроса = "
|DELETE Док
|FROM $ДокументСтроки.РасходнаяНакладная as Док
|INNER JOIN _1SJourn ON _1SJourn.IDDoc = Док.IDDoc
|WHERE _1SJourn.Date_Time_IDDoc BETWEEN :НачДата AND :КонДата~
|";
рс.УстановитьТекстовыйПараметр("НачДата", НачДата);
рс.УстановитьТекстовыйПараметр("КонДата", КонДата);
рс.ВыполнитьИнструкцию(ТекстЗапроса);

// 2. Очистка шапок документов
ТекстЗапроса = "
|DELETE Док
|FROM $Документ.РасходнаяНакладная as Док
|INNER JOIN _1SJourn ON _1SJourn.IDDoc = Док.IDDoc
|WHERE _1SJourn.Date_Time_IDDoc BETWEEN :НачДата AND :КонДата~
|";
рс.ВыполнитьИнструкцию(ТекстЗапроса);

// 3. Очистка проводок бухгалтерского учета
ТекстЗапроса = "
|DELETE Пров
|FROM _1SENTRY as Пров
|INNER JOIN _1SJourn ON _1SJourn.IDDoc = Пров.DocID
|WHERE _1SJourn.Date_Time_IDDoc BETWEEN :НачДата AND :КонДата~
|";
рс.ВыполнитьИнструкцию(ТекстЗапроса);

// 4. Очистка журнала документов
ТекстЗапроса = "
|DELETE FROM _1SJourn
|WHERE Date_Time_IDDoc BETWEEN :НачДата AND :КонДата~
|";
рс.ВыполнитьИнструкцию(ТекстЗапроса);

При использовании прямых SQL-запросов важно соблюдать последовательность зависимостей:

  1. Сначала очищаются подчиненные строки документов ($ДокументСтроки) и движения регистров ($Регистр).
  2. Затем удаляются записи проводок (_1SENTRY), периодические константы (_1SCONST) и системные операции (_1SOPER).
  3. Удаляются подчиненные ссылки в таблице перекрестных ссылок (_1SCRDOC).
  4. Удаляются шапки документов ($Документ).
  5. В последнюю очередь удаляются записи из основного журнала регистрации документов (_1SJOURN).

Обслуживание базы после очистки на MS SQL Server

При прямом массовом удалении данных лог транзакций СУБД начинает активно увеличиваться. В среде MS SQL Server 2008 устаревшая конструкция BACKUP LOG ... WITH TRUNCATE_ONLY больше не поддерживается. Чтобы уменьшить размер журналов и вернуть дисковое пространство, переведем базу данных в простую модель восстановления (Simple) и выполним усечение через команду DBCC SHRINKFILE.

По завершении прямых манипуляций с таблицами MS SQL обязательно запустим процедуру Тестирование и исправление ИБ в монопольном режиме конфигуратора для пересчета итогов и проверки ссылочной целостности базы данных.

← На главную