Освобождение ресурсов сессии
В старых версиях Microsoft Dynamics AX, до Kernel Rollup, существовала проблема (в особенности под Oracle), когда DAX не закрывал сессии базы данных корректно. Например, можно было увидеть, что DAX вроде как закрыл сессию и в OEM, если брать в качестве примера Oracle, сессия исчезла, но процесс Oracle не был закрыт.
Отслеживать данную ситуацию можно с помощью простого скрипта, запуская его в SQL *Plus:
select count(*) total,
sum(decode(s.sid,null,0,1)) with_session
sum(decode(s.sid,null,1,0)) without_session
from v$session s,v$process p
where s.paddr(+) = p.addr
В качестве результата можем получить:
TOTAL with_SESSION without_SESSION
---------- ---------------------- --------------------------
115 11 104
With_SESSION – число процессов, задействованных для открытых сессий пользователей.
Without_SESSION – число процессов, задействованных закрытыми сессиями. Данный результат можно получить при установке в конфигурации DAX параметра 'Time out connection running when idle’.
Если же число, полученное как TOTAL, равно числу процессов в инициализационном файле Oracle (init.ora), то можем получить сообщение об ошибке ORA-04030.
Для того, чтобы обойти данную проблему необходимо установить в конфигурации DAX параметр 'Leave connection running when idle’.
Есть и другой путь, со стороны Oracle. Можно много дискуссировать, где проблема (например, данная проблема может проявляться потому, что по умолчанию Oracle держит процесс 30 минут), но решение есть в базе данных. В Oracle можно использовать нижеследующий сценарий и использовать утилиту DBkill.exe для удаления 'мертвых' сессий в Oracle. Если же в качестве базы данных Oracle используется версия 9.2.0.6 или более старшая, то можно использовать другой процесс, называемый "Dead Connection Detection".
Самый простой путь – использовать сценарий, очищающий 'мертвые' сессии каждые 5-10 минут.
Желательно также установить параметры конфигурации DAX 'Number of retries when creating connection’ и 'Retry delay when creating connection’, например первый параметр в 2, а второй в 100 мс. Это позволяет уменьшить число соединений, поскольку пул соединений AOS будет запрашиваться дважды с заданным интервалом для обнаружения уже существующей сессии, свободной для использования (вместо открытия новой каждый раз).
Итак, как найти идентификатор процесса?
Select s.saddr, s.paddr, s.sid, p.spid THREADID, p.pid, p.addr from v$session s full join v$process p on s.paddr = p.addr;
Затем можно использовать Orakill.exe (утилита доступна только на платформе Win32): Orakill <SID> <ThreadID> , где SID – экземпляр Oracle, а TreadID – идентификатор процесса для очистки.
Также для брошенных сессий актуальными параметрами являются параметры протокола TCP\IP, в частности KeepAliveTime. В части настройки протоколов это актуально и для сервера MS SQL Server. Детали можно посмотреть на сайте Microsoft: “How to troubleshoot orphaned connections in SQL Server” или “How to Determine Loss of Client/Server Connection”. Можно уменьшить, например, параметр KeepAliveTime c 2 часов по умолчанию до 5-10 минут (180000-300000 в десятичном выражении).