Многопоточное обновление 1С: Управление холдингом

10.01.24

База данных - Обновление 1С

Что делать, если обновление базы в режиме предприятия выполняется значительно больше вашего технологического окна, даже если это окно - с вечера пятницы и до утра понедельника.

Скачать исходный код

Наименование Файл Версия Размер
Многопоточное обновление с УХ 3.2.3.58 на УХ 3.2.5.32:
.cfe 26,71Kb
7
.cfe 26,71Kb 7 Скачать

Методика, представленная в статье, предназначена для конфигурации Управление холдингом, однако может использоваться для любой конфигурации 1С, в которой используется стандартный механизм обновления БСП. Статья написана, чтобы помочь людям, столкнувшимся с аналогичной проблемой, достаточно просто решить эту задачу. Методика не предлагается как окончательная и единственно верная. Конструктивная критика и рекомендации по улучшению приветствуются. Тупой хэйт будет игнорироваться или удаляться. Надеюсь, совместными усилиями мы доведём методику до совершенства.

В нашей компании используется конфигурация 1С: Управление холдингом.  В конце 2023 была поставлена задача УХ с версии 3.2.3.58 до 3.2.5.32. 

Проблема заключалась в том, что обновление в режиме предприятия выполнялось, исключительно долго. Пришлось вмешиваться и разбираться. Оказалось дело том, что в обновлении есть ряд тяжелых обработчиков, которые выполнялись каждый по 6-12 часов, но один обработчик особо отличился, скорость выполнения которого равна 1 объект в секунду, а таких объектов около 2,5 млн., то есть расчетное время выполнения которого должно составлять 28,93 суток (2,5 млн /(60*60*24)). Весь процесс обновления должны был выполняться за 31 сутки. Но надо отметить это на тестовом сервере. В продакшене производительность выше в 2 раза, то есть расчетное время примерно 15 суток, что никак не решало проблему. Технологическое окно для этой базы составляет 2,5 суток. На праздниках может быть больше, но это тоже не выход. При этом следует заметить, что процесс обновления очень слабо нагружает сервер 1С и сервер БД.

Таким образом было решено сделать многопоточное обновление, используя средства БСП. Почему средствами БСП, спросите вы? Потому что из коробки очень простой многопоточный механизм, который мы уже использовали в своих разработках.

Постановка задачи:

9 длительных обработчиков обновлений, один из которых выполняется 28,93 суток, а суммарно 31 сутки. Целевое время выполнения не более 2 суток. Из этого следует, что обновление надо выполнять минимум в 15 потоков.

Поиск тяжелых обработчиков

Тут всё просто, в тестовой базе запускал обновление.

  • Подключался отладчиком: меню Отладка-Подключение-Автоматическое подключение, выбрать флажки Клиентские и внешние соединения, Фоновые задания.
  • Периодически мониторю журнал регистрации, когда в ЖР вижу более получаса однотипные записи, останавливаю отладку (Отладка-Остановить), в фоновом задании, в котором выполняется обновление анализирую стек вызовов, нахожу процедуру-обработчик обновления. Понять это можно по общему модулю, в котором находится процедура, название будет начинаться с ОбновлениеИнформационнойБазы. В случае УХ они называться: ОбновлениеИнформационнойБазыУХ  и ОбработчикиОбновленияУХКазначейство (хотя это не по стандарту, но в УХ много чего не по стандарту).

Как правило, обработчики обновления заполняют новые реквизиты в документах, справочниках, регистрах. Алгоритм у низ следующий:

  1. Выбрать данные запросом
  2. Обход запроса в цикле
  3. Заполнение нового реквизита
  4. Запись объекта

Например, описанной выше методикой нашли обработчик ОбработчикиОбновленияУХКазначейство.ЗаполнитьДокументПланированияСписаниеСРасчетногоСчета(). Он заполняет в документе СписаниеСРасчетногоСчета реквизит ДокументПланирования. Ниже приведен код обработчика:

