11 XStream Inの監視

データ・ディクショナリ・ビューを問い合せることで、XStream In構成を監視できます。

この章では、XStreamを監視する方法について説明します。

XStream Inを使用して、Oracle Streams適用プロセスはインバウンド・サーバーとして機能します。したがって、適用プロセスのデータ・ディクショナリ・ビューを使用してインバウンド・サーバーを監視することもできます。

注意:

この章の問合せの例では、可能な場合には常にALL_静的データ・ディクショナリ・ビューを使用します。場合によっては、ALL_ビューの情報にはDBA_ビューの情報より多くの制限があります。

SQL*Plusでは、信頼できるXStream管理者がALL_およびDBA_ビューを問い合せることができます。信頼されないXStream管理者はALL_ビューのみを問い合せることができます。

11.1 インバウンド・サーバーのセッション情報の表示

例では、インバウンド・サーバーのセッション情報を表示する方法を示します。

この項で説明する問合せを実行すると、データベース内のXStreamコンポーネントに関する次のセッション情報が表示されます。

  • XStreamコンポーネント名

  • セッション識別子

  • シリアル番号

  • オペレーション・システムのプロセス識別番号

  • XStreamプロセス数

データベース内に構成済の複数のXStream Inコンポーネントがある場合、この問合せは、特定のXStreamコンポーネントに対してセッションの情報を判別するときに特に便利です。

データベース内の各XStreamコンポーネントに対してこの情報を表示する手順:

  1. データベースにXStream管理者として接続します。

    SQL*Plusでのデータベースへの接続の詳細は、Oracle Database管理者ガイドを参照してください。

  2. 次の問合せを実行します。

    COLUMN ACTION HEADING 'XStream Component' FORMAT A30
    COLUMN SID HEADING 'Session ID' FORMAT 99999
    COLUMN SERIAL# HEADING 'Session|Serial|Number' FORMAT 99999999
    COLUMN PROCESS HEADING 'Operating System|Process Number' FORMAT A17
    COLUMN PROCESS_NAME HEADING 'XStream|Process|Number' FORMAT A7
     
    SELECT /*+PARAM('_module_action_old_length',0)*/ ACTION,
           SID,
           SERIAL#,
           PROCESS,
           SUBSTR(PROGRAM,INSTR(PROGRAM,'(')+1,4) PROCESS_NAME
      FROM V$SESSION
      WHERE MODULE ='XStream';
    

XStream In構成の出力は次のようになります。

                                            Session                   XStream
                                             Serial Operating System  Process
XStream Component              Session ID    Number Process Number    Number
------------------------------ ---------- --------- ----------------- -------
XIN - Apply Reader                     19         9 27304             AS01
XIN - Apply Server                     22         5 27308             AS03
XIN - Apply Server                     25        31 27313             AS05
XIN - Apply Coordinator               112         7 27302             AP01
XIN - Apply Server                    113         5 27306             AS02
XIN - Propagation Receiver            114        17 27342             TNS
XIN - Apply Server                    115        39 27311             AS04

XStreamプロセス数のTNSが表示された行には、インバウンド・サーバーに接続されているXStreamクライアント・アプリケーションのセッションに関する情報が含まれます。

注意:

この問合せを実行するには、ユーザーがV$SESSIONビューの問合せを実行する権限を持っている必要があります。

関連項目:

V$SESSIONビューの詳細は、『Oracle Databaseリファレンス』を参照してください。

11.2 インバウンド・サーバーに関する一般情報の表示

例では、インバウンド・サーバーに関する一般情報を表示する方法を示します。

この項の問合せを実行して、インバウンド・サーバーに関する次の情報を表示できます。

  • インバウンド・サーバーの名前

  • インバウンド・サーバーで使用されるキューの所有者

  • インバウンド・サーバーによって使用されるキューの名前

  • インバウンド・サーバーの適用ユーザー

インバウンド・サーバーに関する一般情報を表示する手順:

  1. データベースにXStream管理者として接続します。

    SQL*Plusでのデータベースへの接続の詳細は、Oracle Database管理者ガイドを参照してください。

  2. 次の問合せを実行します。

    COLUMN SERVER_NAME HEADING 'Inbound Server Name' FORMAT A20
    COLUMN QUEUE_OWNER HEADING 'Queue Owner' FORMAT A15
    COLUMN QUEUE_NAME HEADING 'Queue Name' FORMAT A15
    COLUMN APPLY_USER HEADING 'Apply User' FORMAT A15
     
    SELECT SERVER_NAME, 
           QUEUE_OWNER,
           QUEUE_NAME,
           APPLY_USER
      FROM ALL_XSTREAM_INBOUND;
    

