Проблема с открытыми курсорами

Мы установили открытые курсоры SCOPE = обе на 1000. У нас есть финансовое приложение, в которое в течение дня входит 20-25 пользователей, которое подключается к базе данных Oracle 19c. В приложении время от времени мы видим ошибку превышения лимита открытых курсоров ORA-01000.

Однако, когда мы смотрим на открытые курсоры, текущие с этим запросом, мы не видим ни одного отдельного сеанса где-либо около 1000. Это запрос, который я запускаю для этого:

select a.value, s.username, s.sid, s.serial# from 
v$sesstat a, v$statname b, v$session s 
where a.statistic# = b.statistic#  
and s.sid=a.sid 
and b.name = 'opened cursors current' 
and s.username is not null;

Однако в совокупности мы увидим, что все элементы в представлении v$open_cursors превышают 1000.

select Count(*)
from v$open_cursor 
where user_name IS NOT NULL;

Похоже, что под SYS открыто более 600 курсоров, многие из них, как я предполагаю, являются фоновыми процессами. Они остаются открытыми под cursor_type OPEN_RECURSIVE или что-то в этом роде.

Таким образом, чтобы подвести итог всему этому, кажется, что ни один отдельный сеанс не приближается к нашему пределу в 1000, но кажется, что коллективно мы приближаемся к 1000. Как правильно установить предел ОТКРЫТЫХ КУРСОРОВ, чтобы ни один сеанс не получил до 1000? Что делает этот параметр для SCOPE=both? Спасибо!

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

ОБНОВЛЕНИЕ. Эта проблема возникает после того, как я перенес это приложение с драйвера Microsoft ODBC на драйвер Oracle ODBC. Похоже, что драйвер Microsoft обрабатывал курсоры по-другому. Это приложение очень плохо справляется с закрытием ресурсов, но я не могу вносить все необходимые изменения, потому что оно распространено по всей системе. Microsoft собирается отключить драйвер Microsoft ODBC в любое время в будущем и рекомендует немедленно отказаться от него.

ДАЛЬНЕЙШЕЕ ОБНОВЛЕНИЕ: сегодня я экспериментировал с различными настройками драйвера ODBC Oracle и обнаружил, что настройка кэша операторов отрицательно влияет на открытые курсоры. Даже с 20 операторами казалось, что количество открытых курсоров резко возросло. Когда я полностью отключаю кэширование операторов, я вижу очень управляемое количество сгенерированных курсоров. Возможно, это ошибка драйвера, потому что он создает больше курсоров, чем у меня есть в моем кэше операторов.


person Charles Owen    schedule 08.04.2021    source источник
comment
Значение по умолчанию 50 довольно низкое. Просто увеличьте до 2000 и будет вам счастье.   -  person Wernfried Domscheit    schedule 08.04.2021
comment
Это то, что я сделал, эффективно подняв лимит до 2000.   -  person Charles Owen    schedule 08.04.2021
comment
scope = both означает, что вы хотите изменить параметр как в memory (т.е. действителен сразу), так и в spfile (т.е. действителен после следующего перезапуска).   -  person Marmite Bomber    schedule 08.04.2021
comment
Ознакомьтесь с моим ответом на этот вопрос, чтобы узнать, как найти причину открытых курсоров.   -  person Jon Heller    schedule 09.04.2021
comment
Проблема заключается в том, что ни один конкретный сеанс не приблизился к пределу, когда произошла ошибка. Почему это произошло?   -  person Charles Owen    schedule 11.04.2021
comment
Джон У меня сложилось впечатление, что представление v$open_cursor не является подходящим местом для поиска открытых курсоров, потому что оно содержит все виды курсоров, включая кешированные курсоры сеанса. Что делает представление gv$open_cursor, чего не делает другой запрос? т? Я попробую это.   -  person Charles Owen    schedule 11.04.2021
comment
@CharlesOwen Чтобы сгенерировать эту ошибку, один из сеансов должен был превысить лимит. Эти ошибки могут генерироваться менее чем за секунду, а затем полностью исчезать при закрытии сеанса, поэтому их может быть чрезвычайно сложно отследить, и вам может потребоваться непрерывный цикл в блоке PL/SQL для проверки наличия проблемы. Я не уверен в точной разнице между GV_OPEN_CURSOR и другой запрос, но все курсоры, перечисленные в этом представлении, учитываются в пределе, поэтому я не уверен, имеет ли это значение.   -  person Jon Heller    schedule 12.04.2021