Коли Oracle JVM ламається — вона рідко повідомляє про це чітко. Ви отримуєте каскадні помилки невалідних пакетів, PL/SQL-обгортки, що раптово відмовляються компілюватися, або Java stored procedures, що повертають криптичні помилки ORA-29549 і ORA-29553. Цей гайд охоплює повну послідовність відновлення — від перевірки передумов через перевстановлення самої JVM до відновлення всіх залежних об’єктів та валідації результату.
Написано для Oracle Database 11.2.0.3. Примітки для 19c / 21c включено там, де процедура відрізняється. Усі кроки виконуються як DBA в SQL*Plus, якщо не зазначено інше.
Перш ніж починати: По можливості зробіть холодний бекап або експорт. Процедура перевстановлення JVM перезапускає базу даних у restricted mode та замінює базові системні об’єкти. Вона незворотна без відновлення з резервної копії.
Огляд послідовності відновлення
Виконуйте фази по порядку. Кожна фаза є передумовою для наступної — не пропускайте вперед, якщо знайшли збої.
| Фаза | Що охоплює | Необхідна якщо |
|---|---|---|
| 1 | Відновлення CATPROC | Статус CATPROC не VALID в DBA_REGISTRY |
| 2 | Перевстановлення JVM | JAVAVM або CATJAVA відсутні або мають статус INVALID |
| 3 | Відновлення грантів DBMS_CRYPTO | Після будь-якого перевстановлення JVM або при збоях Java-криптографії |
| 4 | Відновлення зовнішньої директорії | Після перевстановлення JVM або коли об’єкти директорій відсутні |
| 5 | Відновлення Java schema user | Обліковий запис Java-користувача заблоковано, відсутній або втратив привілеї |
| 6 | Перевстановлення кастомних Java-об’єктів | Java-класи застосунку невалідні або відсутні |
| 7 | Функціональне тестування | Завжди — виконувати після кожного відновлення |
Фаза 1 — Відновлення CATPROC
CATPROC (Oracle Database Packages and Types) є жорсткою залежністю JVM. Якщо він невалідний — скрипти перевстановлення JVM завершаться з помилкою посередині. Виправте спочатку.
Перевірте поточний статус:
SELECT comp_id, comp_name, status
FROM dba_registry
WHERE comp_id = 'CATPROC';
Якщо статус не VALID — виконайте двокроковий виправлення нижче.
Крок 1 — Рекомпіляція невалідних об’єктів
Це швидкий шлях. utlrp.sql паралельно рекомпілює всі невалідні об’єкти в базі даних. Усуває багато проблем із невалідністю CATPROC, спричинених незавершеними патчами або перерваними апгрейдами.
@$ORACLE_HOME/rdbms/admin/utlrp.sql
Після завершення повторно перевірте DBA_REGISTRY. Якщо CATPROC тепер VALID — переходьте до Фази 2. Якщо досі невалідний — переходьте до Кроку 2.
Крок 2 — Перевстановлення каталогу та пакетів
Це відновлює словник даних і всі базові PL/SQL-пакети з нуля. На великих базах даних займає значний час і виводитиме повідомлення про замінювані об’єкти — це очікувано.
@$ORACLE_HOME/rdbms/admin/catalog.sql
@$ORACLE_HOME/rdbms/admin/catproc.sql
@$ORACLE_HOME/rdbms/admin/utlrp.sql
Примітка Oracle 19c / 21c: Скрипти та процедура ідентичні. У CDB-середовищі підключіться до
CDB$ROOTякSYSDBAперед запуском — вони працюють на рівні контейнера та застосовуються до PDB відповідним чином.
Фаза 2 — Перевстановлення Oracle JVM
Це ядро відновлення. Процедура монтує базу даних, вимикає кілька фонових процесів, що заважали б заміні JVM, відтворює Java system layer, а потім запускає повні скрипти ініціалізації JVM. База даних має бути перезапущена в рамках цього процесу.
Ця процедура перезапускає базу даних. Погодьте вікно обслуговування. Усі активні сесії будуть завершені.
Крок 1 — Монтування бази даних
Спочатку завершіть роботу бази даних, потім переведіть її в стан mount — не open. Заміна JVM має відбутися до відновлення нормальної роботи.
SHUTDOWN IMMEDIATE;
STARTUP MOUNT;
Крок 2 — Підготовка init-параметрів
Перед відкриттям бази даних вимкніть три налаштування, що інакше заважали б перевстановленню JVM: JIT-компілятор (який намагатиметься компілювати Java-класи під час завантаження), системні тригери (що спрацьовують на DDL і конфліктуватимуть із відтворенням Java system) та процеси черги завдань (які породжують фонові завдання під час встановлення).
ALTER SYSTEM SET java_jit_enabled = FALSE;
ALTER SYSTEM SET "_system_trig_enabled" = FALSE;
ALTER SYSTEM SET JOB_QUEUE_PROCESSES = 0;
Крок 3 — Відкриття в restricted mode
Відкрийте базу даних, але обмежте доступ лише для DBA-сесій. Це запобігає будь-яким підключенням застосунків до бази даних під час відновлення JVM.
ALTER DATABASE OPEN;
ALTER SYSTEM ENABLE RESTRICTED SESSION;
Крок 4 — Відтворення Java system layer
Цей оператор видаляє та відтворює всю Java system в Oracle. Це еквівалент повного стирання та перевстановлення JVM-рушія. Виконання займає кілька хвилин і не виводить жодного повідомлення — це нормально.
CREATE OR REPLACE JAVA SYSTEM;
/
Після завершення перевірте таблицю Java-об’єктів, щоб підтвердити наявність system layer:
SELECT obj#, name
FROM obj$
WHERE type# IN (28, 29, 30)
OR namespace = 32;
Ви маєте побачити тисячі рядків. Порожній результат або дуже мала кількість рядків означає, що CREATE OR REPLACE JAVA SYSTEM не завершився успішно — перевірте alert log перед тим як продовжувати.
Крок 5 — Запуск скриптів ініціалізації JVM
Ці скрипти встановлюють усі компоненти JVM у правильному порядку залежностей. Запускайте послідовно і не переривайте. Кожен скрипт може виконуватися кілька хвилин.
-- Базова JVM
@$ORACLE_HOME/javavm/install/initjvm.sql
-- Oracle XML із підтримкою Java
@$ORACLE_HOME/xdk/admin/initxml.sql
@$ORACLE_HOME/xdk/admin/xmlja.sql
-- Java catalog packages
@$ORACLE_HOME/rdbms/admin/catjava.sql
-- Expression Filter (лише Oracle 11g — дивіться примітку нижче)
@$ORACLE_HOME/rdbms/admin/catexf.sql
Примітка Oracle 12c / 19c / 21c:
catexf.sql(Expression Filter) було визнано застарілим у 12c, і компонент не існує в 19c/21c. Пропускайте цей скрипт на будь-якій версії від 12c і вище — його запуск призведе до помилок.
Крок 6 — Рекомпіляція всіх невалідних об’єктів
@$ORACLE_HOME/rdbms/admin/utlrp.sql
Крок 7 — Скидання init-параметрів та перезапуск
Відновіть три параметри, що були вимкнені перед встановленням, потім виконайте чисте завершення роботи та нормальний запуск.
ALTER SYSTEM SET java_jit_enabled = TRUE;
ALTER SYSTEM SET "_system_trig_enabled" = TRUE;
ALTER SYSTEM SET JOB_QUEUE_PROCESSES = 10;
SHUTDOWN IMMEDIATE;
Запустіть базу даних у нормальному режимі (поза SQL*Plus якщо використовується запуск через ОС, або через SQL*Plus):
STARTUP;
Крок 8 — Перевірка відновлення JVM
SELECT comp_id, comp_name, status
FROM dba_registry
WHERE comp_id IN ('JAVAVM', 'CATJAVA');
SELECT count(*), object_type, status
FROM all_objects
WHERE object_type LIKE '%JAVA%'
GROUP BY object_type, status
ORDER BY object_type;
Обидва — JAVAVM і CATJAVA — мають бути VALID, а кількість об’єктів має відповідати референсним значенням із гайду з діагностики Oracle JVM (SYS: ~20 500 JAVA CLASS на 11.2.0.3).
Oracle 19c / 21c — примітка Multitenant: У CDB-середовищі перевстановлення JVM для PDB вимагає підключення безпосередньо до цільового PDB як
SYSDBAта запускуinitjvm.sqlіcatjava.sqlу контексті цього PDB. КомандаCREATE OR REPLACE JAVA SYSTEMтакож має виконуватися всередині PDB. Зміна_system_trig_enabledє операцією рівня CDB — встановлюйте її зCDB$ROOTперед відкриттям PDB.
Фаза 3 — Відновлення грантів DBMS_CRYPTO
Перевстановлення JVM не завжди зберігає всі гранти привілеїв на системних пакетах. DBMS_CRYPTO є типовою жертвою — будь-який код застосунку, що використовує Java-криптографію або викликає DBMS_CRYPTO напряму зі схем, відмінних від SYS, завершиться помилкою, якщо публічний грант на виконання відсутній.
Перевірте наявність гранту:
SELECT owner, table_name, grantee, privilege
FROM dba_tab_privs
WHERE owner = 'SYS'
AND table_name = 'DBMS_CRYPTO'
AND grantee = 'PUBLIC'
AND privilege = 'EXECUTE';
Якщо рядків не повернуто — відновіть грант:
GRANT EXECUTE ON SYS.DBMS_CRYPTO TO PUBLIC;
Примітка безпеки: Надання гранту на виконання
DBMS_CRYPTOдляPUBLICдоречне в середовищах, де всі користувачі БД є довіреними обліковими записами застосунків. У мультитенантних або спільних середовищах розгляньте надання лише конкретним ролям або користувачам замість PUBLIC.
Фаза 4 — Відновлення зовнішньої директорії
Об’єкти директорій Oracle — це покажчики рівня бази даних на шляхи файлової системи. Вони використовуються для зовнішніх таблиць, виводу лог-файлів та Java I/O операцій. Після перевстановлення JVM або відновлення бази даних ці об’єкти може знадобитися відтворити.
Крок 1 — Перевірка наявності шляху файлової системи
ls -la /opt/oracle/admin/<db_name>/external_tables/
# Створити якщо відсутній:
mkdir -p /opt/oracle/admin/<db_name>/external_tables/
chown oracle:oinstall /opt/oracle/admin/<db_name>/external_tables/
Крок 2 — Відтворення об’єкта директорії Oracle
-- Перевірити чи вже існує
SELECT directory_name, directory_path
FROM all_directories
WHERE owner = 'SYS';
-- Створити або замінити якщо відсутній/некоректний
CREATE OR REPLACE DIRECTORY LOG_DIR
AS '/opt/oracle/admin/<db_name>/external_tables';
-- Надати доступ відповідному користувачу або ролі
GRANT READ, WRITE ON DIRECTORY LOG_DIR TO PUBLIC;
Примітка: Замініть
<db_name>на фактичне ім’я вашої бази даних. Скоригуйте шлях і назву директорії відповідно до вашого середовища. Перевірте, які схеми фактично потребують доступу, перед тим як надавати грантPUBLIC.
Фаза 5 — Відновлення Java schema user
Якщо ваш застосунок завантажує Java у виділену схему користувача (стандартний підхід для відокремлення Java застосунку від SYS), обліковий запис та привілеї цього користувача потрібно перевірити після будь-якого відновлення JVM. Заблокований обліковий запис або відсутній грант ролі призведе до негайного збою всіх Java-викликів із цієї схеми.
Крок 1 — Створення або розблокування користувача
-- Перевірити чи існує користувач і чи відкритий
SELECT username, account_status
FROM dba_users
WHERE username = 'JAVA_OBJS';
-- Створити якщо відсутній
CREATE USER java_objs IDENTIFIED BY <password>
DEFAULT TABLESPACE <tablespace_name>;
ALTER USER java_objs QUOTA UNLIMITED ON <tablespace_name>;
-- Розблокувати якщо заблоковано
ALTER USER java_objs ACCOUNT UNLOCK;
ALTER USER java_objs IDENTIFIED BY <password>;
Крок 2 — Відновлення грантів ролей
-- Перевірити наявні гранти ролей
SELECT granted_role
FROM dba_role_privs
WHERE grantee = 'JAVA_OBJS';
-- Відновити необхідні ролі
GRANT JAVASYSPRIV TO java_objs;
GRANT CONNECT TO java_objs;
Примітка Oracle 18c / 19c / 21c: Роль
JAVA_DEPLOYвизнано застарілою в Oracle Database 18c. Не надавайте її на 18c і пізніших версіях — вона більше не існує. На 11g і раніших версіях вона була необхідна для розгортання Java stored procedures черезloadjava.
Крок 3 — Відновлення системних привілеїв
-- Перевірити наявні системні привілеї
SELECT privilege
FROM dba_sys_privs
WHERE grantee = 'JAVA_OBJS';
-- Відновити необхідні привілеї
GRANT CREATE PROCEDURE TO java_objs;
GRANT CREATE TABLE TO java_objs;
Фаза 6 — Перевстановлення кастомних Java-об’єктів
Після відновлення самої JVM та підготовки schema user необхідно повторно розгорнути всі Java-класи застосунку, що були завантажені в базу даних. Загальна схема: видалити старі об’єкти, завантажити з JAR, скомпілювати джерела, розв’язати класи, відтворити PL/SQL wrapper-функції та повторно надати привілеї на виконання.
Крок 1 — Видалення наявних Java-об’єктів зі схеми
Виконується з ОС від імені Oracle OS-користувача. dropjava видаляє всі Java-класи, джерела та ресурси, що були завантажені з вказаного JAR.
dropjava -v -u java_objs/<password> /path/to/your-application.jar
Крок 2 — Завантаження JAR
loadjava -u java_objs/<password> -resolve /path/to/your-application.jar -grant public
Прапор -resolve змушує Oracle перевіряти всі залежності класів під час завантаження, а не відкладати їх. Помилки завантаження набагато простіше діагностувати на цьому етапі, ніж у рантаймі. Прапор -grant public робить завантажені класи доступними для всіх схем — звузьте область, якщо ваш застосунок не потребує публічного доступу.
Крок 3 — Компіляція джерел та розв’язання класів
Якщо ваш JAR містить Java-файли з вихідним кодом (а не лише скомпільовані класи) — скомпілюйте їх явно. Потім розв’яжіть усі класи, щоб підтвердити задоволеність залежностей.
-- Компіляція Java-джерел (якщо застосовно)
ALTER JAVA SOURCE "java_objs"."com/example/YourClass" COMPILE;
-- Розв'язання Java-класів
ALTER JAVA CLASS "java_objs"."com/example/YourClass" RESOLVE;
Перевірте чистоту завантаження:
SELECT object_name, object_type, status
FROM all_objects
WHERE owner = 'JAVA_OBJS'
AND object_type LIKE '%JAVA%'
ORDER BY object_type, object_name;
Усі рядки мають показувати VALID. Будь-які рядки INVALID вказують на нерозв’язані залежності або помилки компіляції — перевірте USER_ERRORS для деталей.
Крок 4 — Відтворення PL/SQL wrapper-функцій
Java stored procedures викликаються через тонкі PL/SQL wrapper-функції, що відображають SQL-типи на Java-типи. Їх потрібно відтворити, якщо схема була перебудована.
-- Приклад шаблону wrapper
CREATE OR REPLACE FUNCTION java_objs.your_function(input VARCHAR2)
RETURN VARCHAR2
AS LANGUAGE JAVA
NAME 'com.example.YourClass.yourMethod(java.lang.String) return java.lang.String';
/
-- Надати доступ до wrapper-функцій
GRANT EXECUTE ON java_objs.your_function TO PUBLIC;
-- Створити публічний синонім для прозорого доступу між схемами
CREATE PUBLIC SYNONYM your_function FOR java_objs.your_function;
Примітка Oracle 19c / 21c: Утиліти
loadjavaіdropjavaвсе ще існують, але визнані застарілими в 19c і пізніших версіях на користь PL/SQL APIDBMS_JAVA.loadjavaіDBMS_JAVA.dropjava. Обидва підходи працюють у 19c/21c. Для нових розгортань на 19c+ надавайте перевагу PL/SQL API, оскільки OS-утиліти можуть бути видалені в майбутніх релізах.
Фаза 7 — Функціональне тестування
Не закривайте вікно обслуговування, доки не підтвердите наскрізну роботу виконання Java, а не лише те, що об’єкти мають статус VALID у словнику даних.
Тест 1 — Підтвердження валідності компонентів JVM
SELECT comp_id, comp_name, status
FROM dba_registry
WHERE comp_id IN ('JAVAVM', 'CATJAVA', 'CATPROC');
Усі три мають бути VALID.
Тест 2 — Підтвердження кількості Java-об’єктів
SELECT owner, object_type, status, COUNT(*)
FROM all_objects
WHERE object_type LIKE '%JAVA%'
GROUP BY owner, object_type, status
ORDER BY owner, object_type;
SYS має показувати приблизно 20 500 об’єктів JAVA CLASS (11.2.0.3). Усі рядки мають бути VALID — будь-які рядки INVALID у SYS вимагають повторного запуску utlrp.sql або повторного встановлення JVM.
Тест 3 — Виконання Java з SQL
Викличте одну з Java wrapper-функцій вашого застосунку напряму з SQL. Це підтверджує повний шлях виконання: SQL engine → PL/SQL wrapper → розв’язання Java-класу → виконання JVM → повернення значення.
SELECT your_function('test_input') FROM dual;
Чисте повернення значення підтверджує успіх. ORA-00904 (невалідний ідентифікатор) означає відсутність синоніма або wrapper-функції. ORA-29549 або ORA-29553 означає, що клас досі невалідний або Java Pool недостатній — зверніться до гайду з діагностики для дослідження пам’яті.
Тест 4 — Підтвердження доступності DBMS_JAVA
SELECT owner, object_name, object_type, status
FROM dba_objects
WHERE object_name = 'DBMS_JAVA'
ORDER BY owner, object_type;
І SYS.DBMS_JAVA PACKAGE, і SYS.DBMS_JAVA PACKAGE BODY мають бути VALID. Валідна специфікація з невалідним тілом — поширений режим збою після встановлення.
Поширені патерни збоїв та виправлення
| Симптом | Найімовірніша причина | Дія |
|---|---|---|
ORA-29549 — клас змінився | Java-клас перезавантажено, але старий стан сесії закешовано | Від’єднатися та перепідключитися до всіх сесій; перезапустити пул підключень застосунку |
ORA-29553 — клас не знайдено | Клас невалідний або Java Pool вичерпано | Повторити Фазу 6; перевірити вільну пам’ять Java Pool у v$sgastat |
ORA-00904 — невалідний ідентифікатор при виклику wrapper | Публічний синонім відсутній або вказує на неправильну схему | Видалити та відтворити синонім; перевірити наявність GRANT EXECUTE |
utlrp.sql завершується, але об’єкти JAVA CLASS залишаються INVALID | Незадоволена залежність класу — referenced клас відсутній або також невалідний | Повторити Фазу 6 з -resolve; перевірити USER_ERRORS для невалідних об’єктів |
initjvm.sql завершується з ORA-01017 або помилками привілеїв | Запуск не як SYSDBA або restricted session не увімкнено | Перевірити рядок підключення — має містити / as sysdba; перевірити активність RESTRICTED SESSION |
| JVM валідна після відновлення, але знову зламана після наступного перезапуску БД | Init-параметри збережено некоректно або SPFILE не оновлено | Перевірити що java_jit_enabled, JOB_QUEUE_PROCESSES і _system_trig_enabled скинуто з SCOPE=BOTH |
Підсумок
Повна послідовність відновлення — CATPROC, перевстановлення JVM, гранти пакетів, об’єкти директорій, schema user, кастомні Java-об’єкти, функціональне тестування — ретельна, але детермінована. Кожна фаза має чіткий критерій успіху перед переходом до наступної. Якщо ви скриптуєте це для автоматизації — ключові перевірки для gating: статус DBA_REGISTRY після кожної фази та живий виклик Java-функції наприкінці, що виконує повний шлях виконання.
Зберігайте копії ваших команд loadjava, DDL wrapper-функцій та операторів надання привілеїв у системі контролю версій. Відновлення JVM о 2-й ночі значно менш болюче, коли перевстановлення кастомних об’єктів — це один скрипт, а не археологія крізь журнали змін.