出力は次のようになります。

Inbound Server Name  Queue Owner     Queue Name      Apply User
-------------------- --------------- --------------- ---------------
XIN                  XSTRMADMIN      XIN_QUEUE       XSTRMADMIN

11.3 XStream Inコンポーネントでのイベントの履歴の監視

例では、DBA_REPLICATION_PROCESS_EVENTSビューを問い合せることによって、XStream Inコンポーネントでのイベントの履歴を監視する方法を示しています。

たとえば、このビューは、コンポーネントの作成または起動時に表示できます。コンポーネント・パラメータが変更されたときに表示することもできます。コンポーネントがエラーを検出した場合は、エラーに関する情報を表示できます。

このトピックの問合せでは、XStream Outコンポーネントでのイベントに関する次の情報が表示されます。

  • XStreamコンポーネント名

  • コンポーネント・タイプ

  • イベント名

  • イベントの説明

  • イベント時間

データベース内の各XStream Inコンポーネントについて、次の情報を表示する手順:

  1. データベースにXStream管理者として接続します。

    SQL*Plusでのデータベースへの接続の詳細は、Oracle Database管理者ガイドを参照してください。

  2. 次の問合せを実行します。

    COLUMN STREAMS_NAME FORMAT A12
    COLUMN PROCESS_TYPE FORMAT A17
    COLUMN EVENT_NAME FORMAT A10
    COLUMN DESCRIPTION FORMAT A20
    COLUMN EVENT_TIME FORMAT A15
    
    SELECT STREAMS_NAME,
           PROCESS_TYPE,
           EVENT_NAME,
           DESCRIPTION,
           EVENT_TIME
      FROM DBA_REPLICATION_PROCESS_EVENTS;
    

XStream In構成の出力は次のようになります。

STREAMS_NAME PROCESS_TYPE      EVENT_NAME DESCRIPTION          EVENT_TIME
------------ ----------------- ---------- -------------------- ---------------
APP_JOBS     APPLY COORDINATOR CREATE     SUCCESS              03-NOV-15 07.19
                                                               .27.238151 AM
APP_JOBS     APPLY COORDINATOR START      SUCCESS              03-NOV-15 07.21
                                                               .50.812534 AM
APP_JOBS     APPLY READER      START      SUCCESS              03-NOV-15 07.21
                                                               .51.713367 AM
APP_JOBS     APPLY SERVER      START      SUCCESS              03-NOV-15 07.21
                                                               .51.895019 AM

11.4 インバウンド・サーバーのステータスおよびエラー情報の表示

例では、インバウンド・サーバーのステータスおよびエラー情報を表示する方法を示します。

DBA_APPLYビューは、インバウンド・サーバーとして機能している適用プロセスのPURPOSE列にあるXStream Inを表示します。

インバウンド・サーバーのステータスを表示する手順:

  1. データベースにXStream管理者として接続します。

    SQL*Plusでのデータベースへの接続の詳細は、Oracle Database管理者ガイドを参照してください。

  2. 次の問合せを実行します。

    COLUMN APPLY_NAME HEADING 'Inbound Server|Name' FORMAT A15
    COLUMN STATUS HEADING 'Status' FORMAT A8
    COLUMN ERROR_NUMBER HEADING 'Error Number' FORMAT 9999999
    COLUMN ERROR_MESSAGE HEADING 'Error Message' FORMAT A40
    
    SELECT APPLY_NAME, 
           STATUS,
           ERROR_NUMBER,
           ERROR_MESSAGE
      FROM DBA_APPLY
      WHERE PURPOSE = 'XStream In';
    

出力は次のようになります。

Inbound Server
Name            Status   Error Number Error Message
--------------- -------- ------------ ----------------------------------------
XIN             ENABLED

この出力では、XINはインバウンド・サーバーとして機能している適用プロセスであることが示されています。

注意:

この例では、DBA_APPLYビューを問い合せます。このビューにより、信頼できるユーザーは、データベース内のすべての適用ユーザーの情報を表示できます。信頼されないユーザーは、ALL_APPLYビューを問い合せる必要があります。このビューでは現在のユーザーの情報に制限されます。

11.5 インバウンド・サーバーの適用パラメータ設定の表示

例では、インバウンド・サーバーの適用パラメータ設定を表示する方法を示します。

適用パラメータはインバウンド・サーバーの動作方法を決定します。

