суббота, 29 декабря 2012 г.

Архивация ODI логов.

Перевод заметки Gürcan Orhan, не сотрудника Оракл, имеющего звание Oracle ACE Director. В оригинальной заметке есть иллюстрации, я же постарался вытащить скрипты без программы распознавания образов, так что возможны мелкие ошибки в текстах.


Были ли у вас проблемы с большим количеством логов в Операторе ODI? Что бы вы сказали о методе сохранения этих логов так долго и в таком количестве, который вам нужен?

ODI хранит логи в рабочем репозитории, включая и историю значений переменных, в 12 таблицах. Для начала, создайте копии этих таблиц с префиксом ARC_ в отдельной схеме. Я советую не создавать никаких констрейнтов, внешних ключей или индексов для этих таблиц.

  1. Сгенерируйте скрипт создания таблицы, переименуйте таблицу и схему, удалите все кроме CREATE TABLE части. Не создавайте индексы, внешние ключи, констрейнты или любые другие объекты БД для таблицы.
  2. Сделайте реверс и для оригинальных таблиц и для таблиц копий в две модели ODI.
  3. Создайте переменную для хранения количества дней логов, которые не будут удаляться из оригинальных таблиц. Это может быть статическое значение (константа) или этот параметр может храниться в таблице в БД. В этом примере я буду использовать переменную #V_Purge_Log_Retention.
  4. Создайте интерфейс для копирования каждой таблицы и добавьте в эти интерфейсы связки и фильтры согласно приведенной ниже схеме:
    • ARC_SNP_EXP_TXT
      Источники: SNP_EXP_TXT
      Фильтры: TRUNC(SNP_EXP_TXT.FIRST_DATE) < TRUNC(SYSDATE) - #V_Purge_Log_Retention
      Соединения:
    • ARC_SNP_SCEN_REPORT
      Источники: SNP_SCEN_REPORT
      Фильтры: SNP_SCEN_REPORT.CONTEXT_CODE = 'PRODUCTION' AND TRUNC(SNP_SCEN_REPORT.SESS_BEG) < TRUNC(SYSDATE) - #V_Purge_Log_Retention
      Соединения:
    • ARC_SNP_SESS_STEP
      Источники: SNP_SESS_STEP, SNP_SESSION
      Фильтры: SNP_SESSION.CONTEXT_CODE = 'PRODUCTION' AND TRUNC(SNP_SESSION.SESS_BEG) < TRUNC(SYSDATE) - #V_Purge_Log_Retention
      Соединения: SNP_SESS_STEP.SESS_NO = SNP_SESSION.SESS_NO
    • ARC_SNP_SESS_TASK
      Источники: SNP_SESS_TASK, SNP_SESS_STEP, SNP_SESSION
      Фильтры: SNP_SESSION.CONTEXT_CODE = 'PRODUCTION' AND TRUNC(SNP_SESSION.SESS_BEG) < TRUNC(SYSDATE) - #V_Purge_Log_Retention
      Соединения: 1. SNP_SESS_TASK.SESS_NO = SNP_SESS_STEP.SESS_NO AND SNP_SESS_TASK.NNO = SNP_SESS_STEP.NNO 2. SNP_SESS_STEP.SESS_NNO = SNP_SESSION.SESS_NO
    • ARC_SNP_SESS_TASK_LOG
      Источники: SNP_SESS_TASK_LOG, SNP_STEP_LOG, SNP_SESS_STEP, SNP_SESSION
      Фильтры: SNP_SESSION.CONTEXT_CODE = 'PRODUCTION' AND TRUNC(SNP_SESSION.SESS_BEG) < TRUNC(SYSDATE) - #V_Purge_Log_Retention
      Соединения: 1. SNP_SESS_TASK_LOG.NNO = SNP_STEP_LOG.NNO AND SNP_SESS_TASK_LOG.SESS_NO = SNP_STEP_LOG.SESS_NO AND SNP_SESS_TASK_LOG.NB_RUN = SNP_STEP_LOG.NB_RUN 2. SNP_STEP_LOG.SESS_NO = SNP_SESS_STEP.SESS_NO AND SNP_STEP_LOG.NNO = SNP_SESS_STEP.NNO 3. SNP_SESS_STEP.SESS_NO = SNP_SESSION.SESS_NO
    • ARC_SNP_SESS_TXT_LOG
      Источники: SNP_SESS_TXT_LOG, SNP_SESS_TASK_LOG, SNP_STEP_LOG, SNP_SESS_STEP, SNP_SESSION
      Фильтры: SNP_SESSION.CONTEXT_CODE = 'PRODUCTION' AND TRUNC(SNP_SESSION.SESS_BEG) < TRUNC(SYSDATE) - #V_Purge_Log_Retention
      Соединения: 1. SNP_SESS_TXT_LOG.SESS_NO = SNP_SESS_TASK_LOG.SESS_NO AND SNP_SESS_TXT_LOG.NNO = SNP_SESS_TASK_LOG.NNO AND SNP_SESS_TXT_LOG.NB_RUN = SNP_SESS_TASK_LOG.NB_RUN AND SNP_SESS_TXT_LOG.SCEN_TASK_NO = SNP_SESS_TASK_LOG.SCEN_TASK_NO 2. SNP_SESS_TASK_LOG.NNO = SNP_STEP_LOG.NNO AND SNP_SESS_TASK_LOG.SESS_NO = SNP_STEP_LOG.SESS_NO AND SNP_SESS_TASK_LOG.NB_RUN = SNP_STEP_LOG.NB_RUN 3. SNP_STEP_LOG.SESS_NO = SNP_SESS_STEP.SESS_NO AND SNP_STEP_LOG.NNO = SNP_SESS_STEP.NNO 4. SNP_SESS_STEP.SESS_NO = SNP_SESSION.SESS_NO
    • ARC_SNP_SESSION
      Источники: SNP_SESSION
      Фильтры: SNP_SESSION.CONTEXT_CODE = 'PRODUCTION' AND TRUNC(SNP_SESSION.SESS_BEG) < TRUNC(SYSDATE) - #V_Purge_Log_Retention
      Соединения:
    • ARC_SNP_STEP_LOG
      Источники: SNP_STEP_LOG, SNP_SESS_STEP, SNP_SESSION
      Фильтры: SNP_SESSION.CONTEXT_CODE = 'PRODUCTION' AND TRUNC(SNP_SESSION.SESS_BEG) < TRUNC(SYSDATE) - #V_Purge_Log_Retention
      Соединения: 1. SNP_STEP_LOG.SESS_NO = SNP_STEP_SESS.SESS_NO AND SNP_STEP_LOG.NNO = SNP_SESS_STEP.NNO 2. SNP_SESS_STEP.SESS_NO = SNP_SESSION.SESS_NO
    • ARC_SNP_STEP_REPORT
      Источники: SNP_STEP_REPORT, SNP_SCEN_REPORT
      Фильтры: SNP_SCEN_REPORT.CONTEXT_CODE = 'PRODUCTION' AND TRUNC(SNP_SCEN_REPORT.SESS_BEGIN) < TRUNC(SYSDATE) - #V_Purge_Log_Retention
      Соединения: SNP_STEP_REPORT.SCEN_NO = SNP_SCEN_REPORT.SCEN_NO AND SNP_STEP_REPORT.SCEN_RUN_NO = SNP_SCEN_REPORT.SCEN_RUN_NO
    • ARC_SNP_TASK_TXT
      Источники: SNP_TASK_TXT, SNP_SESS_TASK, SNP_SESS_STEP, SNP_SESSION
      Фильтры: SNP_SESSION.CONTEXT_CODE = 'PRODUCTION' AND TRUNC(SNP_SESSION.SESS_BEG) < TRUNC(SYSDATE) - #V_Purge_Log_Retention
      Соединения: 1. SNP_TASK_TXT.SESS_NO = SNP_SESS_TASK.SESS_NO AND SNP_TASK_TXT.NNO = SNP_SESS_TASK.NNO AND SNP_TASK_TXT.SCEN_TASK_NO = SNP_SESS_TASK.SCEN_TASK_NO 2. SNP_SESS_TASK.SESS_NO = SNP_SESS_STEP.SESS_NO AND SNP_SESS_TASK.NNO = SNP_SESS_STEP.NNO AND SNP_SESS_STEP.SESS_NO = SNP_SESSION.SESS_NO
    • ARC_SNP_VAR_DATA
      Источники: SNP_VAR_DATA
      Фильтры: SNP_VAR_DATA.CONTEXT_CODE = 'PRODUCTION' AND TRUNC(SNP_VAR_DATA.FIRST_DATE) < TRUNC(SYSDATE) - #V_Purge_Log_Retention
      Соединения:
    • ARC_SNP_VAR_SESS
      Источники: SNP_VAR_SESS, SNP_SESSION
      Фильтры: SNP_SESSION.CONTEXT_CODE = 'PRODUCTION' AND TRUNC(SNP_SESSION.SESS_BEG) < TRUNC(SYSDATE) - #V_Purge_Log_Retention
      Соединения: SNP_VAR_SESS.SESS_NO = SNP_SESSION.SESS_NO

    Примечание переводчика: Замените название контекста, которое в приведенном коде установлено в 'PRODUCTION'. Условия соединений приведены скорее для примера, при создании интерфейсов ODI сам установит нужные связи, если они были получены из БД при реверсе таблиц рабочего репозитория.

  5. Создайте процедуру ODI для удаления данных логов из оригинальных таблиц репозитория в порядке, указанном в таблице ниже. Если удалять данные в другом порядке можно получить ошибку "referential integrity error" или удалить совсем другие данные.

    1. Clear SNP_SESS_TXT_LOG
      DELETE /*+ USE_HASH(A) PARALLEL(A) */ FROM <%odiGetSchemaName("WORKREP")%>.SNP_SESS_TXT_LOG A WHERE SESS_NO IN (SELECT SESS_NO FROM <%odiGetSchemaName("WORKREP")%>.SNP_SESSION WHERE TRUNC(SESS_BEG) < TRUNC(SYSDATE) - #V_Purge_Log_Retention)
    2. Clear SNP_SESS_TASK_LOG
      DELETE /*+ USE_HASH(A) PARALLEL(A) */ FROM <%odiGetSchemaName("WORKREP")%>.SNP_SESS_TASK_LOG A WHERE SESS_NO IN (SELECT SESS_NO FROM <%odiGetSchemaName("WORKREP").SNP_SESSION WHERE TRUNC(SESS_BEG) < TRUNC(SYSDATE) - #V_Purge_Log_Retention)
    3. Clear SNP_TASK_TXT
      DELETE /*+ USE_HASH(A) PARALLEL(A) */ FROM <%odiGetSchemaName("WORKREP")%>.SNP_TASK_TXT A WHERE SESS_NO IN (SELECT SESS_NO FROM <%odiGetSchemaName("WORKREP").SNP_SESSION WHERE TRUNC(SESS_BEG) < TRUNC(SYSDATE) - #V_Purge_Log_Retention)
    4. Clear SNP_STEP_LOG
      DELETE /*+ USE_HASH(A) PARALLEL(A) */ FROM <%odiGetSchemaName("WORKREP")%>.SNP_STEP_LOG A WHERE SESS_NO IN (SELECT SESS_NO FROM <%odiGetSchemaName("WORKREP").SNP_SESSION WHERE TRUNC(SESS_BEG) < TRUNC(SYSDATE) - #V_Purge_Log_Retention)
    5. Clear SNP_SESS_TASK
      DELETE /*+ USE_HASH(A) PARALLEL(A) */ FROM <%odiGetSchemaName("WORKREP")%>.SNP_SESS_TASK A WHERE SESS_NO IN (SELECT SESS_NO FROM <%odiGetSchemaName("WORKREP").SNP_SESSION WHERE TRUNC(SESS_BEG) < TRUNC(SYSDATE) - #V_Purge_Log_Retention)
    6. Clear SNP_SESS_STEP
      DELETE /*+ USE_HASH(A) PARALLEL(A) */ FROM <%odiGetSchemaName("WORKREP")%>.SNP_SESS_STEP A WHERE SESS_NO IN (SELECT SESS_NO FROM <%odiGetSchemaName("WORKREP").SNP_SESSION WHERE TRUNC(SESS_BEG) < TRUNC(SYSDATE) - #V_Purge_Log_Retention)
    7. Clear SNP_VAR_DATA
      DELETE /*+ USE_HASH(A) PARALLEL(A) */ FROM <%odiGetSchemaName("WORKREP")%>.SNP_VAR_DATA A WHERE TRUNC(A.FIRST_DATE) < TRUNC(SYSDATE) - #V_Purge_Log_Retention
    8. Clear SNP_VAR_SESS
      DELETE /*+ USE_HASH(A) PARALLEL(A) */ FROM <%odiGetSchemaName("WORKREP")%>.SNP_VAR_SESS A WHERE SESS_NO IN (SELECT SESS_NO FROM <%odiGetSchemaName("WORKREP").SNP_SESSION WHERE TRUNC(SESS_BEG) < TRUNC(SYSDATE) - #V_Purge_Log_Retention)
    9. Clear SNP_EXP_TXT
      DELETE /*+ USE_HASH(A) PARALLEL(A) */ FROM <%odiGetSchemaName("WORKREP")%>.SNP_EXP_TXT A WHERE TRUNC(A.FIRST_DATE) < TRUNC(SYSDATE) - #V_Purge_Log_Retention
    10. Clear SNP_SESSION
      DELETE /*+ USE_HASH(A) PARALLEL(A) */ FROM <%odiGetSchemaName("WORKREP")%>.SNP_SESSION A WHERE TRUNC(SESS_BEG) < TRUNC(SYSDATE) - #V_Purge_Log_Retention
    11. Clear SNP_STEP_REPORT
      DELETE /*+ USE_HASH(A) PARALLEL(A) */ FROM <%odiGetSchemaName("WORKREP")%>.SNP_STEP_REPORT A WHERE TRUNC(A.STEP_BEG) < TRUNC(SYSDATE) - #V_Purge_Log_Retention
    12. Clear SNP_SCEN_REPORT
      DELETE /*+ USE_HASH(A) PARALLEL(A) */ FROM <%odiGetSchemaName("WORKREP")%>.SNP_SCEN_REPORT A WHERE TRUNC(A.SESS_BEG) < TRUNC(SYSDATE) - #V_Purge_Log_Retention

    Примечание переводчика: Замените название логической схемы WORKREP, на то, которое у вас используется для рабочего репозитория ODI.

  6. Создайте пакет, в который включите сценарии, сгенерированные из созданных интерфейсов. Эти сценарии должны запускаться в асинхронном режиме. Если один из сценариев упадет - сгенерируется исключительная ситуация. Подробнее о механизмах вызова исключительных ситуаций в моем посте 'ODI Alert Mechanism'
Вот и все. Если вы выполните приведенные шаги в правильной последовательности ваши ODI логи будут сохранены в ARC_ таблицах.

Итак, архивы есть. Получить к ним доступ можно через написание SQL запросов, а можно поступить немного иначе и смотреть логи через привычный интерфейс Оператора ODI.

Для этого я предлагаю следующий подход. Создайте новый репозиторий выполнения. Таблицы этого репозитория будут находиться в отдельной схеме БД Oracle. Замените указанные в заметке 12 таблиц нового репозитория на представления, которые будут вычитывать данные из _ARC таблиц.

Запустите Оператор, создайте подключение к новому репозиторию и войдите в него. Если Оператор будет показывать архивные сессии, значит 12 таблиц, которые были скопированы, действительно достаточно.

P.S. В связи с более полным перечнем таблиц, мой первый описанный способ удаления логов из рабочего репозитория необходимо будет перерабатывать.

Комментариев нет:

Отправить комментарий