Процедура ЗаполнитьДокументПланированияСписаниеСРасчетногоСчета() Экспорт
	
	Запрос = Новый Запрос;
	Запрос.Текст = 
		"ВЫБРАТЬ
		|	СписаниеСРасчетногоСчета.Ссылка КАК Ссылка,
		|	СписаниеСРасчетногоСчета.УдалитьДокументПланирования КАК УдалитьДокументПланирования,
		|	СписаниеСРасчетногоСчета.ДокументПланирования КАК ДокументПланирования
		|ИЗ
		|	Документ.СписаниеСРасчетногоСчета КАК СписаниеСРасчетногоСчета
		|ГДЕ
		|	СписаниеСРасчетногоСчета.УдалитьДокументПланирования <> НЕОПРЕДЕЛЕНО
		|	И СписаниеСРасчетногоСчета.ДокументПланирования = НЕОПРЕДЕЛЕНО";
	
	РезультатЗапроса = Запрос.Выполнить();
	
	ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
	
	Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
		ДокументОбъект = ВыборкаДетальныеЗаписи.Ссылка.ПолучитьОбъект(); 
		ДокументОбъект.ДокументПланирования =  ВыборкаДетальныеЗаписи.УдалитьДокументПланирования;
		ОбновлениеИнформационнойБазы.ЗаписатьОбъект(ДокументОбъект);
	КонецЦикла;

КонецПроцедуры

 

Перепишем код обработчика в многопоточную реализацию.

Создадим расширение МногопоточноеОбновление_УХ32358_УХ32532.

В нём общий серверный модуль УХ32Ускор_МногопоточноеПроведение с вызовом сервера.

Пример реализации:

  1. В модуле УХ32Ускор_МногопоточноеПроведение напишем процедуру СоздадимПотокиНаСервереДляТЗ, которая раскладывает на потоки данных из таблицы значений (аргумент ТЗ) и запускает фоновые задания, плюс сервисную процедурау ЗаполнитьПараметрыПотока. Процедуры универсальная, подходит для любого обработчика обновления, работающего с одной выборкой данных, пишется один раз.

 

Функция СоздадимПотокиНаСервереДляТЗ(УникальныйИдентификатор, ИмяФункцииИлиПроцедуры, ТЗ)
	
	КонстКоличествоПотоков = Константы.КоличествоПотоковДлительныхОпераций.Получить();
	КоличествоПотоков = ?(КонстКоличествоПотоков=0, 4, КонстКоличествоПотоков);		// Минимально хотя бы 4 потока
	МинПорция = 100;					// Если порция маленькая, нет смысла запускать в потоках
	КолОбъектов = ТЗ.Количество();
	КоличествоПотоков = ?(КолОбъектов<=МинПорция, 1, КоличествоПотоков);

	ПараметрыВыполнения = ДлительныеОперации.ПараметрыВыполненияВФоне(УникальныйИдентификатор);
	ПараметрыВыполнения.НаименованиеФоновогоЗадания = СтрШаблон("Многопоточно выполнение: %1", ИмяФункцииИлиПроцедуры);
	ПараметрыВыполнения.ЗапуститьВФоне = Истина;
	
	РазмерПорции = Окр(КолОбъектов / КоличествоПотоков, 0);
	МассивПорции = Новый Массив;
	СчПорции = 0;
	НомерПотока = 1;
	ПараметрыПотоков = Новый Соответствие();
	ПоследнийПоток = Ложь;			// Чтобы остатки элементов для обработки положить в последний поток
	
	Для Каждого стрТЗ из ТЗ Цикл
			
		МассивПорции.Добавить(ОбщегоНазначения.СтрокаТаблицыЗначенийВСтруктуру(стрТЗ));
		СчПорции = СчПорции+1;
		Если СчПорции%РазмерПорции=0 и НЕ ПоследнийПоток Тогда
			ЗаполнитьПараметрыПотока(МассивПорции, НомерПотока, ПараметрыПотоков); // Положим порцию в ПараметрыПотоков
			// Инициализация нового потока
			МассивПорции = Новый Массив;	
			НомерПотока = НомерПотока+1;
		КонецЕсли;
	
	КонецЦикла;
	
	// Весь остаток объектов положим в последний поток
	Если МассивПорции.Количество()>0 Тогда
		ЗаполнитьПараметрыПотока(МассивПорции, НомерПотока, ПараметрыПотоков);
	КонецЕсли;
		
	ФоновоеЗадание = ДлительныеОперации.ВыполнитьПроцедуруВНесколькоПотоков(ИмяФункцииИлиПроцедуры, ПараметрыВыполнения, ПараметрыПотоков);
		
   	Если ФоновоеЗадание.Статус = "Ошибка" Тогда
		Сообщить(СокрЛП(ФоновоеЗадание.Статус));
	КонецЕсли;
	
	Возврат ФоновоеЗадание;	
	
КонецФункции

