Navision - советы и секреты

  Все выпуски  

Navision - советы и секреты - Замер производительности малой кровью


Мы ищем таланты! Рассылке и базе знаний требуются авторы. Если у вас есть чем поделиться с другими - присылайте матерьялы на mailbox@naviart.ru. Опубликуем и поблагодарим!

 

Добрый день, уважаемые подписчики/коллеги!

 

Опросы

 

У нас на сайте закончился опрос "Какой версией Navision вы пользуетесь", по результатам уверенно лидируют 5-я и 3-я версии. Неудивительно, учитывая, что главным инструментом разработчика Navision по-прежнему остается напильник. Ну что ж, наляжем на статьи про старые версии, благо накопленный опыт позволяет.

 

Кроме того, открываем новый опрос - "Кто ты, маска?",  с целью узнать - кому вообще интересна тематика базы знаний про Навижн, и, само собой, скорректируем политику партии в отношении результатов. Думаю, главные интересанты - разработчики, но вдруг? В обчем, на главной странице.

 

Замер производительности малой кровью

 

Задача повышения производительности стояла и стоит перед нами (разработчиками) всегда. Не только в процессе написания свежего кода, но и месяцы (годы) спустя - когда нагрузка на систему естественным образом возрастает. Или неестественно - в тяжелые предновогодние дни, когда графики всех показателей похожи на карпатские горы. А особенно критичные - напоминают пик Эверест.

В общем, такие вещи надо мониторить желательно автоматически и постоянно, с извещениями о том, что на каком-то фронте (процессе) происходят невиданные доселе вещи - например, учет документа стал занимать 5 минут вместо 5 секунд.

Для этих целей был написан спец.инструмент - я бы даже назвал его мини-фреймворком :) Идея почерпнута из аспектно-ориентированного программирования.

По-простому говоря, очередной лог производительности, до безобразия простой в использовании:

1.       Имеется таблица Log, куда отписываются события трех видов - CheckPoint, Start и Finish.

a.       Checkpoint - идет фиксация прохождения некоей контрольной точки.

b.      Start - начало процесса (например, начало выполнения функции).

c.       Finish - окончание процесса (выход из функции). 

d.      На каждую функцию может быть только один Start и несколько Finish'ей - один в конце и один перед каждым EXIT'ом.

e.      Допускается вложенность процессов - т.е., если внутри одной функции идет вызов другой - это необходимо отражать в логе. При этом есть т.н. "уровень вложенности процессов", который при каждой открывающей скобке (Start) ныряет на единичку вглубь, а при каждой закрывающей скобке (Finish) выныривает обратно.

f.        Если за стартом сразу идет финиш - то две строки в логе только запутывают. Такая конструкция схлопывается в одну строчку со временем начала и окончания и ей присваивается тип Execution.

g.       В логе фиксируется:

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

2.       Имеется singleinstance-кодеюнит со следующими функциями:

a.       Start (txtMessage) - отписывает в лог новое событие - начало процесса.

b.      Finish (txtMesage) - закрывает скобку начала процесса, при этом ищется предыдущая открытая скобка с таким же сообщением (т.е. лучше, чтобы они были уникальными, но не обязательно). Рекурсия в данной версии не обрабатывается.

c.       Checkpoint (txtMessage) - отписывает в лог новое событие - прохождение контрольной точки.

d.      Enable (blnEnable) - включение/выключение записи в лог. По умолчанию запись ВЫКЛЮЧЕНА, ее необходимо принудительно включить в зависимости от настроек (можно вынести куда-нибудь галку в настроечную таблицу с проверкой прав на простановку этой галки).

3.       Имеется форма для анализа лога, в которой с помощью Indentation показана вложенность процессов.

 

Скачать его можно на странице http://naviart.ru/logger

 

Какие бонусы мы получаем при запуске такого протоколирования:

1.       Сразу видим тормозящие процессы.

