При работе с распределенными информационными базами в платформе «1С:Предприятие 7.7» системные администраторы и программисты периодически сталкиваются с неприятной ситуацией: при очередном обмене данными из Центральной базы (ЦБ) в Периферийную базу (ПБ) выгружается огромный массив старых документов (например, за прошлые периоды). В самой периферийной базе эти документы успешно загружаются (о чем свидетельствуют записи в Журнале регистрации), однако при последующем ответном обмене Центральная база «не понимает», что ПБ уже приняла эти данные. В результате при каждом новом сеансе обмена одни и те же документы выгружаются снова и снова, раздувая файл обмена до огромных размеров.
В этой статье мы подробно разберем, почему возникает этот сбой, проанализируем внутреннее устройство механизмов УРБД (Управление распределенными информационными базами) 1С 7.7 и рассмотрим пошаговые практические методы решения проблемы как для файлового (DBF), так и для клиент-серверного (SQL) вариантов баз данных.
Чтобы понять первопричину зацикливания, давайте проанализируем, как платформа отслеживает изменения объектов и подтверждает их доставку. Вся работа компоненты УРБД опирается на три системные таблицы в базе данных:
1SDBSET — содержит список всех информационных баз, входящих в распределенную систему, с их уникальными трехсимвольными идентификаторами.1SDWNLDS — таблица регистрации созданных и отправленных пакетов обмена (сессий выгрузки).1SUPDTS — таблица регистрации измененных объектов (Updates), которые должны мигрировать в другие базы. Это ключевое звено нашей проблемы.Рассмотрим структуру таблицы 1SUPDTS. Она содержит следующие важные для нас поля:
DBSIGN — трехсимвольный код информационной базы-получателя (например, "001", "P02").TYPEID — идентификатор типа метаданных измененного объекта (справочника, документа и т.д.) в 36-ричной системе счисления.OBJID — уникальный внутренний идентификатор конкретного объекта.DELETED — маркер удаления объекта (принимает значение "D", если объект помечен на удаление или физически удален).DWNLDID — идентификатор пакета выгрузки, в который была включена данная запись об изменении.Жизненный цикл записи при стандартном обмене выглядит следующим образом:
Шаг 1. Когда пользователь создает или перепроводит документ в Центральной базе, система автоматически делает запись в таблицу 1SUPDTS для каждой периферийной базы, в которую этот документ должен быть передан. В этот момент поле DWNLDID заполняется пробелами (или нулями), что означает: «объект изменен, но еще не выгружался».
Шаг 2. При запуске обмена из ЦБ формируется файл выгрузки. Платформа регистрирует в таблице 1SDWNLDS новую сессию обмена с уникальным номером пакета. Всем записям в 1SUPDTS, которые попали в эту выгрузку, в поле DWNLDID записывается этот самый номер пакета.
Шаг 3. Периферийная база успешно загружает файл обмена. При этом она запоминает номер пакета ЦБ, который был только что успешно принят. При формировании ответного файла из ПБ в ЦБ в заголовок файла (квитанцию) записывается этот подтвержденный номер пакета.
Шаг 4. При загрузке ответа в Центральную базу система считывает из заголовка номер подтвержденного пакета. Происходит процедура квитирования: ЦБ удаляет из таблицы 1SUPDTS все записи для данной ПБ, у которых значение поля DWNLDID меньше или равно подтвержденному номеру пакета.
Если документы выгружаются повторно, это означает, что Центральная база не смогла очистить соответствующие записи в таблице 1SUPDTS. Это может произойти по следующим причинам:
DWNLDID таблицы 1SUPDTS записался идентификатор сессии, которого физически нет в таблице 1SDWNLDS (например, из-за аварийного завершения работы или некорректного восстановления базы из резервной копии), ЦБ никогда не сможет сопоставить подтверждение от ПБ с этими строками. Они зависают там навсегда.1SUPDTS.CDX приводит к тому, что 1С при чтении файла подтверждения пытается найти записи по индексу для удаления, физически их не находит, транзакция завершается без ошибок, но сами записи остаются нетронутыми в таблице DBF.DWNLDID для них сбрасывается обратно в пустое значение. ЦБ считает их вновь измененными и игнорирует старое подтверждение от ПБ.Перед тем как прибегать к ручной правке таблиц, обязательно исключим проблему с индексами. Для этого выполним следующие действия:
.CDX.1SUPDTS.CDX и 1SDWNLDS.CDX (для полной надежности можно удалить абсолютно все файлы с расширением .CDX в каталоге базы данных — они без проблем перестроятся заново).Если проблема заключалась в разрушении индексного файла, после загрузки ответа от ПБ таблица 1SUPDTS успешно очистится, и зацикливание прекратится.
Если переиндексация не помогла, значит, записи в таблице регистрации изменений действительно потеряли связь с реальными номерами пакетов обмена. Нам потребуется удалить их вручную.
Важно: Перед проведением любых низкоуровневых операций с таблицами базы данных обязательно сделайте полную резервную копию базы данных ЦБ!
Для работы нам понадобится любой DBF-редактор, поддерживающий работу со структурами dBase IV (например, DBF Navigator, Database Desktop или аналогичные инструменты).
1SUPDTS.DBF, который находится в каталоге Центральной базы данных.DBSIGN, указав трехсимвольный код нашей периферийной базы (например, "П02" или "002"), в которую без конца выгружаются старые документы за март 2019 года.DWNLDID стоят старые, некорректные или зависшие номера пакетов, которые ПБ уже давно приняла. Если мы уверены, что ПБ полностью синхронизирована по этим документам, мы можем смело удалить все отфильтрованные строки для данной ПБ.1SUPDTS.CDX в каталоге базы и запустим Конфигуратор в монопольном режиме для перестроения индексов.После этого запустим обмен. Выгрузка будет содержать только актуальные измененные объекты, а старый "хвост" документов за март 2019 года перестанет выгружаться.
Если наша Центральная база работает под управлением Microsoft SQL Server, исправить ситуацию гораздо проще, поскольку нам не нужно монопольно выгонять всех пользователей и удалять индексы вручную. Мы можем выполнить точечную очистку таблицы изменений напрямую через SQL Server Management Studio (SSMS).
Выясним структуру таблицы. В SQL-версии 1С 7.7 системная таблица 1SUPDTS имеет название _1SUPDTS (с ведущим символом подчеркивания).
Рассмотрим по шагам процесс очистки:
SELECT *
FROM _1SUPDTS
WHERE DBSIGN = 'П03';
Если мы видим там огромное количество записей по документам за март 2019 года, которые гарантированно загружены в периферийную базу, мы можем безопасно очистить регистрацию для этой ПБ.
Выполним следующий SQL-запрос для удаления всех зарегистрированных изменений для базы "П03":
DELETE FROM _1SUPDTS
WHERE DBSIGN = 'П03';
Если нам необходимо удалить регистрацию не всех объектов, а только конкретных документов определенного вида, мы можем наложить фильтр по полю TYPEID. Выяснить, какому документу соответствует конкретный TYPEID, можно, заглянув в файл описания структуры метаданных 1cv7.dd (или 1cv7.dds для SQL), который лежит в каталоге базы данных. Там мы найдем строки вида:
# Посмотрим соответствие в файле 1cv7.dd:
# T=1SUPDTS |Регистрация изменений
# F=DBSIGN |C3 |0|0|ID базы-получателя
# F=TYPEID |C4 |0|0|ID типа объекта
# F=OBJID |C9 |0|0|ID объекта
Каждому виду документов в 1С 7.7 соответствует свой внутренний четырехсимвольный идентификатор (например, " 1O" или " SP"). Отфильтровав по нему, мы можем выполнить точечное удаление:
-- Удаляем только документы конкретного типа для базы П03
DELETE FROM _1SUPDTS
WHERE DBSIGN = 'П03' AND TYPEID = ' 1O';
После выполнения SQL-запроса изменения вступят в силу мгновенно. При следующей выгрузке обмена из ЦБ файл будет иметь минимальный размер, так как зависшие документы больше не будут в него попадать.
Существует еще один хитрый способ заставить Центральную базу поверить, что Периферийная база успешно приняла все зависшие документы, без прямого вмешательства в структуру базы данных. Этот метод основан на модификации файла обмена.
Проанализируем этот алгоритм:
1SUPDTS получают значение DWNLDID = 250..dat).При загрузке платформа считает, что ПБ официально подтвердила успешный прием пакета под номером 250, и автоматически выполнит стандартную штатную процедуру очистки таблицы 1SUPDTS. Все зависшие записи с номерами пакетов, меньшими или равными 250, будут автоматически удалены самой системой без риска нарушения ссылочной целостности базы данных.
Чтобы избежать повторения проблемы бесконечной выгрузки документов в распределенных базах 1С 7.7, рекомендуем придерживаться нескольких простых правил:
1SUPDTS.Мы надеемся, что предложенные методы помогут вам быстро и безболезненно справиться с зацикливанием обмена в УРБД 1С 7.7, сэкономив ваше время и дисковое пространство!