インバウンド・サーバーの適用パラメータ設定を表示する手順:

  1. データベースにXStream管理者として接続します。

    SQL*Plusでのデータベースへの接続の詳細は、Oracle Database管理者ガイドを参照してください。

  2. 次の問合せを実行します。

    COLUMN APPLY_NAME HEADING 'Inbound Server|Name' FORMAT A15
    COLUMN PARAMETER HEADING 'Parameter' FORMAT A30
    COLUMN VALUE HEADING 'Value' FORMAT A22
    COLUMN SET_BY_USER HEADING 'Set by|User?' FORMAT A10
    
    SELECT APPLY_NAME,
           PARAMETER, 
           VALUE,
           SET_BY_USER  
      FROM ALL_APPLY_PARAMETERS a, ALL_XSTREAM_INBOUND i
      WHERE a.APPLY_NAME=i.SERVER_NAME
      ORDER BY a.PARAMETER;
    

出力は次のようになります。

Inbound Server                                                        Set by
Name            Parameter                      Value                  User?
--------------- ------------------------------ ---------------------- ----------
XIN             ALLOW_DUPLICATE_ROWS           N                      NO
XIN             APPLY_SEQUENCE_NEXTVAL         Y                      NO
XIN             COMMIT_SERIALIZATION           DEPENDENT_TRANSACTIONS NO
XIN             COMPARE_KEY_ONLY               Y                      NO
XIN             COMPUTE_LCR_DEP_ON_ARRIVAL     N                      NO
XIN             DISABLE_ON_ERROR               Y                      NO
XIN             DISABLE_ON_LIMIT               N                      NO
XIN             EAGER_SIZE                     9500                   NO
XIN             ENABLE_XSTREAM_TABLE_STATS     Y                      NO
XIN             EXCLUDETAG                                            NO
XIN             EXCLUDETRANS                                          NO
XIN             EXCLUDEUSER                                           NO
XIN             EXCLUDEUSERID                                         NO
XIN             GETAPPLOPS                     Y                      NO
XIN             GETREPLICATES                  N                      NO
XIN             GROUPTRANSOPS                  250                    NO
XIN             HANDLECOLLISIONS               N                      NO
XIN             IGNORE_TRANSACTION                                    NO
XIN             MAXIMUM_SCN                    INFINITE               NO
XIN             MAX_PARALLELISM                50                     NO
XIN             MAX_SGA_SIZE                   INFINITE               NO
XIN             OPTIMIZE_PROGRESS_TABLE        Y                      NO
XIN             OPTIMIZE_SELF_UPDATES          Y                      NO
XIN             PARALLELISM                    4                      NO
XIN             PRESERVE_ENCRYPTION            Y                      NO
XIN             RTRIM_ON_IMPLICIT_CONVERSION   Y                      NO
XIN             STARTUP_SECONDS                0                      NO
XIN             SUPPRESSTRIGGERS               Y                      NO
XIN             TIME_LIMIT                     INFINITE               NO
XIN             TRACE_LEVEL                    0                      NO
XIN             TRANSACTION_LIMIT              INFINITE               NO
XIN             TXN_AGE_SPILL_THRESHOLD        900                    NO
XIN             TXN_LCR_SPILL_THRESHOLD        10000                  NO
XIN             WRITE_ALERT_LOG                Y                      NO

インバウンド・サーバーでは、一部の適用パラメータの設定は無視されます。

注意:

パラメータのSet by user列がNOの場合、そのパラメータはデフォルト値に設定されます。パラメータのSet by user列がYESの場合、パラメータはユーザーによって設定され、デフォルト値に設定されることもされないこともあります。

11.6 インバウンド・サーバーの位置情報の表示

例では、インバウンド・サーバーの位置情報を表示する方法を示します。

インバウンド・サーバーでは、ALL_XSTREAM_INBOUND_PROGRESSビューを問い合せることで、位置情報を表示できます。具体的には、この項で説明する問合せを実行すると、次の位置情報を表示できます。

  • インバウンド・サーバーの名前

  • インバウンド・サーバーの適用最低位置

  • インバウンド・サーバーのオーバーフロー位置

  • インバウンド・サーバーの適用最高位置

  • インバウンド・サーバーの処理済最低位置

インバウンド・サーバーの位置情報を表示する手順:

  1. データベースにXStream管理者として接続します。

    SQL*Plusでのデータベースへの接続の詳細は、Oracle Database管理者ガイドを参照してください。

  2. 次の問合せを実行します。

    COLUMN SERVER_NAME HEADING 'Inbound|Server|Name' FORMAT A10
    COLUMN APPLIED_LOW_POSITION HEADING 'Applied Low|Position' FORMAT A15
    COLUMN SPILL_POSITION HEADING 'Spill Position' FORMAT A15
    COLUMN APPLIED_HIGH_POSITION HEADING 'Applied High|Position' FORMAT A15
    COLUMN PROCESSED_LOW_POSITION HEADING 'Processed Low|Position' FORMAT A15
     
    SELECT SERVER_NAME, 
           APPLIED_LOW_POSITION,
           SPILL_POSITION,
           APPLIED_HIGH_POSITION,
           PROCESSED_LOW_POSITION
      FROM ALL_XSTREAM_INBOUND_PROGRESS;
    