Процедура ЗаполнитьПараметрыПотока(МассивПорции, НомерПотока, ПараметрыПотоков)
		
	КодПотока = "Поток " + НомерПотока;
	ПараметрыПотока = Новый Структура;
	ПараметрыПотока.Вставить("ОбъектыДляОбработки", МассивПорции);
	
	ПараметрыВызоваСервера = Новый Массив;
	ПараметрыВызоваСервера.Добавить(КодПотока); 
	ПараметрыВызоваСервера.Добавить(ПараметрыПотока);
	
	ПараметрыПотоков.Вставить(КодПотока, ПараметрыВызоваСервера);

КонецПроцедуры

Обратите внимание на строку МассивПорции.Добавить(ОбщегоНазначения.СтрокаТаблицыЗначенийВСтруктуру(стрТЗ));

Она нужна, чтобы в обработчик потока получил эмуляцию строки выборки запроса (или таблицы значения). По-другому прокинуть не получится, будет ошибка передачи мутабельного значения.

 

  1. Процедура ожидания выполнения потоков ОбработатьДанныеТЗМногопоточно. Процедура универсальная, пишется один раз.
Процедура ОбработатьДанныеТЗМногопоточно(РезультатЗапроса, ИмяПроцедуры)
	
	Если РезультатЗапроса.Пустой() Тогда
		Возврат;
	КонецЕсли;	
	
	тз = РезультатЗапроса.Выгрузить();
	КолОбъектов = ТЗ.Количество();
	ВремяНачала = ТекущаяДата();
	УникальныйИдентификатор = Новый УникальныйИдентификатор;
	
	Задание = СоздадимПотокиНаСервереДляТЗ(УникальныйИдентификатор, ИмяПроцедуры, тз);	
	
	ИдентификаторЗадания = Задание.ИдентификаторЗадания;
	инд = 0;
	Попытка
		//Пока Задание.Статус = "Выполняется" Цикл
		Пока ДлительныеОперации.ОперацияВыполнена(ИдентификаторЗадания, Задание).Статус = "Выполняется" Цикл
			// Ожидаем выполнения задания
			инд = инд +1;
		КонецЦикла;	
	Исключение
	КонецПопытки;
	
	ВремяВыполнения = Окр((ТекущаяДата()-ВремяНачала)/60,2);
	ИмяСобытия = СтрШаблон("Начало процедуры %1_Поток", ИмяПроцедуры);
	ЖурналРегистрации.ДобавитьСообщениеДляЖурналаРегистрации(ИмяСобытия,
	УровеньЖурналаРегистрации.Информация,,, СтрШаблон("Процедура выполнена, обработано %1 за %2 мин", КолОбъектов, ВремяВыполнения));

КонецПроцедуры 

 

  1. Выборка данных, пишется на основании оригинальной процедуры обработчика, в нашем случае ОбработчикиОбновленияУХКазначейство.ЗаполнитьДокументПланированияСписаниеСРасчетногоСчета, оставляем только код выборки данных, сравните с  Для каждого обработчика обновления.
Процедура ЗаполнитьДокументПланированияСписаниеСРасчетногоСчета() Экспорт
	
	Запрос = Новый Запрос;
	Запрос.Текст = 
		"ВЫБРАТЬ
		|	СписаниеСРасчетногоСчета.Ссылка КАК Ссылка,
		|	СписаниеСРасчетногоСчета.УдалитьДокументПланирования КАК УдалитьДокументПланирования,
		|	СписаниеСРасчетногоСчета.ДокументПланирования КАК ДокументПланирования
		|ИЗ
		|	Документ.СписаниеСРасчетногоСчета КАК СписаниеСРасчетногоСчета
		|ГДЕ
		|	СписаниеСРасчетногоСчета.УдалитьДокументПланирования <> НЕОПРЕДЕЛЕНО
		|	И СписаниеСРасчетногоСчета.ДокументПланирования = НЕОПРЕДЕЛЕНО";
	
	РезультатЗапроса = Запрос.Выполнить();
	
	Если РезультатЗапроса.Пустой() Тогда
		Возврат;
	КонецЕсли;
	
	// СА Многопоточная реализация в.2
	ИмяПроцедуры = "УХ32Ускор_МногопоточноеПроведение.ЗаполнитьДокументПланированияСписаниеСРасчетногоСчета_Поток";
	ОбработатьДанныеТЗМногопоточно(РезультатЗапроса, ИмяПроцедуры);	
	
