Oracle посмотреть инвалидные объекты

Обновлено: 04.07.2024

И так, мы настроили аудит. Информация о действиях пользователей в базе данных начала собираться. Мы знаем, где ёё можно посмотреть. Но всё это будет напрасно, если мы не сможем разобраться в этом большом количестве разнообразных данных. Поэтому попытаемся выработать основные этапы анализа аудита. Начнём с подключений пользователей к базе данных. Так как в больших системах количество соединений может составлять тысячи за день, нас в первую очередь будут интересовать подключения пользователей обладающих расширенными привилегиями. К таким пользователям относятся системные учётные записи, отдельная учётная запись администратора базы данных, если таковая имеется. Так же к ним можно отнести и пользователей, которые могут изменить критически важные данные, например известные нам пользователи AH и BE. Такие подключения следует, прежде всего, отслеживать по месту откуда делается попытка соединения. Если соединение осуществлялось с компьютера имя, которого отличается от привычного имени, то, скорее всего, произошёл взлом или утечка регистрационных данных учётной записи. Во всяком случае, на эти записи следует обратить внимание. Выполним, к примеру, следующий запрос:

В результате мы видим, что было произведено успешное подключение под учётной системной записью BE с компьютера W005, хотя пользователь раньше всегда соединялся только с терминалов W003 или W004. Возможно, это говорит о том, что учётная запись BE была взломана. Если же проверка успешных подключений привилегированных пользователей не показала ничего подозрительного, то нам стоит проанализировать соединения, которые по тем или иным причинам завершились с ошибкой. Делается это с помощью следующего запроса:

В данном случае видно, что попытка подключения под пользователями AH и BE окончилась неудачей. Но если одиночное неудачное соединение пользователя AH можно списать на ошибку ввода пароля. То аудит подключений пользователя BE может говорить о попытке взлома учётной записи. Кроме вопросов касающихся безопасности аудит подключений можно использовать и в целях определения сеансов сильно загружающих экземпляра базы данных. Всё дело в том, что при удачном завершении подключения в аудит происходит запись некоторой статистики сеанса. Поэтому обращаясь к столбцам SESSION_CPU, LOGOFF_LREAD, LOGOFF_PREAD, LOGOFF_DLOCK можно находить сеансы которые используют, слишком большое количество процессорного времени, осуществляют много физических и логических чтений или имеют взаимоблокировки. Выполним, к примеру, следующий запрос:

Здесь мы видим, что сеанс пользователя VP длился девять часов, причём время, в течение которого использовался процессор, составило более восьми часов. Это, скорее всего, говорит о ненормальной работе приложения, в котором работал пользователь. Определить, какое это приложение можно только по числовому идентификатору сеанса SESSIONID. Ему соответствует поле AUDSID представления V$SESSION. К сожалению когда мы будем просматривать аудит мы уже не найдем в этом представлении информацию о сеансе. Поэтому нам придётся дополнительно вести историю сеансов с помощью системных триггеров. Разобравшись с подключениями и не выявив попыток взлома или несанкционированного использования учётных записей, можно попытаться разобраться в остальных действиях пользователей. И начать это лучше с проверки выполнения системных команд. К ним в первую очередь стоит отнести команду ALTER SYSTEM динамически меняющую экземпляр базы данных, команды выдачи, отбора привилегий GRANT и REVOKE, операторы изменения настройки аудита AUDIT и NOAUDIT. Выбрать все записи, образующиеся при выполнении этих команд можно с помощью следующего запроса:

