При обслуживании объемных информационных баз 1С:Предприятия 7.7 (в особенности размером более нескольких десятков гигабайт) администраторы и разработчики часто сталкиваются с ситуацией, когда штатные сервисные механизмы перестают работать. Попытка выполнить стандартное удаление помеченных объектов завершается ошибкой Не хватает памяти, а попытка выгрузить базу данных в файл выгрузки (архив .zip) для последующей обработки приводит к многочасовому зависанию конфигуратора. Выясним причину такого поведения платформы и разберем эффективные практические способы решения поставленной задачи.
Проанализируем технические ограничения платформы 1С 7.7, которые приводят к возникновению этих сбоев:
Установка соединения с сервером базы данных.Если требуется сохранить ссылочный контроль платформы, но избежать переполнения памяти, разобьем удаление на небольшие порции. Также перед началом очистки отключим запись журнала регистрации в конфигураторе, что существенно ускорит процесс.
Посмотрим на пример пакетного удаления документов по временным интервалам с использованием компоненты 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 в заголовке исполняемого файла с помощью системной утилиты. Это предотвратит вылеты по нехватке памяти при обработке средних объемов ссылок.
Когда база имеет огромный объем и штатное удаление работает недопустимо долго, эффективным решением становится удаление записей прямыми запросами к таблицам 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-запросов важно соблюдать последовательность зависимостей:
$ДокументСтроки) и движения регистров ($Регистр)._1SENTRY), периодические константы (_1SCONST) и системные операции (_1SOPER)._1SCRDOC).$Документ)._1SJOURN).При прямом массовом удалении данных лог транзакций СУБД начинает активно увеличиваться. В среде MS SQL Server 2008 устаревшая конструкция BACKUP LOG ... WITH TRUNCATE_ONLY больше не поддерживается. Чтобы уменьшить размер журналов и вернуть дисковое пространство, переведем базу данных в простую модель восстановления (Simple) и выполним усечение через команду DBCC SHRINKFILE.
По завершении прямых манипуляций с таблицами MS SQL обязательно запустим процедуру Тестирование и исправление ИБ в монопольном режиме конфигуратора для пересчета итогов и проверки ссылочной целостности базы данных.