出力は次のようになります。

Inbound
Server     Applied Low                     Applied High    Processed Low
Name       Position        Spill Position  Position        Position
---------- --------------- --------------- --------------- ---------------
XIN        C10A            C11D            C10A            C11D

出力で示されている位置の値は、インバウンド・サーバーに接続するクライアント・アプリケーションによって設定されました。ただし、インバウンド・サーバーによって、現在の適用最低位置、オーバーフロー位置、適用最高位置、および処理済最低位置の値が決定されます。

11.7 DML競合ハンドラに関する情報の表示

DBA_APPLY_DML_CONF_HANDLERSビューには、DML競合ハンドラに関する情報が表示されます。

DBMS_APPLY_ADMパッケージのSET_DML_CONFLICT_HANDLERプロシージャを使用して、DML競合ハンドラを構成できます。
  1. データベースにXStream管理者として接続します。
  2. DBA_APPLY_DML_CONF_HANDLERSビューを問い合せます。

例11-1 DML競合ハンドラに関する情報の表示

COLUMN APPLY_NAME FORMAT A8
COLUMN OBJECT_OWNER FORMAT A5
COLUMN OBJECT_NAME FORMAT A12
COLUMN COMMAND_TYPE FORMAT A6
COLUMN CONFLICT_TYPE FORMAT A11
COLUMN METHOD_NAME FORMAT A12
COLUMN CONFLICT_HANDLER_NAME FORMAT A20

SELECT APPLY_NAME,
       OBJECT_OWNER, 
       OBJECT_NAME,
       COMMAND_TYPE,
       CONFLICT_TYPE, 
       METHOD_NAME, 
       CONFLICT_HANDLER_NAME
  FROM DBA_APPLY_DML_CONF_HANDLERS
  ORDER BY OBJECT_OWNER, OBJECT_NAME, CONFLICT_HANDLER_NAME;

出力は次のようになります。

APPLY_NA OBJEC OBJECT_NAME  COMMAN CONFLICT_TY METHOD_NAME  CONFLICT_HANDLER_NAM
-------- ----- ------------ ------ ----------- ------------ --------------------
APP_JOBS HR    JOBS         DELETE ROW_MISSING IGNORE       JOBS_HANDLER_DELETE
APP_JOBS HR    JOBS         INSERT ROW_EXISTS  OVERWRITE    JOBS_HANDLER_INSERT
APP_JOBS HR    JOBS         UPDATE ROW_EXISTS  OVERWRITE    JOBS_HANDLER_UPDATE

関連トピック

11.8 エラー・ハンドラに関する情報の表示

DBA_APPLY_REPERROR_HANDLERSビューには、DML競合ハンドラに関する情報が表示されます。

DBMS_APPLY_ADMパッケージのSET_REPERROR_HANDLERプロシージャを使用して、エラー・ハンドラを構成できます。
  1. データベースにXStream管理者として接続します。
  2. DBA_APPLY_REPERROR_HANDLERSビューを問い合せます。

例11-2 DML競合ハンドラに関する情報の表示

COLUMN APPLY_NAME FORMAT A15
COLUMN OBJECT_OWNER FORMAT A15
COLUMN OBJECT_NAME FORMAT A15
COLUMN ERROR_NUMBER 999999999
COLUMN METHOD FORMAT A15

SELECT APPLY_NAME,
       OBJECT_OWNER, 
       OBJECT_NAME,
       ERROR_NUMBER,
       METHOD 
  FROM DBA_APPLY_REPERROR_HANDLERS
  ORDER BY OBJECT_OWNER, OBJECT_NAME;

出力は次のようになります。

APPLY_NAME      OBJECT_OWNER    OBJECT_NAME     ERROR_NUMBER METHOD
--------------- --------------- --------------- ------------ ---------------
APP_OE          OE              ORDERS                 26787 IGNORE

11.9 適用エラーのチェック

適用エラーの有無をチェックする例を示します。

信頼できるユーザーは、DBA_APPLY_ERRORデータ・ディクショナリ・ビューを問い合せるか、またはOracle Enterprise Manager Cloud Controlを使用して、適用エラーを確認できます。信頼されないユーザーは、ALL_APPLY_ERRORデータ・ディクショナリ・ビューを問い合せることで、適用エラーを確認できます。