Попробуем провести анализ полученного результата. Первая запись говорит нам о том, что администратором была включена опция аудита PROCEDURE. На это указывает действие SYSTEM AUDIT в столбце ACTION_NAME и название опции в столбце AUDIT_OPTION. Далее следует семь записей, отображающие выдачу администратором объектных привилегий роли HR_PROG, о чём свидетельствует тип действия SYSTEM AUDIT. Столбцы OWNER и OBJ_NAME при этом идентифицируют объект, на который выдаются права, а столбец GRANTEE получателя этих привилегий. Расшифровку выдаваемых прав, можно осуществить с помощью значения столбца OBJ_PRIVILEGE. Здесь каждое положение символа соответствует определённой объектной привилегии. Если символ имеет значение Y, то значит, привилегия на объект была предоставлена. В нашем случае роли были предоставлены все объектные привилегии, которые имеются для данного типа объекта. В следующей записи аудита присутствует действие SYSTEM GRANT, означающее, что администратором была произведена выдача системной привилегии роли HR_PROG. Посмотреть какая привилегия при этом выдавалась можно в столбце SYS_PRIVILEGE. В нашем случае там находится значение ALTER SESSION. Далее мы видим группу записей с общим действием GRANT ROLE. Это действие относится к предоставлению роли пользователям или другим ролям, выдаваемая роль при этом отображается в столбце OBJ_NAME. В нашем случае была произведена выдача администратором роли CONNECT пользователям AH, BE, VP и роли HR_PROG пользователю AH. Причём в последнем случае роль была предоставлена пользователю с правом передачи, о чём свидетельствует присутствие символа A в столбце ADMIN_OPTION. Четырнадцатая запись аудита, пожалуй, не нуждается в пояснении. Действие ALTER SYSTEM явно указывает на то, что администратором была выполнена в системе одноименная команда и дополнительной информации мы здесь не увидим. Последние две записи аудита относятся, как было ранее рассмотрено, к предоставлению ролей пользователям. Но выдачу этих ролей осуществляют не привилегированные пользователи. Так мы видим, что пользователь AH предоставил роль HR_PROG пользователю BE, без права передачи, который в свою очередь попытался выдать эту роль пользователю VP, но потерпел неудачу. Ошибка при этом отобразилась в столбце RETURNCODE. Анализ аудита, осуществляемый с использованием представления DBA_AUDIT_STATEMENT, имеет большое значение, так как именно на этом этапе есть возможность определить попытки повышения привилегий учётной записи и вероятность замести следы несанкционированных действий путём изменения настроек аудита. Поэтому надо внимательно анализировать все без исключения записи на предмет, кто выполняет, какие действия, в какое время и главное откуда. Если же нам на этом этапе не удалось обнаружить никаких подозрительных действий, то мы можем спокойно переходить к следующему виду анализа аудита – анализу действий над объектами. Под объектами здесь подразумевается не только объекты схемы, но и системные объекты: пользователи, профили, роли, табличные пространства и т.д. Посмотреть аудит этих объектов можно с помощью следующего запроса:

Проанализируем полученный результат. В первых четырёх записях мы видим, что администратор создал роль HR_PROG и учетные записи пользователей AH, BE, VP. Их имена отображены в столбце OBJ_NAME, а действия совпадают с названиями применяемых SQL команд. После этого администратор включил триггер безопасности HR.SECURE_EMPLOYEES. На это указывает действие ENABLE TRIGGER и имя объекта в полях OWNER и OBJ_NAME. Далее пользователь AH попытался обратиться к таблице HR.EMPLOYEES. Но вместо какого либо понятного нам действия, в столбце ACTION_NAME мы видим лишь значение SESSION REC. На самом деле это значение означает, что запись факта всех действий для этого объекта в течение сеанса будет отображаться в этой записи, так как настройке опций был применён режим по умолчанию BY SESSION. Определить какие команды применялись к данному объекту можно по положению специального символа в столбце SES_ACTIONS. В нашем случае это положение соответствует команде UPDATE, а сам символ имеет значение F, что означает неудачное выполнение команды. После этого пользователь AH попытался выключить триггер безопасности HR.EMPLOYEES. Но потерпел неудачу. Это видно по значению поля RETURNCODE. Далее этим же пользователем были выполнены две команды SELECT и UPDATE применительно к объекту HR.JOBS. Это было определено из положения символов S в значении столбца SES_ACTIONS. Кстати данный символ свидетельствует об успешном выполнении команды. Продолжая анализ, мы видим, что в следующей записи присутствует действие CREATE TRIGGER, которое говорит нам о том, что администратор изменил триггер HR.SECURE_EMPLOYEES. Поле NEW_NAME здесь указывает на основной объект. В нашем случае это таблица HR.EMPLOYEES, к которой относится данный триггер. После того как триггер пересоздан, пользователь AH получил возможность удачно выполнить команду UPDATE для таблицы HR.EMPLOYEES, на это указывает положение символа S в значении столбца SES_ACTIONS. И наконец, в последней записи аудита видно как пользователь BE осуществил доступ к таблице HR.JOBS. Но в значении столбца SES_ACTIONS мы видим только символ B. Позиция его соответствует выполненной команде SELECT, но результат выполнения команды неизвестен. На самом деле присутствие этого символа означает, что произошло удачное и одновременно неудачное выполнение команды в течение сеанса.

Сопровождаем журнал

