Хочу поделиться опытом, касающимся распределенных баз. Ко мне обратился заказчик с просьбой восстановить обмен в распределенной базе, который перестал работать некоторое время назад. Беглый взгляд на монитор обмена привел меня в недоумение - откуда столько объектов для выгрузки (см. Рис. 1).
Помявшись, местный спец признался, что обмен из центральной базы в периферийную сломался два месяца назад, хотя в обратном направлении работает без проблем. На вопрос, почему тянули два месяца, внятного ответа я не получил. Размер файла обмена тем временем вырос до 3,7 Гб (несжатый).
Ладно. Симптомы отсутствия обмена - сообщение об ошибке (см. Рис. 2).
Причина, очевидно, "кривые" движения каких-либо документов.
Патрон (1С), в этом случае, советует перепроводить все документы, попавшие в выгрузку (см. Рис. 3).
Совет хороший, но был отметен сразу, как неосуществимый - слишком их много. Как локализовать источник ошибок?
Учитывая размер центральной базы (15 Гб) первым предположением было превышение суммарного размера одной или нескольких таблиц, величины в 4ГБ. Это не подтвердилось.
Тестирование и исправление ничего не дало. Выгрузка и повторная загрузка центральной и периферийной баз в dt не выявила каких-либо ошибок. Все проходило штатно. Обработка, которая ищет неуникальные комбинации (Регистратор, НомерСтроки) в движениях регистров не выявила ошибок. Код процедур проверки регистров приведен на Рис. 4.
Процедура КнопкаВыполнитьНажатие(Кнопка)
Ошибки.Очистить();
МетаданныеРегистрыНакопления = Метаданные.РегистрыНакопления;
КоличествоРегистров = МетаданныеРегистрыНакопления.Количество();
Для Сч = 1 По КоличествоРегистров Цикл
МетаданныеРегистр = МетаданныеРегистрыНакопления[Сч - 1];
ИмяРегистра = МетаданныеРегистр.Имя;
Если ИмяРегистра = "ПартииНоменклатуры" Тогда
//Продолжить;
КонецЕсли;
Сообщить(ИмяРегистра + " ???");
ТекстЗапроса = СформироватьТекстЗапросаПоРегистру(ИмяРегистра);
Запрос = Новый Запрос;
Запрос.Текст = ТекстЗапроса;
Результат = Запрос.Выполнить();
Если Результат.Пустой() Тогда
Сообщить(ИмяРегистра + " Okay");
Продолжить;
КонецЕсли;
Сообщить(ИмяРегистра + " + ");
Выборка = Результат.Выбрать();
Пока Выборка.Следующий() Цикл
НоваяСтрока = Ошибки.Добавить();
НоваяСтрока.Регистратор = Выборка.Регистратор;
НоваяСтрока.Период = Выборка.Регистратор.Дата;
НоваяСтрока.ИмяРегистра = ИмяРегистра;
КонецЦикла;
КонецЦикла;
КонецПроцедуры
Функция СформироватьТекстЗапросаПоРегистру(ИмяРегистра)
ТекстЗапроса =
"ВЫБРАТЬ РАЗЛИЧНЫЕ
| Данные.Регистратор КАК Регистратор
|ИЗ
| (ВЫБРАТЬ
| РегистрНакопления.Регистратор КАК Регистратор,
| РегистрНакопления.НомерСтроки КАК НомерСтроки,
| СУММА(1) КАК КоличествоДублей
| ИЗ
| РегистрНакопления." + ИмяРегистра + " КАК РегистрНакопления
|
| СГРУППИРОВАТЬ ПО
| РегистрНакопления.Регистратор,
| РегистрНакопления.НомерСтроки
|
| ИМЕЮЩИЕ
| СУММА(1) > 1) КАК Данные";
Возврат ТекстЗапроса;
КонецФункции
Кусочек кода, относящийся к регистру "Партии номенклатуры" появился, поскольку в файловом варианте попытка проверки приводила к аварийному закрытию сеанса с сообщением об ошибке "Недостаточно памяти" (32 Гб оперативной памяти - маловато, само собой).
Отключение итогов (кстати, аналогично, по совету патрона) тоже не помогло. Обе базы выглядели совершенно нормально. Ошибка возникала только при операции ПрочитатьИзменения() при загрузке файла. Возможно, это проблема платформы, как я сейчас думаю. Признаться, я зашел в тупик - предложение создать заново начальный образ периферийной базы я оставил в качестве последнего шанса не потерять лицо, да и не факт, что выгрузка прошла бы гладко.
Решение пришло внезапно. Кто сказал, что индексы должны быть уникальны? Далее, я создал базу SQL, загрузил туда периферийную базу, и начал попытки загрузить туда файл обмена. Как только загрузка вываливалась на ошибку (см. Рис. 5),
я снимал флажки уникальности с индексов таблиц регистров (Рис. 6).
Всего таких регистров нашлось шесть. Когда файл загрузился, я снова применил обработку поиска неуникальных комбинаций (Регистр, НомерСтроки), и получил таблицу "кривых" документов (см. Рис. 7).
После этого я сделал их непроведенными в центральной базе, выгрузил файл обмена, затем загрузил его в исходную периферийную. Все прошло нормально. Бинго!
PS. После этого я перепровел документы из таблицы и они ушли в периферийную без проблем.