Свёртка крупной и непрерывно работающей базы 1С (работа в режиме 24/7) — одна из наиболее сложных задач администрирования и разработки. Стандартная процедура свёртки через создание отдельной копии, её очистку и последующую подмену рабочей базы сталкивается с серьёзной проблемой: если в рабочей базе непрерывно функционируют другие планы обмена (РИБ с филиалами, интеграции с сайтами, выгрузки в бухгалтерию или CRM), то за время проведения свёртки данные обмена разойдутся.
Разберём детально, почему возникает рассинхронизация, как устроены внутренние механизмы регистрации изменений на уровне платформы 1С и СУБД, а также рассмотрим практические способы переключения на свёрнутую базу с сохранением работоспособности всех интеграций.
Проанализируем классическую схему свёртки через промежуточную базу:
Однако в рабочей базе параллельно продолжают выполняться регламентные обмены по сторонним планам. В результате возникают две критические проблемы:
НомерОтправленного и НомерПринятого в рабочей базе увеличиваются при каждой успешной сессии обмена. В свернутой копии эти номера «застыли» на момент создания бэкапа. При попытке отправить пакет из копии с меньшим номером базы-получатели отвергнут его с ошибкой нарушения последовательности сообщений.Авторегистрация = Разрешить. В результате в сторонние узлы (например, в розничные магазины) уйдут миллионы служебных удалений или документов остатков, что заблокирует каналы связи.Рассмотрим порядок действий для программного переноса состояния очередей обмена без прямого вмешательства в структуру СУБД. Данный метод является наиболее безопасным с точки зрения целостности метаданных.
Разберем по шагам алгоритм финального переключения:
Посмотрим на пример программной фиксации и восстановления номеров пакетов обмена:
// Выполняется в рабочей базе для сохранения состояния узла
Функция ПолучитьПараметрыУзла(УзелОбмена) Экспорт
Результат = Новый Структура;
Результат.Вставить("НомерОтправленного", УзелОбмена.НомерОтправленного);
Результат.Вставить("НомерПринятого", УзелОбмена.НомерПринятого);
Результат.Вставить("Код", УзелОбмена.Код);
Возврат Результат;
КонецФункции
// Выполняется в свернутой копии для актуализации номеров
Процедура УстановитьНомераСообщений(УзелСсылка, НомерОтправленного, НомерПринятого) Экспорт
УзелОбъект = УзелСсылка.ПолучитьОбъект();
УзелОбъект.НомерОтправленного = НомерОтправленного;
УзелОбъект.НомерПринятого = НомерПринятого;
// Блокируем стандартные обработчики при необходимости
УзелОбъект.ОбменДанными.Загрузка = Истина;
УзелОбъект.Записать();
КонецПроцедуры
Для переноса очереди изменений используем методы менеджера планов обмена ПланыОбмена.ВыбратьИзменения() в источнике и ПланыОбмена.ЗарегистрироватьИзменения() в приёмнике:
// Восстановление регистрации конкретного массива ссылок в целевой свернутой базе
Процедура ВосстановитьРегистрациюВБазе(УзелСсылка, МассивСсылок) Экспорт
Для Каждого Ссылка Из МассивСсылок Цикл
ПланыОбмена.ЗарегистрироватьИзменения(УзелСсылка, Ссылка);
КонецЦикла;
КонецПроцедуры
Если очередь регистрации слишком велика (сотни тысяч записей) и программная регистрация займет слишком много времени в рамках технологического окна, перенос таблиц регистрации можно выполнить напрямую средствами СУБД.
Проанализируем внутреннее устройство таблиц обмена в Microsoft SQL Server / PostgreSQL. Платформа 1С создает для каждого объекта метаданных, входящего в состав плана обмена, специальную таблицу изменений с префиксом _ChangeRec* (например, _DocumentChngR*, _ReferenceChngR*, _AccumRgChngR*).
Разберем последовательность действий для переноса таблиц через SQL:
ПолучитьСтруктуруХраненияБазыДанных() в 1С:
ТаблицаСтруктуры = ПолучитьСтруктуруХраненияБазыДанных();
// Отбираем записи, где ИмяТаблицыХранения содержит информацию о регистрации изменений
Для Каждого Строка Из ТаблицаСтруктуры Цикл
Если Строка.Назначение = "ТаблицаИзменений" Тогда
// Строка.ИмяТаблицыХранения содержит реальное имя таблицы в SQL
КонецЕсли;
КонецЦикла;
-- Пример для MS SQL Server (между базами на одном сервере)
TRUNCATE TABLE [Base_Copy].[dbo].[_DocumentChngR1234];
INSERT INTO [Base_Copy].[dbo].[_DocumentChngR1234]
SELECT * FROM [Base_Prod].[dbo].[_DocumentChngR1234];
_SentNo (НомерОтправленного) и _RcvdNo (НомерПринятого) из таблицы узлов _Node*.Важное условие: Данный метод применим только тогда, когда свернутая база была получена прямым копированием исходной, то есть внутренние идентификаторы (GUID) узлов и объектов метаданных полностью совпадают.
Если архитектура обменов допускает повторную регистрацию среза данных или обнуление номеров сообщений, можно использовать штатный механизм сброса счетчиков.
Рассмотрим особенности этого подхода:
УзелОбъект = УзелСсылка.ПолучитьОбъект();
УзелОбъект.НомерОтправленного = 0;
УзелОбъект.НомерПринятого = 0;
УзелОбъект.ОбменДанными.Загрузка = Истина;
УзелОбъект.Записать();
ПланыОбмена.ЗарегистрироватьИзменения().Выясним, какие меры предосторожности необходимо предпринять в процессе свёртки копии, чтобы не повредить интеграционную инфраструктуру:
ДокументОбъект.ОбменДанными.Загрузка = Истина. Это предотвращает автоматическое попадание технических документов свёртки в таблицы регистрации изменений сторонних узлов.
// Очищаем регистрацию для документов ввода остатков по всем планам обмена
ПланыОбмена.УдалитьРегистрациюИзменений(УзелСсылка, Метаданные.Документы.ВводНачальныхОстатков);
УстановитьГлавныйУзел(Неопределено)).Использование комбинации отключения авторегистрации и переноса счетчиков пакетов позволяет успешно свернуть даже терабайтные базы 1С без длительного простоя и без сбоев в работе распределенной информационной сети.