2.       Видим вложенность вызовов функций, а в больших проектах она всегда очевидна, учитывая огромное количество кода на Validate'ах и т.п. Я в первый день "промышленной эксплуатации" нашел процесс, в котором 3 (три) раза подряд вызывается одна и та же функция.

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

 

Сам процесс внедрения такого логгирования крайне прост - обертываем в скобки "Старт-Финиш" все критичные процессы, перезапускаем систему, наливаем кофе и следим за логом. Каждый найдет для себя массу интересного :)

 

К этому можно прикрутить еще много разных вещей, например ссылку на обрабываемый документ, по результатам работы лога можно автоматически выстроить дерево функций проекта. При должной усидчивости и смекалке можно обернуть ВСЕ функции навижна (в автоматическом режиме), запустить лог на месяц и снять дерево использованных функций самого навижна. Можно+ В общем, много чего можно, но без этого очень полезная вещь.

 

Инджой!

 

 

Troubleshooting

 

В рамках развития практической ценности ресурса - открываем на сайте новый раздел - "Troubleshooting", куда попадут разные проверочные и корректировочные скрипты, в основном на SQL. Первой ласточкой отписался Дмитрий Пугаев (http://naviart.ru/fix-ndodefault-constraint) с исправлением ошибки ниже:

Microsoft Business Solutions-Navision
Произошла следующая ошибка(и) SQL Server при обращении к таблице Purch. Inv. Header:
3728,"42000″,[Microsoft][ODBC SQL Server Driver][SQL Server] $ndodefault$860319737$66′ is not a constraint.
3727,"42000″,[Microsoft][ODBC SQL Server Driver][SQL Server]Could not drop constraint. See previous errors.
SQL:
ALTER TABLE "work"."dbo"."YOUR COMPANY$Purch__Inv__Header" DROP CONSTRAINT "$ndodefault$860319737$66″
OK

Лечится она следующим скриптом:

-- Скрипт исправляет ndodefault 
 
DECLARE @Old_Name   VARCHAR(100),
        @New_Name   VARCHAR(100),
        @ParentID   VARCHAR(100),
        @i          INT  
 
DECLARE Cur_constr CURSOR LOCAL FAST_FORWARD READ_ONLY TYPE_WARNING 
FOR
    SELECT [name], CAST ([parent_object_id] AS VARCHAR)
    FROM   [sys].[default_constraints]
    WHERE  NAME LIKE '$ndodefault$%$%'
           AND [is_system_named] = 0
    ORDER BY
           parent_object_id
 
OPEN  Cur_constr
FETCH NEXT FROM Cur_constr INTO @Old_Name , @ParentID                         
SET @i = 0
 
DECLARE @SQL_Expr AS nVARCHAR(MAX)
 
WHILE @@Fetch_Status = 0
      AND @i < 200000
BEGIN
    SET @New_Name = '$ndodefault$' + @ParentID + SUBSTRING(@Old_Name, 
    CHARINDEX('$', @Old_Name, 13), LEN(@Old_Name))
    IF @Old_Name <> @New_Name
    BEGIN
        SET @i = @i + 1 
        SET @SQL_Expr = ' EXEC sp_rename ' + QUOTENAME(@Old_Name) + ', ' 
        + QUOTENAME(@New_Name) + '; Print '  + CAST(@i AS nVARCHAR)
        EXEC sp_executeSQL @statement = @SQL_Expr 
    END
 
    FETCH NEXT FROM Cur_constr INTO @Old_Name , @ParentID
END

На сегодня все, спасибо за внимание :)

 

Ах, еще, забыл - теперь дружим с твиттером, navisionart  :)

 

С уважением,

Андрей Стрельников

Группа "Технологии как Искусство".

 

http://naviart.ru

mailto:mailbox@naviart.ru

 

P.S. Мы ищем таланты! Рассылке и базе знаний требуются авторы. Если у вас есть чем поделиться с другими - присылайте матерьялы на mailbox@naviart.ru. Опубликуем и поблагодарим!

 

P.P.S. Читатели тоже требуются :) Ваши отзывы - ресурс для развития ресурса :)

 


В избранное