По мере роста количества записей в журнале аудита, возникает необходимость в проведении определённых действий связанных с сопровождением этого журнала. Если этого не делать, то мы можем столкнуться с рядом проблем, от сложности в анализе аудита, до полной остановки системы в случае переполнения табличного пространства SYSTEM. Что же это за действия? Перечислим их - это удаление лишних и архивирование нужных записей, сброс маркера максимального уровня заполнения таблицы SYS.AUD$, а также проведение усечения данной таблицы. Теперь рассмотрим их более подробно. В первую очередь необходимо время от времени удалять лишние записи из журнала аудита. Стратегия удаления может быть разнообразной. Допустим можно выборочно удалять отдельные записи аудита непосредственно в процессе анализа. Например, выполним следующий запрос и проанализируем полученный результат:

Подозрительных действий не обнаружено, и мы можем удалить, к примеру, первую запись. Удаление надо производить непосредственно из таблицы SYS.AUD$, используя при этом в качестве ключа значения столбцов SESSIONID и ENTRYID:

Но такой способ годится только при небольшом количестве записей. Гораздо более удобно групповое удаление. Для этого можно использовать запросы, к представлениям журнала аудита применяемые при анализе. В качестве примера удалим с помощью следующей команды все санкционированные подключения привилегированных пользователей:

Приведённые выше способы удаления подразумевают хранение оставшейся информации, которая нас интересует непосредственно в самом журнале аудита. Это может привести к тому, что, по мере роста журнала аудита, эту информацию также придётся удалять. Чтобы этого не делать, можно организовать архивирование нужных нам записей аудита. Для этого можно создать архивные таблицы по структуре соответствующие представлениям журнала аудита в схеме отличной от SYS. Попробуем продемонстрировать это на примере. Создадим архивную таблицу ARCH_AUDIT_SESSION в схеме SYSTEM. По структуре она будет соответствовать представлению DBA_AUDIT_SESSION, но располагаться в другом табличном пространстве.

Теперь перенесём нужные нам записи из представления DBA_AUDIT_SESSION:

После того как все архивные таблицы созданы и необходимые нам записи аудита будут в них перенесены, можно спокойно очистить журнал аудита одной командой DELETE. Правда само удаление записей не решит проблему роста журнала. Для её устранения необходим сброс маркера максимального уровня заполнения таблицы SYS.AUD$. И сделать это можно с помощью нескольких способов. Первый состоит в том, чтобы очистить таблицу SYS.AUD$ с помощью команды TRUNCATE TABLE. Это приведёт к сбросу маркера. Если в таблице должны оставаться какие-либо записи, то необходимо вначале создать копию таблицы с помощью оператора CREATE TABLE AS SELECT. Затем выполнить команду TRUNCATE TABLE и вставить записи из копии таблицы обратно. Если при создании копии таблицы возникают проблемы, например не хватает места в табличном пространстве, то можно выгрузить данные в файл экспорта. Затем провести импорт данных обратно в таблицу. В качестве недостатка этого способа следует отметить, что неиспользуемые блоки, возникшие в результате удаления записей из журнала аудита, не освобождаются. И хотя таблица SYS.AUD$ не будет больше расти по объёму до определённого уровня, она будет иметь такой же размер, как и до её очистки. Чтобы избежать этого, можно использовать ещё один способ сброса маркера. Он представляет собой перемещение таблицы SYS.AUD$ в другое табличное пространство с помощью команды ALTER TABLE MOVE TABLESPACE и последующий возврат таблицы в табличное пространство SYSTEM:

При этом происходит не только сброс маркера максимального уровня, но и освобождение неиспользуемых блоков сегмента, то есть усечение таблицы. Единственно, что надо не забыть в этом случае, это перекомпилировать объекты, зависимые от таблицы SYS.AUD$, так как данная команда переводит их в статус инвалидных.

Используем расширенный режим

Проводя анализ аудита мы видели, что в журнале сохраняется довольно много информации, достаточной для того чтобы идентифицировать то действие которое выполнил пользователь. Но если мы захотим более подробно разобраться в том какая, же команда была выполнена, то здесь нас ждёт неудача. Поясним это на примере:

Рассматривая результат запроса, мы видим, что администратор выполнил какое-то изменение экземпляра базы данных с помощью команды ALTER SYSTEM. Но нам не видно, какие конкретно изменения он сделал. Это могло быть и изменение инициализационного параметра, и уничтожение сеанса пользователя. Если бы мы знали, какую команду выполнил пользователь в данный момент времени, мы могли бы точнее определить само действие и опасность его для системы. К счастью в Oracle начиная с девятой версии, предусмотрен расширенный режим аудита. В данном режиме в качестве дополнения в журнал аудита записываются исполняемые SQL команды, или значения переменных привязки, если таковые имеются. Включается данный режим изменением параметра инициализации AUDIT_TRAIL. Для этого надо присвоить ему значение DB,EXTENDED. Попробуем включить данный режим:

Перезагрузим экземпляр и проверим правильность установки значения параметра:

Расширенный режим установился. Заполним журнала аудита новой информацией. И если теперь мы повторим запрос к представлению журнала, то увидим, что в столбце SQL_TEXT появился текст выполненной команды:

В результате становиться понятно, какие действия совершил пользователь SYSTEM с экземпляром базы данных. Правда иногда, когда в SQL операторе используются связанные переменные, текст команды не даёт полной информации о совершаемом действии. В этом случае нам надо знать значения этих переменных. К примеру, в результате выполнения следующего запроса мы видим две записи с совершенно одинаковыми DML командами. Единственное что их отличает это значения связанных переменных, отображённых в столбце SQL_BIND.

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

Применяем другие виды журналов

Журнал аудита, который мы рассматривали выше, представляет собой таблицу AUD$ в схеме пользователя SYS. Но это не единственно место для хранения записей аудита. Кроме таблицы, аудит можно помещаться в системный журнал операционной системы или в XML файлы. Для включения данных режимов требуется изменить значение параметра инициализации AUDIT_TRAIL. Попробуем включить один из таких режимов. Для этого выполним следующую команду:

Перезагрузим экземпляр и вновь сгенерируем аудит. Если после этого мы сделаем запрос таблице SYS.AUD$, то увидим, что она пуста:

Но зато в системном журнале операционной системы появились записи. В нашем случае это будет выглядеть примерно так:

Информацию протоколирования можно записывать не только в системный журнал, но и в отдельные XML файлы. Их расположение определяется значением параметра AUDIT_FILE_DEST и по умолчанию может указывать на директории ORACLE_BASE/admin/DB_UNIQUE_NAME /adump или ORACLE_HOME/rdbms/audit. Попробуем включить данный режим, выполнив следующую команду:

Перезагрузим экземпляр и проверим значения параметров инициализации:

Далее проведём генерацию аудита. После чего мы обнаружим в директории C:\ORACLEXE\APP\ORACLE\ADMIN\XE\ADUMP несколько файлов. Это и будут файлы журнала аудита. В каждом отдельном файле с помощью XML формата будут отражены действия, выполняемые пользователем в течение одного сеанса. Имя файла при этом формируется из префикса ora_ и идентификатора серверного процесса. Приведем для примера содержимое одного такого файла:

Здесь мы могли бы столкнуться с большими трудностями при анализе аудита, так как довольно сложно обрабатывать такие файлы. Но Oracle облегчает задачу, предоставив нам системное представление V$XML_AUDIT_TRAIL. Сделав запрос к нему, мы получим данные аудита в уже привычной для нас табличной форме, где большинство столбцов соответствуют столбцам уже рассмотренного нами представления DBA_AUDIT_TRAIL.

Хочется отметить одну важную особенность, характерную для обоих режимов аудита. Так как Oracle не может прочитать такие журналы для поиска информации об уже выполнявшейся аналогичной команде в течение сеанса, то запись аудита будет генерироваться при каждом исполнении SQL оператора. Поэтому настройка опций с фокусировкой на сеанс, для данных режимов работы аудита не будет иметь смысла.

Для определения инвалидных объектов можно использовать представление DBA_OBJECTS, как в этом запросе:

COLUMN object_name FORMAT A30
SELECT owner,
object_type,
object_name,
status
FROM dba_objects
WHERE status = 'INVALID'
ORDER BY owner, object_type, object_name;


Полученную информацию можно использовать для выбора метода рекомпиляции.

Вручную

При небольшом количестве инвалидных объектов ручной перекомпиляции может быть достаточно. Например:
ALTER PROCEDURE AGRP.AGR_DEFRAG_PROC COMPILE;
ALTER VIEW AGRP.ABUVIPROP COMPILE;
ALTER PACKAGE APEX_030200.WWV_FLOW_FND_GLOBAL COMPILE;
ALTER SYNONYM BRAFAKT.ACRCLIENT COMPILE;