КонецПроцедуры

 

  1. Обработчик потока, пишется на основании оригинальной процедуры обработчика, оставляем только код обработки данных.
Процедура ЗаполнитьДокументПланированияСписаниеСРасчетногоСчета_Поток(Поток, Параметры) Экспорт
	
	ИмяПроцедуры = "ЗаполнитьДокументПланированияСписаниеСРасчетногоСчета_Поток";
	ИмяСобытия = "Выполнение потока";
	ЖурналРегистрации.ДобавитьСообщениеДляЖурналаРегистрации(ИмяСобытия,
		УровеньЖурналаРегистрации.Информация,,,СтрШаблон("Начат %1 поток %2", ИмяПроцедуры, Поток));
		
	Сч = 0;
	Для каждого Выборка Из Параметры.ОбъектыДляОбработки Цикл
	
		ДокументОбъект = Выборка.Ссылка.ПолучитьОбъект(); 
		ДокументОбъект.ДокументПланирования =  Выборка.УдалитьДокументПланирования;
		ОбновлениеИнформационнойБазы.ЗаписатьОбъект(ДокументОбъект);
		Сч=Сч+1;
		
	КонецЦикла;
	
	ЖурналРегистрации.ДобавитьСообщениеДляЖурналаРегистрации(ИмяСобытия,
		УровеньЖурналаРегистрации.Информация,,, СтрШаблон("Завершен %1 поток %2 обработано %3", ИмяПроцедуры, Поток, Формат(Сч,"ЧГ=0")));
	
КонецПроцедуры

Многопоточная реализация готова.

  1. Теперь нужно выполнить этот обработчик до выполнения типового обновления. Для этого с помощью расширения доопределим процедуру СтандартныеПодсистемыКлиент.ПередНачаломРаботыСистемы() с вызовом &Перед, в обработчике события вызовем  наш обработчик обновления УХ32Ускор_МногопоточноеПроведение.УХ32Ускор_ПередНачаломРаботыСистемы_НаСервере():
&Перед("ПередНачаломРаботыСистемы")
Процедура УХ32Ускор_ПередНачаломРаботыСистемы(Знач ОповещениеЗавершения)
	
	УХ32Ускор_МногопоточноеПроведение.УХ32Ускор_ПередНачаломРаботыСистемы_НаСервере();
	
КонецПроцедуры

 

Далее код самого обработчика в модуле УХ32Ускор_МногопоточноеПроведение:

 

Процедура УХ32Ускор_ПередНачаломРаботыСистемы_НаСервере() Экспорт
	
	УстановитьКоличествоПотоков(30);		// При необходимости устанавливаем константу КоличествоПотоковДлительныхОпераций
	
	ЗаполнитьДокументПланированияСписаниеСРасчетногоСчета();
		
КонецПроцедуры

Процедура УстановитьКоличествоПотоков(КолПотоков)
	
	Константы.КоличествоПотоковДлительныхОпераций.Установить(КолПотоков);
	
КонецПроцедуры

Вы спросите, зачем понадобилось перехватывать вызов СтандартныеПодсистемыКлиент.ПередНачаломРаботыСистемы()? Отвечаю, чтобы выполнить наши обработчики до установки монопольного режима. В многопоточный механизм БСП не работает.

Также прошу обратить внимания на вызов УстановитьКоличествоПотоков(20). Он нужен для установки константы КоличествоПотоковДлительныхОпераций, которая как верхняя граница количества потоков в механизме длительных операций. Константу можно установить руками через интерфейс Администриование-Общие настройки-Настройка производительности, если вдруг было установлено мало потоков, а запас по ресурсам есть, то можно перед запуском обработчиков установить на ваш выбор.

В итоге что мы имеем:

  1. Процедуры, составляющие «ядро» многопоточной обработки.
  2. Пример перевода типового однопоточного обработчика обновления в многопоточный. При этом многопоточная обвязка унифицирована, вынесена в отдельные процедуры «ядра».
  3. Показано, как выполнить обработчик до выполнения типовых.

Но есть один нюанс… Дело в том, что мы грубо нарушаем последовательность выполнения обработчиков обновления, которые теоретически должны выполняться в строго определенной последовательности. Для себя нашел такой выход:

  1. Запускаю обновление базы без многопоточного расширения, т.е. флаг Активно сброшен.

  2. Когда я по ЖР вижу, что начал выполняться долгоиграющий обработчик, сбрасываю сеанс, активирую расширение.

  3. Запускаю базу, теперь сначала запустятся наши многопоточные обработчики.