適用エラーを確認する手順:

  1. データベースにXStream管理者として接続します。

    SQL*Plusでのデータベースへの接続の詳細は、Oracle Database管理者ガイドを参照してください。

  2. 次の問合せを実行します。

    COLUMN APPLY_NAME HEADING 'Inbound|Server|Name' FORMAT A7
    COLUMN SOURCE_DATABASE HEADING 'Source|Database' FORMAT A8
    COLUMN SOURCE_TRANSACTION_ID HEADING 'Source|Transaction|ID' FORMAT A11
    COLUMN MESSAGE_NUMBER HEADING 'Failed Message|in Error|Transaction' FORMAT 99999999
    COLUMN ERROR_NUMBER HEADING 'Error Number' FORMAT 99999999
    COLUMN ERROR_MESSAGE HEADING 'Error Message' FORMAT A10
    COLUMN MESSAGE_COUNT HEADING 'Messages in|Error|Transaction' FORMAT 99999999
    
    SELECT APPLY_NAME, 
           SOURCE_DATABASE, 
           SOURCE_TRANSACTION_ID, 
           MESSAGE_NUMBER,
           ERROR_NUMBER,
           ERROR_MESSAGE,
           MESSAGE_COUNT
      FROM ALL_APPLY_ERROR;
    

注意:

信頼できるユーザーは、問合せのALL_APPLY_ERRORDBA_APPLY_ERRORで置き換える必要があります。

適用エラーがある場合、出力は次のようになります。

Inbound          Source      Failed Message                         Messages in
Server  Source   Transaction       in Error                               Error
Name    Database ID             Transaction Error Number Error Mess Transaction
------- -------- ----------- -------------- ------------ ---------- -----------
XIN     OUTX.EXA 19.20.215                1         1031 ORA-01031:           1
        MPLE.COM                                          insuffici
                                                         ent privil
                                                         eges
XIN     OUTX.EXA 11.21.158                1         1031 ORA-01031:           1
        MPLE.COM                                          insuffici
                                                         ent privil
                                                         eges

適用エラーがある場合は、エラーが発生したトランザクションを再実行するか、またはそのトランザクションを削除することができます。エラーが発生したトランザクションを再実行するには、まず、トランザクションでエラーが発生する原因となった状態を修正します。

エラーが発生したトランザクションを削除するときに、複数のデータベースでデータを共有している場合には、手動によるデータの再同期化が必要になることがあります。データを手動で再同期化する場合は、必要に応じて適切なセッション・タグを設定してください。

11.10 適用エラーの詳細情報の表示

SQLスクリプトによって、データベースのエラー・キュー内のエラー・トランザクションに関する詳細情報が表示されます。

11.10.1 手順1: ALL_APPLY_ERRORビューでの明示的なSELECT権限の付与

DBMS_XSTREAM_AUTHパッケージのGRANT_ADMIN_PRIVILEGEプロシージャの実行により、ALL_APPLY_ERRORビューでのSELECT権限をユーザーに付与します。

ここで説明するprint_errorsおよびprint_transactionプロシージャを作成して実行するユーザーには、ALL_APPLY_ERRORデータ・ディクショナリ・ビューに対する明示的なSELECT権限が付与されている必要があります。この権限は、ロールを介しては付与できません。

ALL_APPLY_ERRORビューでの明示的なSELECT権限を付与する手順:

  1. SQL*Plusで、権限を付与できる管理ユーザーとして接続します。

    SQL*Plusでのデータベースへの接続の詳細は、Oracle Database管理者ガイドを参照してください。

  2. ALL_APPLY_ERRORデータ・ディクショナリ・ビューでのSELECT権限を適切なユーザーに付与します。たとえば、この権限をxstrmadminユーザーに付与するには、次の文を実行します。

    GRANT SELECT ON ALL_APPLY_ERROR TO xstrmadmin;
    
  3. DBMS_APPLY_ADMパッケージのEXECUTE権限を付与します。たとえば、この権限をxstrmadminユーザーに付与するには、次の文を実行します。

    GRANT EXECUTE ON DBMS_APPLY_ADM TO xstrmadmin;
    
  4. 手順2および3で権限を付与したユーザーとして、データベースに接続します。

11.10.2 手順2: ANYDATAオブジェクト内の値を出力するプロシージャの作成

選択したデータ型に対して、指定したANYDATAオブジェクト内の値が出力されるプロシージャを作成します。このプロシージャには、オプションで他のデータ型を追加できます。

CREATE OR REPLACE PROCEDURE print_any(data IN ANYDATA) IS
  tn  VARCHAR2(61);
  str VARCHAR2(4000);
  chr VARCHAR2(1000);
  num NUMBER;
  dat DATE;
  rw  RAW(4000);
  res NUMBER;
