Вход | Регистрация



Зависание SQL-сервера при при прометке на удаление элементов справочников

Зависание SQL-сервера при при прометке на удаление элементов справочников
Я
   NewUser10
 
14.10.16 - 11:06
Добрый день. Microsoft SQL сервер 2012 (64 bit). Платформа (8.3.7.1759). Физически SQL и сервер 1С находятся на одном выделенном серверном компе.
Когда то была написана синхронизация по COM контрагентов и их договоров между КА и УНФ.
На днях обратил внимание на кучу одинаковых договоров у отдельных контрагентов. Причина проста: синхронизация осуществлялась по наименованию (доп реквизит у договора по условиям задачи добавлять нельзя, нумерацию тоже попросили оставить неизменной, поэтому оставалось синхронизировать по наименованию), но длина наименования в КА 100, а в УНФ 50...
Ну да ладно, причина была выявлена, алгоритм синхронизации уточнен. Так как действие одноразовое, быстренько набросал обработку пометки на удаление дублей договоров, чтобы потом их удалить штатными средствами:

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


&НаСервере
Процедура выполнитьНаСервере()
    Выборка = Справочники.Контрагенты.Выбрать(); 
    Пока Выборка.Следующий() Цикл 
        ПроверитьДубли(Выборка); 
    КонецЦикла;
КонецПроцедуры

В файловом варианте обработка в течение часа пометила на удаление порядка 30000 договоров, которые потом успешно удалились штатными средствами.
А вот при запуске на сервере (в нерабочее время), все рабочие базы стали жутко тормозить. Через два часа работы я попытался убить свой сеанс консолью. Консоль полторы минуты думала, потом выдала ошибку. Зависла 1с на моем локальном компе, пришлось ее выбить через диспетчер задач. Затем перезапустил службу сервера 1С. После перезапуска рабочий процесс (судя по времени запуска) остался. Убил все сеансы, перезапустил службу сервера 1С, после этого процесс перезапустился, но бызы продолжали дико тормозить пока через 8 часов не перезапустил SQL...
Понимаю, что для оптимизации установки пометки удаления можно было сделать транзакции по несколько сотен элементов, можно было в конце концов выполнить чистку в файловом варианте с последующей загрузкой обновленной базы... У меня вопросы:
1. Что в принципе не так, что так подвесило SQL? В чем, как говорится суть подвисания и почему SQL сервер был в коматозе до перезагрузки, даже после перезапуска сервера 1С?
2. Можно ли разграничить ресурсы, чтобы при выполнении тяжелых задач все базы не подвисали и как это сделать?
 
 
   Ёпрст
 
1 - 14.10.16 - 11:14
с таким кодом я бы тоже завис, ну или хотя бы матом ругнулся
   Ёпрст
 
2 - 14.10.16 - 11:15
1. код в топку
2. читать сп на ночь
   Йохохо
 
3 - 14.10.16 - 11:15
Записать?
   NewUser10
 
4 - 14.10.16 - 11:21
(1,2) Да читаю и СП и систему стандартов (http://its.1c.ru/db/v8std). Можно конкретнее, из-за каких моментов код плох, как решаются подобные задачи и что было с SQL?
   Ёпрст
 
5 - 14.10.16 - 11:32
(4) запрос в цикле, выборка полей через точку, ну и весь код, в топку.

Написать один запрос, получить все договора к пометке на удаление, обойти выборку, пометить.
+ По-уму, искать ссылки нужно на помечаемые объекты, хотя бы в одном из регистров. Ибо оне ужо могли быть использованы в документах.
   Serg_1960
 
6 - 14.10.16 - 11:40
Из-за каких? Из-за процедуры ПроверитьДубли(). Всё что там написано - можно сделать запросом (кроме пометки на удаление). Ну, по крайней мере, однозначно не стоит в цикле тянуть весь объект из-за банального обращения к реквизиту через точку - это всё можно сделать в запросе.

Неверный алгоритм изначально. Имхо, помечать на удаление дубли нужно те, на которые нет ссылок или их меньше всего.

Имхо, да и циклы тут вообще не нужны - запрос по всему справочнику может определить количество дублей по наименованию и вернуть только нужные вам записи к удалению.
   NewUser10
 
7 - 14.10.16 - 11:43
(5) Я имел в виду, какие моменты кода имели фатальные последствия для SQL? То что одним запросом все договора выбрать упорядочить и потом помечать, я понимаю. Рассчитывал, что при разумном количестве контрагентов одноразово сойдет и так. Кроме того, проанализировав базу, мне было понятно, что использовались только ранее заведенные по времени договора, отсюда и сортировка по коду, которой действительно оказалось достаточно. До конца все вычистилось штатным поиском дублей, который вначале отказался работать из-за большого объема выбранных элементов... Вопрос я больше задавал с целью, что творилось с SQL? Код привел, чтобы Знающие люди сказали, он просто неоптимален (далеко неоптимален), или в нем есть убийственные для SQL блоки.
И дальше, если он просто неоптимален, то как правильно делать, чтобы тяжелые задачи не делали неработоспособными все базы?
   NewUser10
 
8 - 14.10.16 - 11:46
(6) А для базы имеет значение, помечаются на удаление объекты, на которые есть ссылки или нет? Дело в том, что в файловой базе в результате только три из тридцати тысяч помеченных договоров не были удалены, остальные были без ссылок...
   NewUser10
 
9 - 14.10.16 - 11:51
+(5) Хотел узнать, как и что убило SQL, мой код или то, что я убивал сеанс, не дождавшись завершения своего кода...
   Serg_1960
 
10 - 14.10.16 - 11:55
Отладка, замер производительности - и ты сам поймёшь, чем плох твой код :)
 
 Рекламное место пустует
   NewUser10
 
11 - 14.10.16 - 12:01
Да, спасибо, похоже за последнее время второй раз наступаю на те же грабли (обращение к результату запроса через две точки). А по поводу разграничения ресурсов, если в одном SQL крутятся несколько баз, можно ли по ним ресурс разграничить? Просто SQL - это вотчина сисадмина...
   NewUser10
 
12 - 14.10.16 - 12:30
(10) При замере производительности подавляющее время занимают, как я и думал, получение объекта и пометка объекта на удаление...
   Йохохо
 
13 - 14.10.16 - 12:36
в запросе получи все поля, чтобы не было то.ч.ек, весь цикл после запроса оберни в явную транзакцию, откажись от получения объекта
   NewUser10
 
14 - 14.10.16 - 12:53
(13) Спасибо, первые два совета уже воплотил, а как отказаться от получения объекта?
   H A D G E H O G s
 
15 - 14.10.16 - 13:01
(9) Сервер убил твой запрос. 1С умер, когда SQL выжрал всю память. Потом, под эту дудку, умерла винда и интерфейсная система. SQL оставался при это живым, но без интерфейса. Даже когда 1С был завален, и винда немного приподнялась из свопа (но только немного) - ей этого не хватило и "все тормозило". Перезапуск SQL решил проблему.

Ограничивайте SQL.

Такое вот мое гадание на гуще.
   Йохохо
 
16 - 14.10.16 - 13:05
(14) никак, поспешишь насмешишь
   NewUser10
 
17 - 14.10.16 - 13:15
(15) Делать настройку SQL, например по (http://catalog.mista.ru/public/65955/)?
   H A D G E H O G s
 
18 - 14.10.16 - 13:19
(17) Это минимум. На ИТС есть более подробная настройка.
   H A D G E H O G s
 
19 - 14.10.16 - 13:21
Этот адрес надо всем записать в "Избранное" и передавать потомкам
http://its.1c.ru/db/metod8dev#content:5904:hdoc
   H A D G E H O G s
 
20 - 14.10.16 - 13:22
   NewUser10
 
21 - 14.10.16 - 13:36
(19),(20) Спасибо, читаю. Думаю, не один день нужно, чтобы "попасть в тему"...
   ptiz
 
22 - 14.10.16 - 14:07
(19) Ух ты!
А вот это:
tempdb - Разбить базу на 4 файла данных.
Почему именно 4 ?
   H A D G E H O G s
 
23 - 14.10.16 - 14:24
(22) Спросите об этом Александра.


Список тем форума
Рекламное место пустует  Рекламное место пустует
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.
Тема не обновлялась длительное время, и была помечена как архивная. Добавление сообщений невозможно.
Но вы можете создать новую ветку и вам обязательно ответят!
Каждый час на Волшебном форуме бывает более 2000 человек.
Рекламное место пустует