P.S. В статье описан только один обработчик, как пример. По аналогии можно в течении 15-30 минут переписать практически любой стандартный обработчик обновления. Для желающих, файл с готовым расширением для ускорения обновления с УХ 3.2.3.58 до 3.2.5.32 во вложении. Перед использованием прочтите абзац выше "Но есть один нюанс".

Если кому-то нужна консультация, как для другой конфигурации использовать эту методику, пишите, постараюсь помочь. Присылайте свои реализации, можно будет сделать библиотеку многопоточных обработчиков обновлений.

Проверено на следующих конфигурациях и релизах:

  • 1С:Управление холдингом 1.3, релизы 10.3.73.3

Управление холдингом обновление ускорение многопоточное

См. также

Обновление для КА 1.1, ЗУП 2.5, БУХ 2.0: НДС, ЕФС-1, Расчет страховых взносов, Мобилизация, Статистика, Электронные трудовые книжки, 2-НДФЛ, Регламентированная отчетность, Кадровый учет, Прослеживаемость импортных товаров

Зарплата Регламентированный учет и отчетность Кадровый учет Обновление 1С Платформа 1С v8.3 Сложные периодические расчеты 1С:Комплексная автоматизация 1.х 1С:Бухгалтерия 2.0 1С:Зарплата и Управление Персоналом 2.5 Бухгалтерский учет Налоговый учет Управленческий учет Акцизы ЕНВД ЕСН Земельный налог ИП, ПБОЮЛ, КФХ Налог на имущество Налог на прибыль НДС НДФЛ ФОМС, ЕФС Транспортный налог УСН ПСН (патентная система налогообложения) Платные (руб)

Обновления для конфигураций: КА 1.1; ЗУП 2.5; БУХ 2.0; КА 1.1 Комплексная автоматизация торговли алкогольной продукцией; КА 1.1 Комплексный учет сельскохозяйственного предприятия

19900 руб.

01.04.2020    141028    681    352    

233

Автоматическое подтверждение легальности обновления базы или как обновить 100 типовых баз 1С за 5 часов

DevOps и автоматизация разработки Обновление 1С Платформа 1С v8.3 Конфигурации 1cv8 1С:Бухгалтерия 3.0 1С:Зарплата и Управление Персоналом 3.x Абонемент ($m)

Расширение для конфигураций 1С для автоматического подтверждения легальности обновления и выполнения обработчиков обновления при пакетном автоматическом обновлении большого числа баз 1С. А также сам модуль обработки по автоматическому обновлению баз.

2 стартмани

08.05.2019    24350    55    VPanin56    26    

27

Ссылочная константа содержит недопустимый ссылочный номер таблицы

Обновление 1С Платформа 1С v8.3 1С:Управление нашей фирмой 3.0 Россия Бесплатно (free)

На связи Сергей Скирдин, технический директор ИТ-интегратора «Белый код». Сегодня расскажу, как решить одну из проблем, с которой можно столкнуться при обновлении конфигурации 1С.

19.03.2024    977    sergey.skirdin    4    

14

Скрипт для обновления базы с расширением из хранилища

Обновление 1С Платформа 1С v8.3 Бесплатно (free)

Небольшая оптимизация рабочего времени через скрипт обновления базы 1С с расширением из хранилища конфигураций.

22.01.2024    1196    ke.92@mail.ru    2    

25

Не обновляется типовая конфигурация 1С через конфигуратор

Обновление 1С Платформа 1С v8.3 Россия Бесплатно (free)

Столкнулся с проблемой. Нужно было поднять до текущего релиза Розницу 2.3. Обновлял по старинке, через конфигуратор (база клиент-серверная). Указывал логин и пароль, ждал скачивания обновления и обновлял. Но после накатывания 5 релизов следующий устанавливаться не хотел, а точнее конфигуратор гордо говорил, что обновлений больше нет. Решение нашел здесь на форуме и хочу зафиксировать. Чтобы самому не забыть и передать опыт начинающим.

29.11.2023    1465    shestopalovpro    4    

7

Принудительный запуск дополнительных процедур обработки данных после обновления

Обновление 1С Платформа 1С v8.3 Конфигурации 1cv8 Россия Абонемент ($m)

