Хорошее время.
Несколько дней назад наша команда БД обнаружила, что есть сеансы с статусом "АКТИВ" для неактивных клиентов. Исследование показало, что для таких вопросов есть два основных источника:
Для меня странно, что все эти сеансы находятся в статусе "ACTIVE". Может кто-нибудь, пожалуйста, уточнить, как это может быть (может быть, есть что-то с лежащими в основе процессами, которые ждут соответствующих сокетов или... Насколько все хорошо при правильном завершении tomcat, кажется, что первопричина связана с транзакциями...)?
Помогло бы это, если бы мы установили 'IDLE_TIME' (для всех подключений) и 'EXPIRE_TIME' (для всех наших экземпляров RAC)?
Правильно ли, что должны иметь место следующие сценарии (с указанными выше параметрами):
ОБНОВЛЕНИЕ:
Кажется, что единственный способ работать с такой ситуацией - настроить экземпляры Oracle. Есть результаты моего расследования:
https://community.oracle.com/thread/873226?start=0&tstart=0
Для Dead Connection Detection используется серверный параметр файла sqlnet.ora сервера SQLNET.EXPIRE_TIME = <число минут>
Другой вариант - реализовать idle_time в настройках профиля. И затем, когда какая-то работа завершит сеансы SNIPED (когда idle_time будет достигнуто, сеанс станет от INACTIVE до SNIPED).
Если я открою соединение и уйду на обед, ограничение IDLE_TIME приведет к прекращению моего сеанса после 15 минут бездействия. EXPIRE_TIME из 15 минут будет просто отправить Oracle пакет в мое клиентское приложение, чтобы убедиться, что клиент не сработал. Если клиент встал, он ответит на пинг, и мой сеанс останется неопределенным. EXPIRE_TIME только заставляет сеансы убивать, если клиентское приложение не отвечает на пинг, что означает, что процесс клиента завершился неудачно или что клиентская система потерпела неудачу. IDLE_TIME будет убивать сеансы, которые не имеют активности в течение определенного периода времени, но, как правило, это плохо работает с приложениями, поддерживающими пул соединений, поскольку предполагается, что пул соединений будет иметь достаточное количество соединений, которые бездействуют для периодов дня, и поскольку приложения, использующие пулы соединений, плохо реагируют на соединения в пуле, убиваемом.
https://asktom.oracle.com/pls/asktom/f?p=100:11:0::P11_QUESTION_ID:2233109200346833212
TCP/IP не прерывает работу по умолчанию, по дизайну. Когда соединение уходит, клиент и/или сервер не получают немедленного уведомления. Таким образом, если ваш клиент подключается к базе данных и ничего не делает, и вы отключите свой клиент (синий экран, убейте его, вытащите сетевой кабель, выбейте компьютер, как бы то ни было), шансы на то, что сеанс останется в базе данных. Сервер не будет знать, что он никогда не получит от вас сообщения. У нас есть мертвое обнаружение клиента, если это становится проблемой:
http://download.oracle.com/docs/cd/B12037_01/network.101/b10776/sqlnet.htm#sthref476
Что касается активного сеанса, это очень просто. Вы открываете соединение, вы отправляете запрос по этому соединению, например, "lock table T". Таблица t заблокирована вашей транзакцией в вашем сеансе. Затем вы отправляете блок кода, например:
begin loop dbms_lock.sleep(5); конец цикла; конец; /
ваш сеанс будет активным до тех пор, пока этот код будет запущен - клиентский процесс блокируется в сокете, ожидающем, пока сервер вернет результат - ответ (который, конечно, никогда не придет). Сервер не трогает сеть прямо сейчас - он активен с вашим кодом. Итак, если ваш клиент "умирает" прямо сейчас - блок кода будет продолжать работать, запускаться и запускаться - и поскольку он никогда не совершает - он будет просто висеть там и запускаться, и, конечно, любые блокировки, которые у вас есть, будут оставаться на месте.
http://www.dba-oracle.com/t_connect_time_idle_expire_timeout.htm
Параметр sqlnet.expire_time используется для установки временного интервала в минутах, чтобы определить, как часто следует отправлять пробник, проверяя, что соединения клиент/сервер активны. Если вам необходимо убедиться, что соединения не остаются открытыми неограниченно (или до времени, заданного параметрами операционной системы), вы должны установить значение, большее 0. Это защищает систему от подключений, открытых открытыми из-за ненормального завершение клиента.
https://asktom.oracle.com/pls/apex/f?p=100:11:0::NO::P11_QUESTION_ID:453256655431
Если сеанс ожидает блокировки ресурсов или защелок, и если это время ожидания превышает значение idle_time в профиле, выполняется ли сеанс sniped, даже если сеанс находится в середине транзакции и ожидает блокировки и т.д.
Если да, будут ли какие-либо записи в журнале предупреждений.
Следовать за
если вы ожидаете блокировки, вы активны - не праздны.
Эта страница привлекла мое внимание, за шесть месяцев до того, как у меня появилась поддержка Oracle для защиты данных, поэтому один из ребят из Oracle заметил, что я использую Idle_Time, и он сказал мне, что этот параметр не работает очень хорошо, потому что Oracle не выпускает ресурс сеансов, которые были отмечены как отловленные, до следующего попытки пользователя использовать его (ожидание, чтобы сообщить, что ваша сессия была убита, чтобы очистить ресурсы сеанса)
Следовать за
... после расследования... существует "сессия", которая не исчезнет, пока клиент не подтвердит это, но "транзакция" исчезла.
Том, я изменил профиль, чтобы иметь IDLE_TIME = 240 (4 часа) и удостоверился, что для параметра resource_limit установлено значение TRUE. Когда я запрашиваю сеанс v $, я вижу некоторые "отрезанные" сеансы, но также и "неактивные", которые простаивают более одного дня. У всех этих пользователей этот профиль назначен им. Если сеанс пользователя был подключен до того, как был установлен idle_time, повлияют ли эти сеансы на эти сеансы или нет? Некоторое время назад я внес изменения. Есть ли что-нибудь еще, что я должен был сделать?
Следовать за
Если сеанс пользователя был подключен до того, как был установлен idle_time, они будут "grandfathered" in - они не будут sniped. это влияет только на новые сеансы.
http://agstamy.blogspot.ru/2011/03/profile-and-resource-limit.html
Мы проверили параметры, перечисленные в приведенном выше исследовании, и все работает правильно!