BEGIN
  IF data IS NULL THEN
    DBMS_OUTPUT.PUT_LINE('NULL value');
    RETURN;
  END IF;
  tn := data.GETTYPENAME();
  IF tn = 'SYS.VARCHAR2' THEN
    res := data.GETVARCHAR2(str);
    DBMS_OUTPUT.PUT_LINE(SUBSTR(str,0,253));
  ELSIF tn = 'SYS.CHAR' then
    res := data.GETCHAR(chr);
    DBMS_OUTPUT.PUT_LINE(SUBSTR(chr,0,253));
  ELSIF tn = 'SYS.VARCHAR' THEN
    res := data.GETVARCHAR(chr);
    DBMS_OUTPUT.PUT_LINE(chr);
  ELSIF tn = 'SYS.NUMBER' THEN
    res := data.GETNUMBER(num);
    DBMS_OUTPUT.PUT_LINE(num);
  ELSIF tn = 'SYS.DATE' THEN
    res := data.GETDATE(dat);
    DBMS_OUTPUT.PUT_LINE(dat);
  ELSIF tn= 'SYS.TIMESTAMP' THEN
    res := data.GETTIMESTAMP(dat);
    DBMS_OUTPUT.PUT_LINE(TO_CHAR(dat,'DD-MON-RR HH.MI.SSXFF AM'));
  ELSIF tn= 'SYS.TIMESTAMPTZ' THEN
    res := data.GETTIMESTAMPTZ(dat);
    DBMS_OUTPUT.PUT_LINE(TO_CHAR(dat,'DD-MON-RR HH.MI.SSXFF AM'));
  ELSIF tn= 'SYS.TIMESTAMPLTZ' THEN
    res := data.GETTIMESTAMPLTZ(dat);
    DBMS_OUTPUT.PUT_LINE(TO_CHAR(dat,'DD-MON-RR HH.MI.SSXFF AM'));
  ELSIF tn = 'SYS.RAW' THEN
    -- res := data.GETRAW(rw);
    -- DBMS_OUTPUT.PUT_LINE(SUBSTR(DBMS_LOB.SUBSTR(rw),0,253));
    DBMS_OUTPUT.PUT_LINE('BLOB Value');
  ELSIF tn = 'SYS.BLOB' THEN
    DBMS_OUTPUT.PUT_LINE('BLOB Found');
  ELSE
    DBMS_OUTPUT.PUT_LINE('typename is ' || tn);
  END IF;
END print_any;
/

11.10.3 手順3: 指定したLCRを出力するプロシージャの作成

指定したLCRを出力するプロシージャを作成します。

このプロシージャでは、手順2: ANYDATAオブジェクト内の値を出力するプロシージャの作成で作成したprint_anyプロシージャがコールされます。

CREATE OR REPLACE PROCEDURE print_lcr(lcr IN ANYDATA) IS
  typenm    VARCHAR2(61);
  ddllcr    SYS.LCR$_DDL_RECORD;
  proclcr   SYS.LCR$_PROCEDURE_RECORD;
  rowlcr    SYS.LCR$_ROW_RECORD;
  res       NUMBER;
  newlist   SYS.LCR$_ROW_LIST;
  oldlist   SYS.LCR$_ROW_LIST;
  ddl_text  CLOB;
  ext_attr  ANYDATA;