Ручной запуск процедур обработки обработчиков после обновлений. Может быть полезно стажерам, консультантам, разработчикам, администраторам, всем, кто обновляет информационные базы.

1 стартмани

20.11.2023    680    9    IvanTerentev    0    

2

Ошибка SDBL "Нет таблицы или отсутствует RefSelf"

Инструменты администратора БД Обновление 1С Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

Известно несколько способов разной степени шаманства. Предлагаю ещё один, проверенный на практике и базирующийся на точном понимании своих действий.

15.11.2023    1544    Yashazz    1    

9
Комментарии
Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. kauksi 216 10.01.24 12:26 Сейчас в теме
Мне одному кажется что фирма 1с должна использовать этот метод работы с обработчиками по умолчанию? либо как то проверять размер получаемых данных и если от превышает какой то объем, то выбирать производительный метод обработки данных (документов, элементов справочников).
saver77; Serega-artem; t278; ye_s; +4 Ответить
7. saver77 60 11.01.24 17:25 Сейчас в теме
(1)Не одного. У есть стандартный многопоточный обработчик обновлений, который запускается регламентным заданием "Отложенное обновление ИБ". Часть обработчиков обновлений выполняется в нём. Но заполнение новых реквизитов в классических обработчиках.
Дмитрий74Чел; +1 Ответить
2. PerlAmutor 129 10.01.24 22:09 Сейчас в теме
Тоже недавно обновлял ERP. В системе обновления обнаружились проблемы:

- невозможно создавать программно индексы на момент выполнения обработчиков обновления под конкретные запросы. В моем случае выполнение одного из таких долгих обработчиков сократилось с 15 часов до 7 минут после добавления индексов на регистры.

- неадекватный механизм распределения потоков. Слишком большие паузы между сбором информации и стартом фоновых заданий. Если поставил 30 потоков, то по-хорошему 30 потоков должны быть запущены постоянно и выполнять обработку порции данных, а не стартовать и тут же завершаться. Время обработки также сильно зависит от данных, какие-то потоки завершаются раньше чем другие, хотя размер порции был дан одинаковый. В таком случае с одного из потоков порцию можно забрать и отдать другому.

- неадекватные размеры порций для различных обработчиков обновления. В каких-то действительно по 1000 штук оптимально, а в каких-то и ПЕРВЫЕ 10000 это маловато, т.к. данные пишутся в регистр сразу за один заход через набор записей.

- некоторые обработчики, которые могут быть распараллелены написаны как однопоточные в бесконечном цикле. Задание на узле плана обмена одно и обработчик обрабатывает просто все в одном потоке по условию "Пока ЕстьДанные() Цикл". Один из таких обработчиков - заполнение поля Период в Статусах проверки документов.

- при обработке регистров накопления не отключаются итоги по регистру, что замедляет вставку

- заполнение данных для отложенных обработчиков обновления выполняются в монопольном режиме, что увеличивает время блокировки на вход пользователей. В моем случае заполнение данных для отложенной обработки выполнялось 4 часа, хотя вполне можно было бы запустить пользователей и делать это в самом регламентом задании как это происходит при перезапуске выполнения обработчиков отложенного обновления

- при перезапуске отложенных обработчиков обновления данные собираются заново для всех обработчиков, несмотря на то, что остался всего один незавершенный обработчик, да и написано в самом окне, что якобы будет перезапущены лишь незавершившиеся обработчики. Обманывают.

- часто сами таблицы "Изменения" вносят свою задержку, т.к. то там нет данных, то 20 миллионов регистраторов, MSSQL сервер работает с "протухшей" статистикой и появляются плохие планы запросов. Пришлось "рисовать" Plan Guide'ы, чтобы принудить запросы выбирать правильные планы без Table Spool

В целом делал все тоже самое - писал свои многопоточные обработки, которые позволяли распараллеливать обработчики по произвольному количеству фоновых заданий. С прошлого обновления у меня таких лежит теперь 5 штук, запускал их вручную с учетом зависимостей от других обработчиков.

MAXDOP на сервере не меняйте с 1 на 0 - становится хуже.
fancy; kauksi; ixijixi; sapervodichka; ye_s; +5 Ответить
8. saver77 60 11.01.24 17:34 Сейчас в теме
(2) Спасибо за информацию. Понятно, что не мы одни такие. Не понятно как люди обновляют большие базы, особенно с технологическим окном меньше 12 часов. У кого есть опыт в таких уловиях?

