Справочник системных ошибок и решений

Windows Server, Active Directory, 1С:Предприятие, СУБД, Linux, Cisco, MikroTik, Asterisk.

⚠️ Важная информация Все материалы, инструкции, команды и скрипты на сайте предоставлены исключительно в ознакомительных целях. Их применение может повлиять на работу операционной системы, программного обеспечения, баз данных, сетевого оборудования и других компонентов инфраструктуры. Перед выполнением действий создайте резервную копию и по возможности протестируйте изменения в безопасной среде. Пользователь самостоятельно оценивает риски и несет ответственность за результат. При отсутствии необходимых знаний обратитесь к квалифицированному ИТ-специалисту.

ORA-01000 1С:Предприятие и СУБД

Ошибка ORA-01000: maximum open cursors exceeded в Oracle DB

Обновлено: 26.08.2026 · Официальная документация ↗
  • Ошибка ORA-01000: maximum open cursors exceeded в высоконагруженных приложениях и веб-сервисах.
  • Постепенная деградация производительности сессий и утечка памяти PGA.
  • Количество открытых курсоров на одну сессию достигает установленного предела в параметре open_cursors.

1. Проверка текущего лимита open_cursors

SHOW PARAMETER open_cursors;

2. Поиск сессий с наибольшим числом открытых курсоров

SELECT a.sid, s.username, s.program, s.machine, a.value AS open_cursors
FROM v$sesstat a
JOIN v$statname b ON a.statistic# = b.statistic#
JOIN v$session s ON a.sid = s.sid
WHERE b.name = 'opened cursors current'
ORDER BY a.value DESC;

3. Определение SQL-запросов, вызывающих утечку курсоров

SELECT c.sid, c.user_name, c.sql_text, COUNT(*)
FROM v$open_cursor c
WHERE c.sid = <SID_ИЗ_ПРЕДЫДУЩЕГО_ЗАПРОСА>
GROUP BY c.sid, c.user_name, c.sql_text
ORDER BY COUNT(*) DESC;

4. Динамическое увеличение параметра open_cursors

Параметр можно изменить на лету без перезапуска экземпляра СУБД:

ALTER SYSTEM SET open_cursors=1500 SCOPE=BOTH;

5. Исправление утечек курсоров в коде приложения

Убедитесь, что в коде (Java, C#, PL/SQL) все дескрипторы закрываются в блоках finally или через try-with-resources:

// Пример Java JDBC
try (PreparedStatement ps = conn.prepareStatement(sql);
     ResultSet rs = ps.executeQuery()) {
    while (rs.next()) { /* processing */ }
} // Автоматическое закрытие ResultSet и Statement
💡 Практика специалистов: Если параметр `open_cursors` установлен в 2000-3000, но ошибка ORA-01000 продолжает периодически возникать — в коде приложения 100% присутствует Cursor Leak (например, циклический вызов `conn.createStatement()` внутри цикла обработки сообщений брокера).

Частые вопросы (FAQ)

В чем разница между представлениями v$open_cursor и v$sesstat ('opened cursors current')?

v$open_cursor показывает курсоры, находящиеся в кэше сессии (Session Cached Cursors) плюс реально открытые. Истинное число удерживаемых открытых дескрипторов показывает только метрика 'opened cursors current' в v$sesstat.

Приводит ли увеличение open_cursors к высокому потреблению оперативной памяти?

Нет. Параметр open_cursors задает лишь верхний лимит. Память в PGA выделяется динамически только под фактически открытые дескрипторы.

Почему PL/SQL курсорные циклы FOR r IN (SELECT ...) не вызывают ORA-01000?

Неявные курсоры в циклах FOR r IN (...) управляются ядром PL/SQL автоматически — они открываются, читают данные с предвыборкой (bulk fetch) и гарантированно закрываются при выходе из блока.

Закрываются ли открытые курсоры при выполнении COMMIT?

По умолчанию обычные курсоры остаются открытыми после COMMIT. Только курсоры, объявленные с опцией WITH HOLD (в ряде интерфейсов) или закрытые явно через CLOSE, освобождают ресурсы.

Полезные материалы
Рекомендуем