Немного подшаманим:
SELECT 'ALTER '|| case object_type when 'PACKAGE BODY' then 'PACKAGE' else object_type end||' '|| owner||'.'||object_name||' COMPILE;' "Recompile"
FROM dba_objects
WHERE status = 'INVALID'
ORDER BY owner, object_type, object_name;



С чем пришлось столкнуться

Решение:
Подключиться к БД как SYSDBA пользователь:
SQL> exec dbms_java_dev.enable;

После того как всё скомпилируется/перекомпилируется и новые процедуры разработки не нужны, подключиться к БД как SYSDBA пользователь:
SQL> exec dbms_java_dev.disable;

Выглядело всё вот так:

SQL> exec dbms_java_dev.enable;
_
PL/SQL procedure successfully completed.
_
SQL> ALTER PACKAGE MDSYS.SDO_NET COMPILE;
_
Package altered.
_
SQL> ALTER PACKAGE SYS.SQLJUTL2 COMPILE;
_
Package altered.
_
SQL> exec dbms_java_dev.disable;
_
PL/SQL procedure successfully completed.

Перекомпиляция инвалидных объектов схемы: 1 комментарий

Недействительные объекты PL/SQL и неприменимые индексы оказывают влияние на производительность. Недействительный объект PL/SQL должен быть перекомпилирован прежде, чем он сможет использоваться. Это потребует времени на перекомпиляцию, которое надо будет добавить к первому действию, которое пытается получить доступ к пакету PL/SQL, процедуре или функции. Если PL/SQL не удалось перекомпилировать успешно, операция завершится с ошибкой. Неприменимые индексы игнорируются оптимизатором. Если надлежащая производительность SQL-оператора зависит от индекса, который был отмечен как неприменимый, производительность не улучшится, пока индекс не будет пересоздан.

Недействительные объекты PL/SQL: Текущий статус объектов PL/SQL может быть просмотрен, запрашивая словарь данных. Можно найти недействительные объекты PL/SQL следующим образом:

SELECT object_name, object_type FROM DBA_OBJECTS
WHERE status = 'INVALID';

По умолчанию метрика количества недействительных объектов владельца проверяется каждые 24 часа. Если число объектов для отдельного владельца превышает два, возникает предупреждение.

Ничего не делать. Большинство PL/SQL объектов автоматически перекомпилируются если нужно, когда их вызывают. Пользователи испытывают небольшую задержку, пока происходит перекомпиляция. (В большинстве случаев эта задержка даже не заметна.)

Вручную перекомпилировать недействительный объект.

Недействительные PL/SQL объекты могут быть вручную перекомпилированы в Enterprise Manager или посредством команд SQL:

ALTER PROCEDURE HR.add_job_history COMPILE;

Ручная перекомпиляция пакетов PL/SQL состоит из двух шагов:

ALTER PACKAGE HR.maintainemp COMPILE;
ALTER PACKAGE HR.maintainemp COMPILE BODY;

Неприменимые индексы: Неприменимые индексы могут быть найдены, запрашивая представление словаря данных DBA_INDEXES:

SELECT index_name, table_name FROM DBA_INDEXES
WHERE status = 'UNUSABLE';

Для разделенных индексов состояние хранится в представлении DBA_IND_PARTITIONS.

Неприменимые индексы делаются действительными посредством их пересоздания, чтобы повторно вычислить указатели. Восстановление неприменимого индекса пересоздает индекс в новом расположении и затем удаляет неприменимый индекс. Это может быть сделано в Enterprise Manager или посредством команд SQL:

ALTER INDEX HR.emp_empid_pk REBUILD;
ALTER INDEX HR.emp_empid_pk REBUILD ONLINE;
ALTER INDEX HR.email REBUILD TABLESPACE USERS;

Если предложение TABLESPACE не указывается, индекс пересоздается в том же самом табличном пространстве , где он существовал прежде. Предложение REBUILD ONLINE позволяет пользователям продолжать обновлять таблицу индекса, в то время как происходит пересоздание индекса. (Без ключевого слова ONLINE пользователи должны ожидать, пока не закончится пересоздание, прежде, чем выполнить DML на таблице, индекс которой пересоздается. Если индекс неприменим, он не применяется во время пересоздания, даже если используется ключевое слово ONLINE.)

Enterprise Manager использует действие Reorganize, чтобы восстановить неприменимый (UNUSABLE) индекс.

Отметьте: Пересоздание индекса требует, чтобы было доступно свободное пространство для пересоздания. Проверьте, что есть достаточно места прежде, чем делать попытку пересоздания. Enterprise Manager автоматически проверяет требования пространства.

Читайте также: