При работе с крупными информационными базами на платформе 1С:Предприятие 8.3 администраторы часто сталкиваются с ситуацией, когда стандартный механизм создания начального образа подчиненного узла РИБ (распределенной информационной базы) завершается ошибкой Microsoft SQL Server: Create site failed. Disk full. При этом файлы tempdb могут разрастаться до нескольких сотен гигабайт и даже терабайт, превышая объем самой базы в несколько раз. Разберем подробно, почему это происходит и как решить проблему, используя альтернативные методы.
Проанализируем механику работы SQL Server в момент выполнения команды Создать начальный образ. Когда мы инициируем этот процесс, особенно с использованием фильтров (например, по подразделению или организации), 1С генерирует крайне сложные SQL-запросы. Рассмотрим основные факторы, влияющие на потребление ресурсов:
tempdb. Это происходит из-за неактуальной статистики или сложности вложенных запросов 1С.Read Committed Snapshot Isolation (RCSI), tempdb используется для хранения версий строк. Длительная транзакция создания образа «держит» старые версии данных, не позволяя системе очищать их, что приводит к забиванию диска.MAXDOP сервер может запускать множество параллельных потоков для обработки запроса, каждый из которых требует своего рабочего пространства в tempdb.Прежде чем переходить к радикальным мерам, попробуем оптимизировать текущую среду. Рассмотрим шаги, которые могут помочь стандартному механизму отработать успешно:
Обновим статистику. Это критически важный этап. Выполним полное обновление статистики для всех таблиц базы данных. Это поможет оптимизатору SQL выбрать более эффективный план запроса. Используем скрипт:
EXEC sp_updatestats;
-- Или более глубокое обновление для конкретных таблиц
UPDATE STATISTICS [ИмяТаблицы] WITH FULLSCAN;
Настроим MAXDOP. Попробуем временно ограничить максимальную степень параллелизма до 1. Это может замедлить процесс, но существенно снизит нагрузку на tempdb за счет исключения конкуренции потоков за временные таблицы.
Проверим параметры tempdb. Убедимся, что tempdb разбит на несколько файлов (рекомендуется по количеству ядер процессора, но не более 8) одинакового размера с фиксированным шагом приращения. Это предотвратит фрагментацию и «затыки» при выделении места.
Если стандартный метод CreateInitialImage продолжает «съедать» все дисковое пространство, проанализируем и применим метод создания подчиненного узла из копии базы. Этот способ считается наиболее надежным для баз объемом свыше 50-100 Гб.
Рассмотрим алгоритм по шагам:
Вместо создания образа средствами 1С, сделаем полный бэкап основной базы средствами SQL Server и восстановим его как новую базу. На этом этапе мы получаем идентичную копию, которая еще «не знает», что она является подчиненным узлом.
Зайдем в восстановленную базу в монопольном режиме. Нам необходимо программно установить признак того, что эта база теперь является подчиненной. Рассмотрим пример кода, который нужно выполнить в обработке:
// Устанавливаем главный узел для текущей базы
ПланыОбмена.УстановитьГлавныйУзел(СсылкаНаГлавныйУзел);
// Очистим регистрацию изменений в новом узле
// Чтобы он не пытался отправить обратно в центр все данные
ПланыОбмена.УдалитьРегистрациюИзменений(СсылкаНаЭтотУзел);
После выполнения УстановитьГлавныйУзел() база перезапустится, и в заголовке окна появится название узла. Теперь база считает себя полноправным участником обмена.
Поскольку мы создавали узел из полной копии, в нем присутствуют все данные, включая те, которые не должны были попасть в узел из-за фильтров. Теперь наша задача — удалить лишнее. Рассмотрим, почему это эффективнее:
Важный совет: Если данных для удаления очень много, стандартный метод Объект.Удалить() будет работать крайне медленно и забьет лог транзакций. Проанализируем возможность использования прямых SQL-запросов для очистки таблиц движений (регистров накопления и сведений), которые точно не нужны в подчиненном узле. Это сэкономит десятки часов времени.
После того как данные удалены, необходимо убедиться, что таблицы регистрации изменений (так называемые «таблицы со слониками») пусты. Если в них остались записи, узел попытается передать информацию об удалении обратно в центральную базу при первом же обмене, что может привести к катастрофической потере данных в центре.
Выполним полную очистку регистрации изменений для всех планов обмена в подчиненном узле:
Для Каждого ПланОбмена Из ПланыОбмена Цикл
ПланыОбмена.УдалитьРегистрациюИзменений(ПланОбмена.ЭтотУзел());
КонецЦикла;
Если вы решили удалять данные напрямую через SQL (что не рекомендуется для новичков, но необходимо для профи), помните о ссылочной целостности. Рассмотрим порядок действий:
Использование команды TRUNCATE TABLE вместо DELETE позволяет мгновенно очистить таблицу, не нагружая tempdb и лог транзакций, но она применима только если вы очищаете таблицу полностью.
Мы выяснили, что рост tempdb — это не аномалия, а следствие неоптимальных планов запросов при попытке 1С «выкусить» кусок огромной базы. Использование дисков объемом 4 Тб может быть временным решением, но оно не устраняет причину — низкую производительность процесса. Метод создания «ручного» РИБ через УстановитьГлавныйУзел() позволяет обойти ограничения стандартного механизма, обеспечивая полный контроль над составом данных и нагрузкой на серверное оборудование.