Oracle JVM — один із тих компонентів, що мовчки ламається і залишається зламаним до того моменту, поки щось нижче по ланцюгу не вибухне в найгірший можливий момент. Цей пост розбирає кожен діагностичний рівень — від перевірки наявності в реєстрі до аналізу пулів пам’яті — щоб ви могли тріажувати проблему JVM за хвилини, а не години.
Усі запити виконуються як DBA в SQL*Plus проти бази даних у стані OPEN. Написано для Oracle 11.2.0.3.2; примітки для 19c / 21c включено там, де поведінка відрізняється.
Діагностичний чеклист — загальна картина
Перш ніж заглиблюватися в кожен крок, ось повна картина. Виконуйте перевірки по порядку — ранні кроки швидкі й першими виключають очевидні причини.
| # | Перевірка | Об’єкт запиту | Що шукаємо |
|---|---|---|---|
| 1.1 | Банери компонентів | ALL_REGISTRY_BANNERS | Присутні JServer JAVA Virtual Machine і Oracle Database Java Packages |
| 1.2 | Реєстр компонентів | DBA_REGISTRY | JAVAVM і CATJAVA, обидва VALID |
| 1.3 | Прапор опції рушія | V$OPTION | Java = TRUE |
| 2.1 | Кількість Java-об’єктів | DBA_OBJECTS | SYS ≥ ~19 000 JAVA CLASS; нуль рядків INVALID |
| 2.2 | Пакет DBMS_JAVA | DBA_OBJECTS | Усі записи PACKAGE і PACKAGE BODY зі статусом VALID |
| 2.3 | Список невалідних об’єктів | DBA_OBJECTS + sys.javasnm$ | no rows selected |
| 2.4 | Пам’ять Java Pool | V$SGASTAT | Пул присутній; вільна пам’ять > 5 МБ |
| 2.5 | Java-ролі | DBA_ROLES | Усі п’ять основних ролей присутні |
Частина 1 — Чи встановлено JVM взагалі?
1.1 ALL_REGISTRY_BANNERS
Це представлення — найшвидша перевірка на здоровий глузд. Воно перераховує кожен компонент, що завершив встановлення та зареєстрував себе як валідний. Для того щоб JVM вважалася працездатною, мають бути присутні два рядки.
SELECT *
FROM all_registry_banners;
Здоровий вивід — обидва рядки мають бути присутні:
JServer JAVA Virtual Machine Release 11.2.0.3.0 - Production
Oracle Database Java Packages Release 11.2.0.3.0 - Production
Повний приклад здорової бази даних:
BANNER
-------------------------------------------------------------------
Oracle Database Catalog Views Release 11.2.0.3.0 - 64bit Production
Oracle Database Packages and Types Release 11.2.0.3.0 - Production
Oracle Workspace Manager Release 11.2.0.3.0 - Production
JServer JAVA Virtual Machine Release 11.2.0.3.0 - Production
Oracle XDK Release 11.2.0.3.0 - Production
Oracle Database Java Packages Release 11.2.0.3.0 - Production
Oracle Expression Filter Release 11.2.0.3.0 - Production
Приклад бази даних без JVM:
BANNER
-------------------------------------------------------------------
Oracle Database Catalog Views Release 11.2.0.3.0 - 64bit Production
Oracle Database Packages and Types Release 11.2.0.3.0 - Production
Oracle Workspace Manager Release 11.2.0.3.0 - Production
Oracle Expression Filter Release 11.2.0.3.0 - Production
Якщо відсутній будь-який із банерів JVM — не зупиняйтеся тут. Переходьте до DBA_REGISTRY, щоб визначити: компонент відсутній чи просто невалідний.
1.2 DBA_REGISTRY
DBA_REGISTRY дає повну картину: не лише чи присутній компонент, але й його точний статус. Саме тут ви розрізняєте JVM не встановлено (немає рядків) і JVM встановлено, але пошкоджено (статус INVALID). Різниця важлива — шляхи виправлення відрізняються.
SELECT comp_id, comp_name, version, status
FROM dba_registry;
Здоровий вивід — обидва компоненти присутні та VALID:
| COMP_ID | COMP_NAME | VERSION | STATUS |
|---|---|---|---|
| EXF | Oracle Expression Filter | 11.2.0.3.0 | VALID |
| OWM | Oracle Workspace Manager | 11.2.0.3.0 | VALID |
| CATALOG | Oracle Database Catalog Views | 11.2.0.3.0 | VALID |
| CATPROC | Oracle Database Packages and Types | 11.2.0.3.0 | VALID |
| JAVAVM | JServer JAVA Virtual Machine | 11.2.0.3.0 | VALID |
| XML | Oracle XDK | 11.2.0.3.0 | VALID |
| CATJAVA | Oracle Database Java Packages | 11.2.0.3.0 | VALID |
Три можливі результати:
- JAVAVM і CATJAVA відсутні — JVM ніколи не встановлювалася. Потрібне повне встановлення через
$ORACLE_HOME/javavm/install/initjvm.sql. - JAVAVM або CATJAVA присутні зі статусом INVALID — JVM встановлено, але пошкоджено. Потрібне перевстановлення або цільова рекомпіляція.
- Обидва присутні та VALID — переходьте до наступних перевірок.
Oracle 19c / 21c — примітка Multitenant: JVM є компонентом рівня PDB в CDB-архітектурах. Виконуйте цей запит, підключившись до цільового PDB, а не до
CDB$ROOT.CDB$ROOTне покажеJAVAVMабоCATJAVAнезалежно від стану JVM у PDB.
1.3 V$OPTION
Цю перевірку легко пропустити, а вона виловлює специфічний клас проблем: об’єкти JVM можуть бути повністю встановлені та валідні, тоді як опція Java-рушія вимкнена на рівні інстансу. У такому стані жоден Java-код не виконається — ви отримаєте лише ORA-29549: class ... has changed, Java session state cleared або подібні помилки рантайму.
SELECT *
FROM v$option
WHERE parameter = 'Java';
| PARAMETER | VALUE |
|---|---|
| Java | TRUE |
TRUE означає, що опція ліцензована та активна. FALSE означає, що виконання Java вимкнено на рівні рушія — потрібне перелінкування бінарника Oracle із увімкненою опцією Java, що є операцією на рівні ОС хоста бази даних.
Примітка Oracle 19c / 21c: Oracle Database XE та деякі керовані хмарні конфігурації Oracle поставляються з
Java = FALSE, навіть якщо схемні об’єкти існують. Якщо ви на керованій платформі — уточніть у свого хмарного провайдера, чи підтримується виконання Java у вашому рівні.
Частина 2 — Інспекція Java-об’єктів
2.1 Кількість Java-об’єктів у SYS
Повне встановлення JVM завантажує десятки тисяч об’єктів Java-класів, ресурсів і даних у SYS. Якщо кількість значно нижча за очікуваний діапазон — встановлення, ймовірно, було перервано або застосовано частково. Використовуйте ці числа як орієнтири, а не жорсткі пороги — рівень патчів дещо впливає на кількість.
SELECT owner, object_type, status, COUNT(*)
FROM dba_objects
WHERE object_type LIKE '%JAVA%'
GROUP BY owner, object_type, status
ORDER BY owner, object_type, status;
Орієнтовні пороги для SYS на 11.2.0.3:
| OBJECT_TYPE | Мінімум очікуваний | Типове здорове значення |
|---|---|---|
| JAVA CLASS | ~19 000 | ~20 500 |
| JAVA DATA | ~250 | ~317 |
| JAVA RESOURCE | ~700 | ~761 |
Приклад здорового результату:
| OWNER | OBJECT_TYPE | STATUS | COUNT(*) |
|---|---|---|---|
| EXFSYS | JAVA CLASS | VALID | 47 |
| EXFSYS | JAVA RESOURCE | VALID | 1 |
| SYS | JAVA CLASS | VALID | 20 500 |
| SYS | JAVA DATA | VALID | 317 |
| SYS | JAVA RESOURCE | VALID | 761 |
| SYS | JAVA SOURCE | VALID | 2 |
Будь-які рядки INVALID у секції SYS або кількість об’єктів значно нижче мінімумів — сигнал для запуску повного запиту невалідних об’єктів у розділі 2.3.
Примітка Oracle 19c / 21c: Очікуйте кількість
JAVA CLASSу SYS у діапазоні 30 000–40 000 через розширені базові бібліотеки. Значення нижче ~25 000 на стандартній інсталяції 19c потребує розслідування.
2.2 Валідність пакету DBMS_JAVA
DBMS_JAVA — основний PL/SQL-міст до JVM. Якщо тіло пакету невалідне — будь-який код, що його викликає, завершиться помилкою, навіть якщо всі базові Java-об’єкти справні. Ця перевірка також виловлює зламані публічні синоніми, що спричиняють помилки іменного розв’язання на стороні користувача.
SELECT owner, object_name, object_type, status
FROM dba_objects
WHERE object_name LIKE 'DBMS_JAVA%'
OR object_name LIKE '%INITJVMAUX%'
ORDER BY owner, object_name, object_type;
Очікуваний вивід — кожен рядок має бути VALID:
| OWNER | OBJECT_NAME | OBJECT_TYPE | STATUS |
|---|---|---|---|
| PUBLIC | DBMS_JAVA | SYNONYM | VALID |
| PUBLIC | DBMS_JAVA_DUMP | SYNONYM | VALID |
| PUBLIC | DBMS_JAVA_TEST | SYNONYM | VALID |
| SYS | DBMS_JAVA | PACKAGE | VALID |
| SYS | DBMS_JAVA | PACKAGE BODY | VALID |
| SYS | DBMS_JAVA_DEFINERS | PACKAGE | VALID |
| SYS | DBMS_JAVA_DEFINERS | PACKAGE BODY | VALID |
| SYS | DBMS_JAVA_DUMP | PACKAGE | VALID |
| SYS | DBMS_JAVA_DUMP | PACKAGE BODY | VALID |
| SYS | DBMS_JAVA_TEST | PACKAGE | VALID |
| SYS | DBMS_JAVA_TEST | PACKAGE BODY | VALID |
INVALID PACKAGE BODY у SYS при валідній специфікації PACKAGE зазвичай означає часткове застосування встановлення. Повністю відсутній рядок PACKAGE BODY вказує на те, що скрипт встановлення не завершився.
2.3 Перерахування всіх INVALID Java-об’єктів
Цей запит робить join із sys.javasnm$, щоб розкрити короткі внутрішні імена об’єктів, які Oracle використовує всередині, до їхніх повних імен класів. Без цього join’у ви отримаєте беззмістовні скорочені ідентифікатори, які нічого не кажуть про те, який клас зламано.
SELECT owner, NVL(longdbcs, object_name) long_name, object_type, status
FROM dba_objects, sys.javasnm$
WHERE object_type LIKE '%JAVA%'
AND status <> 'VALID'
AND short (+) = object_name
ORDER BY owner, long_name, object_type;
Очікуваний результат на здоровій системі:
no rows selected
Якщо рядки з’являються в SYS — повне перевстановлення JVM зазвичай є правильним виправленням; спроба вручну рекомпілювати окремі Java-класи SYS, як правило, перетворюється на нескінченне копання. Для невалідних об’єктів у схемах користувачів цільова рекомпіляція через DBMS_JAVA.compile_class зазвичай достатня.
2.4 Пам’ять Java Pool
Валідні об’єкти та коректне встановлення нічого не варті, якщо Java Pool вичерпано або неправильно налаштовано. Завантаження класів відбувається в рантаймі з цього пулу, і занадто малий пул породжує криптичні помилки — ORA-29553, збої ініціалізації JVM або мовчазну поведінку “клас не знайдено” — замість очевидної помилки пам’яті.
SELECT *
FROM v$sgastat
WHERE pool = 'java pool' OR name = 'free memory'
ORDER BY pool, name;
Приклад здорового результату:
| POOL | NAME | BYTES |
|---|---|---|
| java pool | JOXLE | 15 821 568 |
| java pool | free memory | 16 906 304 |
| java pool | joxs heap | 826 560 |
| large pool | free memory | 8 585 216 |
| shared pool | free memory | 107 256 528 |
Як інтерпретувати результат:
| Умова | Оцінка |
|---|---|
Рядки java pool повністю відсутні | Пул не налаштовано — перевірте параметр JAVA_POOL_SIZE |
free memory > 5 МБ | Прийнятно для легкого використання JVM |
free memory < 1 МБ | Високий ризик ORA-29553 та збоїв завантаження класів під навантаженням |
| Загальний java pool < 32 МБ | Збільшіть мінімум до 32–64 МБ для будь-якого активного JVM-навантаження |
Для інспекції та зміни розміру пулу:
-- Перевірити поточний налаштований розмір
SELECT name, value
FROM v$parameter
WHERE name = 'java_pool_size';
-- Змінити розмір онлайн (лише коли SGA_TARGET не керує пам'яттю автоматично)
ALTER SYSTEM SET java_pool_size = 64M SCOPE=BOTH;
Примітка Oracle 19c / 21c: При Automatic Memory Management (
MEMORY_TARGET) або Automatic SGA Management (SGA_TARGET) параметрjava_pool_sizeпоказуватиме0— це очікувано, не проблема. Пул розмірується динамічно менеджером пам’яті. Перевіряйте фактичний розподіл в рантаймі черезv$sgastatпід репрезентативним навантаженням, а не через значення параметра.
2.5 Java-ролі
Встановлення JVM створює набір ролей бази даних, що контролюють доступ до привілеїв виконання Java. Якщо основні ролі відсутні — Java-код на рівні користувача завершуватиметься помилками привілеїв, навіть якщо JVM рівня SYS функціонує коректно.
SELECT role
FROM dba_roles
WHERE role LIKE '%JAVA%'
ORDER BY role;
Очікуваний вивід:
| ROLE | Примітки |
|---|---|
| JAVADEBUGPRIV | Необхідна для налагодження Java |
| JAVAIDPRIV | Привілей ідентичності для Java |
| JAVASYSPRIV | Системний привілей Java |
| JAVAUSERPRIV | Стандартний користувацький привілей Java |
| JAVA_ADMIN | Адміністративний привілей Java |
| JAVA_DEPLOY | Застаріло починаючи з Oracle Database 18c — відсутність на 18c+ є очікуваною |
Якщо будь-яка з п’яти основних ролей (JAVAUSERPRIV, JAVASYSPRIV, JAVAIDPRIV, JAVADEBUGPRIV, JAVA_ADMIN) відсутня — встановлення JVM неповне, і необхідно повторно запустити скрипти створення ролей із набору встановлення JVM.
Oracle 19c / 21c — примітка Multitenant: Ролі є локальними для PDB. Виконуйте цю перевірку, підключившись до цільового PDB. Запит із
CDB$ROOTпокаже неповний або порожній набір незалежно від стану PDB.
Підсумок
Якщо ви пройшли всі вісім перевірок і все зелене — JVM встановлена, валідна та має ресурси для роботи. Якщо знайшли проблеми — найпоширеніші шляхи виправлення:
- JAVAVM / CATJAVA відсутні в DBA_REGISTRY — необхідне повне встановлення JVM через
$ORACLE_HOME/javavm/install/initjvm.sqlта суміжні скрипти. - Статус INVALID у DBA_REGISTRY або DBMS_JAVA — повторно запустіть скрипти встановлення JVM; розгляньте повне перевстановлення, якщо цільова рекомпіляція не допомагає.
- Мала вільна пам’ять Java Pool — збільшіть
java_pool_sizeабо дайте менеджеру пам’яті більше простору в режимі SGA/AMM. - Відсутні ролі — повторно запустіть частину скриптів встановлення JVM, що створює ролі, з
$ORACLE_HOME/javavm/install/.
Ці вісім запитів виконуються менш ніж за дві хвилини та дають повну картину стану JVM. Варто додати до будь-якого DBA runbook як pre-flight перевірку перед розгортанням чого завгодно, що залежить від Oracle JVM.