MAXDOP у нас 4. Ядер на сервере БД много, а некоторые запросы реально лучше себя чувствуют при 4. 0 - согласен, плохой вариант, тяжелый запрос может забрать все ядра.
3. triviumfan 93 11.01.24 09:50 Сейчас в теме

MAXDOP на сервере не меняйте с 1 на 0 - становится хуже.

Это прикол такой?
4. rambomax 11.01.24 12:48 Сейчас в теме
Основная логика поста:
Дано: одна женщина рожает одного ребёнка за девять месяцев. Автор предлагает брать девять женщин, чтобы ребёнок получился через месяц.
Ведь каждому понятно, что чем больше параллельных заданий запустить, тем быстрее работает сервер!
5. baracuda 2 11.01.24 16:59 Сейчас в теме
(4)
Технологическое окно для этой базы составляет 2,5 суток. На праздниках может быть больше, но это тоже не выход. При этом следует заметить, что процесс обновления очень слабо нагружает сервер 1С и сервер БД.

ваша метафора не самая удачная, так как автор укзаал что на сервере нет особой нагрузки в момент типового обновления
6. RustIG 1407 11.01.24 17:16 Сейчас в теме
Неудачный пример привели в первом абзаце. Пропишите возврат в начале процедуры. И не делайте перезапись документов планирования. Обновите все релизы УХ. После чего напишите свою обработку этих документов. Да и не надо вам обновлять эти документы в закрытом периоде. Короче, не надо потоки делать. Не в ту сторону смотрите, имхо.
9. saver77 60 11.01.24 17:43 Сейчас в теме
(6) "Пропишите возврат в начале процедуры." - не понял. Можете привести код в комментарии.
Я в одном из обновлений пробовал обрабатывать только объекты в рабочем периоде. Но где-то остатки "поехали", пришлось всё дообновлять. Да, это вариант, но непредсказуемый.
Вы пишите "Короче, не надо потоки делать. Не в ту сторону смотрите, имхо". Предложите свой вариант с подробностями. Может кому-то ваш вариант больше подойдёт.
baracuda; +1 Ответить
10. RustIG 1407 11.01.24 17:59 Сейчас в теме
(9)
Процедура ЗаполнитьДокументПланированияСписаниеСРасчетногоСчета() Экспорт

       //вот так
        Возврат;

	Запрос = Новый Запрос;
	Запрос.Текст = 
		"ВЫБРАТЬ
		|	СписаниеСРасчетногоСчета.Ссылка КАК Ссылка,
		|	СписаниеСРасчетногоСчета.УдалитьДокументПланирования КАК УдалитьДокументПланирования,
		|	СписаниеСРасчетногоСчета.ДокументПланирования КАК ДокументПланирования
		|ИЗ
		|	Документ.СписаниеСРасчетногоСчета КАК СписаниеСРасчетногоСчета
		|ГДЕ
		|	СписаниеСРасчетногоСчета.УдалитьДокументПланирования <> НЕОПРЕДЕЛЕНО
		|	И СписаниеСРасчетногоСчета.ДокументПланирования = НЕОПРЕДЕЛЕНО";
	
	РезультатЗапроса = Запрос.Выполнить();
	
	ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
	
	Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
		ДокументОбъект = ВыборкаДетальныеЗаписи.Ссылка.ПолучитьОбъект(); 
		ДокументОбъект.ДокументПланирования =  ВыборкаДетальныеЗаписи.УдалитьДокументПланирования;
		ОбновлениеИнформационнойБазы.ЗаписатьОбъект(ДокументОбъект);
	КонецЦикла;

КонецПроцедуры
Показать
15. saver77 60 12.01.24 12:03 Сейчас в теме
(10) Мне не надо делать возврат из типового обработчика, он будет выполнен многопоточной реализацией.

Возможно вы не до конца поняли идею статьи. Статья о том как стандартные обработчики обновления переписать на многопоточную реализацию минимальными трудозатратами. Многопоточная обвязка есть в статье, не надо даже качать расширение. Пример приведенный в статье - частный случай.

На счет не обновлять "закрытый" период. Пробовал, в нашей компании такой вариант не подходит.
16. RustIG 1407 12.01.24 13:12 Сейчас в теме
(15) мы не понимаем друг друга ...
вы привели пример - я написал что он неудачный...
Вы такого монстра придумали из-за чего? Из-за обработки документов ДокументПланирования?
Привели примитивный код изменения этих документов - которых у вас 2,5 млн....
И сделали вывод о необходимости многопоточности?