BEGIN
  typenm := lcr.GETTYPENAME();
  DBMS_OUTPUT.PUT_LINE('type name: ' || typenm);
  IF (typenm = 'SYS.LCR$_DDL_RECORD') THEN
    res := lcr.GETOBJECT(ddllcr);
    DBMS_OUTPUT.PUT_LINE('source database: ' || 
                         ddllcr.GET_SOURCE_DATABASE_NAME);
    DBMS_OUTPUT.PUT_LINE('owner: ' || ddllcr.GET_OBJECT_OWNER);
    DBMS_OUTPUT.PUT_LINE('object: ' || ddllcr.GET_OBJECT_NAME);
    DBMS_OUTPUT.PUT_LINE('is tag null: ' || ddllcr.IS_NULL_TAG);
    DBMS_LOB.CREATETEMPORARY(ddl_text, TRUE);
    ddllcr.GET_DDL_TEXT(ddl_text);
    DBMS_OUTPUT.PUT_LINE('ddl: ' || ddl_text);    
    -- Print extra attributes in DDL LCR
    ext_attr := ddllcr.GET_EXTRA_ATTRIBUTE('serial#');
      IF (ext_attr IS NOT NULL) THEN
        DBMS_OUTPUT.PUT_LINE('serial#: ' || ext_attr.ACCESSNUMBER());
      END IF;
    ext_attr := ddllcr.GET_EXTRA_ATTRIBUTE('session#');
      IF (ext_attr IS NOT NULL) THEN
        DBMS_OUTPUT.PUT_LINE('session#: ' || ext_attr.ACCESSNUMBER());
      END IF; 
    ext_attr := ddllcr.GET_EXTRA_ATTRIBUTE('thread#');
      IF (ext_attr IS NOT NULL) THEN
        DBMS_OUTPUT.PUT_LINE('thread#: ' || ext_attr.ACCESSNUMBER());
      END IF;   
    ext_attr := ddllcr.GET_EXTRA_ATTRIBUTE('tx_name');
      IF (ext_attr IS NOT NULL) THEN
        DBMS_OUTPUT.PUT_LINE('transaction name: ' || ext_attr.ACCESSVARCHAR2());
      END IF;
    ext_attr := ddllcr.GET_EXTRA_ATTRIBUTE('username');
      IF (ext_attr IS NOT NULL) THEN
        DBMS_OUTPUT.PUT_LINE('username: ' || ext_attr.ACCESSVARCHAR2());
      END IF;      
    DBMS_LOB.FREETEMPORARY(ddl_text);
  ELSIF (typenm = 'SYS.LCR$_ROW_RECORD') THEN
    res := lcr.GETOBJECT(rowlcr);
    DBMS_OUTPUT.PUT_LINE('source database: ' || 
                         rowlcr.GET_SOURCE_DATABASE_NAME);
    DBMS_OUTPUT.PUT_LINE('owner: ' || rowlcr.GET_OBJECT_OWNER);
    DBMS_OUTPUT.PUT_LINE('object: ' || rowlcr.GET_OBJECT_NAME);
    DBMS_OUTPUT.PUT_LINE('is tag null: ' || rowlcr.IS_NULL_TAG); 
    DBMS_OUTPUT.PUT_LINE('command_type: ' || rowlcr.GET_COMMAND_TYPE); 
    oldlist := rowlcr.GET_VALUES('old');
    FOR i IN 1..oldlist.COUNT LOOP
      IF oldlist(i) IS NOT NULL THEN
        DBMS_OUTPUT.PUT_LINE('old(' || i || '): ' || oldlist(i).column_name);
        print_any(oldlist(i).data);
      END IF;
    END LOOP;
    newlist := rowlcr.GET_VALUES('new', 'n');
    FOR i in 1..newlist.count LOOP
      IF newlist(i) IS NOT NULL THEN
        DBMS_OUTPUT.PUT_LINE('new(' || i || '): ' || newlist(i).column_name);
        print_any(newlist(i).data);
      END IF;
    END LOOP;
    -- Print extra attributes in row LCR
    ext_attr := rowlcr.GET_EXTRA_ATTRIBUTE('row_id');
      IF (ext_attr IS NOT NULL) THEN
        DBMS_OUTPUT.PUT_LINE('row_id: ' || ext_attr.ACCESSUROWID());
      END IF;
    ext_attr := rowlcr.GET_EXTRA_ATTRIBUTE('serial#');
      IF (ext_attr IS NOT NULL) THEN
        DBMS_OUTPUT.PUT_LINE('serial#: ' || ext_attr.ACCESSNUMBER());
      END IF;
    ext_attr := rowlcr.GET_EXTRA_ATTRIBUTE('session#');
      IF (ext_attr IS NOT NULL) THEN
        DBMS_OUTPUT.PUT_LINE('session#: ' || ext_attr.ACCESSNUMBER());
      END IF; 
    ext_attr := rowlcr.GET_EXTRA_ATTRIBUTE('thread#');
      IF (ext_attr IS NOT NULL) THEN
        DBMS_OUTPUT.PUT_LINE('thread#: ' || ext_attr.ACCESSNUMBER());
      END IF;   
    ext_attr := rowlcr.GET_EXTRA_ATTRIBUTE('tx_name');
      IF (ext_attr IS NOT NULL) THEN
        DBMS_OUTPUT.PUT_LINE('transaction name: ' || ext_attr.ACCESSVARCHAR2());
      END IF;
    ext_attr := rowlcr.GET_EXTRA_ATTRIBUTE('username');
      IF (ext_attr IS NOT NULL) THEN
        DBMS_OUTPUT.PUT_LINE('username: ' || ext_attr.ACCESSVARCHAR2());
      END IF;          
  ELSE
    DBMS_OUTPUT.PUT_LINE('Non-LCR Message with type ' || typenm);
  END IF;
END print_lcr;
/

11.10.4 手順4: エラー・キューにあるすべてのLCRを出力するプロシージャの作成

すべてのエラー・キューに含まれているすべてのLCRを出力するプロシージャを作成します。

このプロシージャでは、手順3: 指定したLCRを出力するプロシージャの作成で作成したprint_lcrプロシージャがコールされます。

CREATE OR REPLACE PROCEDURE print_errors IS
  CURSOR c IS
    SELECT LOCAL_TRANSACTION_ID,
           SOURCE_DATABASE,
           MESSAGE_NUMBER,
           MESSAGE_COUNT,
           ERROR_NUMBER,
           ERROR_MESSAGE
      FROM ALL_APPLY_ERROR
      ORDER BY SOURCE_DATABASE, SOURCE_COMMIT_SCN;
  i      NUMBER;
  txnid  VARCHAR2(30);
  source VARCHAR2(128);
  msgno  NUMBER;
  msgcnt NUMBER;
  errnum NUMBER := 0;
  errno  NUMBER;
  errmsg VARCHAR2(2000);
  lcr    ANYDATA;
  r      NUMBER;
BEGIN
  FOR r IN c LOOP
    errnum := errnum + 1;
    msgcnt := r.MESSAGE_COUNT;
    txnid  := r.LOCAL_TRANSACTION_ID;
    source := r.SOURCE_DATABASE;
    msgno  := r.MESSAGE_NUMBER;
    errno  := r.ERROR_NUMBER;
    errmsg := r.ERROR_MESSAGE;
DBMS_OUTPUT.PUT_LINE('*************************************************');
    DBMS_OUTPUT.PUT_LINE('----- ERROR #' || errnum);
    DBMS_OUTPUT.PUT_LINE('----- Local Transaction ID: ' || txnid);
    DBMS_OUTPUT.PUT_LINE('----- Source Database: ' || source);
    DBMS_OUTPUT.PUT_LINE('----Error in Message: '|| msgno);
    DBMS_OUTPUT.PUT_LINE('----Error Number: '||errno);
    DBMS_OUTPUT.PUT_LINE('----Message Text: '||errmsg);
    FOR i IN 1..msgcnt LOOP
      DBMS_OUTPUT.PUT_LINE('--message: ' || i);
        lcr := DBMS_APPLY_ADM.GET_ERROR_MESSAGE(i, txnid);
        print_lcr(lcr);
    END LOOP;
  END LOOP;
END print_errors;
/

このプロシージャを作成後に実行するには、次のように入力します。

SET SERVEROUTPUT ON SIZE 1000000

EXEC print_errors

11.10.5 手順5: トランザクションに関するすべてのエラーLCRを出力するプロシージャの作成

特定のトランザクションに対するエラー・キューに含まれているすべてのLCRを出力するプロシージャを作成します。

このプロシージャでは、手順3: 指定したLCRを出力するプロシージャの作成で作成したprint_lcrプロシージャがコールされます。

CREATE OR REPLACE PROCEDURE print_transaction(ltxnid IN VARCHAR2) IS
  i      NUMBER;
  txnid  VARCHAR2(30);
  source VARCHAR2(128);
  msgno  NUMBER;
  msgcnt NUMBER;
  errno  NUMBER;
  errmsg VARCHAR2(2000);
  lcr    ANYDATA;
BEGIN
  SELECT LOCAL_TRANSACTION_ID,
         SOURCE_DATABASE,
         MESSAGE_NUMBER,
         MESSAGE_COUNT,
         ERROR_NUMBER,
         ERROR_MESSAGE
      INTO txnid, source, msgno, msgcnt, errno, errmsg
      FROM ALL_APPLY_ERROR
      WHERE LOCAL_TRANSACTION_ID =  ltxnid;
  DBMS_OUTPUT.PUT_LINE('----- Local Transaction ID: ' || txnid);
  DBMS_OUTPUT.PUT_LINE('----- Source Database: ' || source);
  DBMS_OUTPUT.PUT_LINE('----Error in Message: '|| msgno);
  DBMS_OUTPUT.PUT_LINE('----Error Number: '||errno);
  DBMS_OUTPUT.PUT_LINE('----Message Text: '||errmsg);
  FOR i IN 1..msgcnt LOOP
  DBMS_OUTPUT.PUT_LINE('--message: ' || i);
    lcr := DBMS_APPLY_ADM.GET_ERROR_MESSAGE(i, txnid); -- gets the LCR
    print_lcr(lcr);
  END LOOP;
END print_transaction;
/

このプロシージャを作成後に実行するには、このプロシージャにエラー・トランザクションのローカル・トランザクション識別子を渡します。たとえば、ローカル・トランザクション識別子が1.17.2485の場合は、次のように入力します。

SET SERVEROUTPUT ON SIZE 1000000

EXEC print_transaction('1.17.2485')