можно обновить релизы УХ без обновления ДокументаПланирования.
Далее после того как обновили ночью, выспались, утром кофе выпили, запускаете внешнюю обработку обновления документов ДокументПланирования - с упорядочиванием с текущего дня и до конца в прошлое время. Сначала обновляю текущие документы....Это снизит нагрузку на ваши отчеты, которые формируются по текущим данным...Они уже будут обновлены....
Дальше идете пить кофе , играть в сониплейстейшн.

Далее что я вижу у вас в потоках вырезан кусок кода
 ДокументОбъект = ВыборкаДетальныеЗаписи.Ссылка.ПолучитьОбъект(); 
        ДокументОбъект.ДокументПланирования =  ВыборкаДетальныеЗаписи.УдалитьДокументПланирования;
        ОбновлениеИнформационнойБазы.ЗаписатьОбъект(ДокументОбъект);


Вставлен в цикл Для каждого....
так это самый простой случай вы берете...
А если у разработчиков будет более сложная схема вызовов функций и обработки документов?....как вы поймете какой именно кусок кода надо в поток облачать?

Сама идея многопоточности интересна...Она реализована частично через фоновые задания. Плюс много об этом написано на ИС - но написано с аргументацией, что вот эти задачи надо завернуть в многопоток - под моей публикацией про многопотоки кто-то высказал что использует их для перепроведения документов при закрытии периода - в разрезе организаций делит потоки....

Обновление заворачивать в многопоток - зачем? Я считаю надо написать разработчикам, пусть изменят схему обновлений, поскольку она убыточна для таких организаций , как вы - у которых 2,5 млн документов ДокументПланирования + у которых закрытый период надо также обновлять... Я думаю мало таких, как вы.

Управлять многоптоком - достаточно сложная задача - и делать для всех чревато еще большим торможением и дополнительными багами на ближайшей перспективе....

Я не обсуждаю вашу идею и реализацию, я просто не увидел аргументов в пользу вашей идеи.
Я не раз сталкивался при обновлениях с разными ошибками, которые затягивали обновление - программа висит - через отладчик находил проблемные места - и как-то выкручивался - что-то придумывал разово...

Надеюсь, это теперь все...
artbear; Redokov; +2 Ответить
11. RustIG 1407 11.01.24 18:02 Сейчас в теме
(9) Возврат в начале процедуры - это стандартный способ обхода процедур.
Остатки не полетят - поскольку все остатки в регистрах, а здесь изменяется реквизит документа - не увидел перепроведение документа.
Пропишите отбор по дате - и вместо 2,5 млн документов получите последний квартал, который у вас открыт.
Да и вообще кому нужен документ планирования в закрытом периоде? Запланировали год назад - кому это надо?
12. RustIG 1407 11.01.24 18:07 Сейчас в теме
(9)ну вот и доказательство:

ДокументРежимЗаписи - РежимЗаписиДокумента - имеет смысл только для данных типа ДокументОбъект - режим записи документа. Если параметр не передан, то документ записывается в режиме "Запись".

Взято из синтаксиса БСП - процедуры ОбновлениеИнформационнойБазы.ЗаписатьОбъект(ДокументОбъект);
https://its.1c.ru/db/bsp319doc#content:1377:hdoc:_top:обновлениеинформационнойбазы.записатьобъект(документобъект)
17. FAMыч 13.01.24 11:33 Сейчас в теме
(12) И вот тут возникает очень простой вопрос: Зачем в данном конкретном случае городить многопоток, если эту задачу можно выполнить с помощью одного прямого запроса из SQL Management Studio?
13. RustIG 1407 11.01.24 18:09 Сейчас в теме
(9)
Предложите свой вариант с подробностями. Может кому-то ваш вариант больше подойдёт.

так уже... написал и предложил то, что написал ....
14. titanium2008 42 11.01.24 18:54 Сейчас в теме
УХ вообще особенная конфигурация с особенным качеством кода)) не раз писал разработчикам на партнерке про эти обработчики обновления , воз и ныне там. Автору спасибо за проделанную работу!
baracuda; +1 Ответить
18. artbear 1516 17.01.24 17:40 Сейчас в теме
(0) как решаете проблему зависания или падения одного из потоков?

что происходит после падения? просто повторный перезапуск всего и вся?

не увидел в коде ответов на этот вопрос
Оставьте свое сообщение