クラウド・オブジェクト・ストアに格納されたメッセージでの永続メッセージングの使用

DBMS_PIPEパッケージには、メッセージがクラウド・オブジェクト・ストアに格納される永続メッセージングをサポートするために、Autonomous Databaseの拡張機能があります。

DBMS_PIPEを使用した永続メッセージングについて

DBMS_PIPEを使用した永続メッセージングでは、1つ以上のデータベース・セッションが同じリージョン内またはリージョン間で、クラウド・オブジェクト・ストアに格納されているメッセージと通信できます。

DBMS_PIPEの永続メッセージ:

  • 非常に大きなメッセージを送信および取得できます。

  • 多数のパイプメッセージの送信をサポートします。

  • 1つのデータベース内、複数のデータベース間、および異なるリージョンのデータベース間でのメッセージの送受信をサポートします。

  • 同じクラウド・オブジェクト・ストアの場所URIを使用して複数のパイプをサポートします。

永続メッセージング・パイプは、サポートされている任意のDBMS_PIPEタイプで作成できます。

  • 暗黙的パイプ: DBMS_PIPE.SEND_MESSAGE関数を使用して不明なパイプ名でメッセージを送信すると、自動的に作成されます。
  • 明示的パイプ:ユーザー指定のパイプ名でDBMS_PIPE.CREATE_PIPE関数を使用して作成されます。
  • パブリック・パイプ: DBMS_PIPEパッケージに対するEXECUTE権限を持つすべてのユーザーがアクセスできます。
  • プライベート・パイプ:パイプ作成者と同じユーザーを持つセッションからアクセスできます。
ノート

Oracleでは、永続メッセージングでメッセージを送信または受信する前に、明示的なパイプを作成することをお薦めします。DBMS_PIPE.CREATE_PIPEを使用して明示的なパイプを作成すると、(privateパラメータを設定して)パブリックまたはプライベートのいずれかのアクセス権限でパイプが作成されます。

次に、永続メッセージングを使用するDBMS_PIPEの一般的なワークフローを示します。

database-pipe-persistent-messaging.epsの説明が続きます

DBMS_PIPEを使用する既存のアプリケーションは、最小限の変更で操作を続行できます。DBMS_PIPEを使用する既存のアプリケーションは、ログオン・トリガーを使用するか、他の初期化ルーチンを使用して、資格証明オブジェクトおよび場所URIで構成できます。DBMS_PIPE資格証明および場所URIを設定した後、永続メッセージングを使用するために他の変更は必要ありません。パイプの後続のすべての使用は、データベース・メモリーではなくクラウド・オブジェクト・ストアにメッセージを格納します。これにより、最小限の変更で、インメモリーから永続クラウド・オブジェクト・ストレージにメッセージのストレージ方法を変更できます。

永続メッセージの概要と機能

永続メッセージングを使用するDBMS_PIPEの機能:

  • メッセージは、同じリージョンまたはリージョン間で複数のAutonomous Databaseインスタンス間で送信および取得できます。

  • 永続メッセージは、1つのプロセスによる書込みまたは読取りが保証されます。これにより、同時書込みおよび同時読取りによるメッセージ・コンテンツの不整合が回避されます。永続メッセージング・パイプを使用すると、DBMS_PIPEは1つの操作のみを許可し、メッセージまたは受信メッセージを一度にアクティブに送信します。ただし、進行中の操作のために操作が不可能な場合、timeout値に達するまで、プロセスは定期的に再試行します。

  • DBMS_PIPEは、DBMS_CLOUDを使用してクラウド・オブジェクト・ストアにアクセスします。メッセージは、サポートされている任意のクラウド・オブジェクト・ストアに格納できます。詳細は、DBMS_CLOUD URI形式を参照してください。

  • DBMS_PIPEは、DBMS_CLOUDを使用してクラウド・オブジェクト・ストアにアクセスし、サポートされているすべての資格証明タイプを使用できます:

DBMS_PIPE権限の認可とセキュリティ

DBMS_PIPEプロシージャは、実行者権限で実行されます。プライベートパイプは現在のユーザーが所有し、ユーザーが作成したプライベートパイプは、同じユーザーのみが使用できます。これは、クラウド・オブジェクト・ストアにメッセージが格納されるインメモリー・パイプと永続メッセージング・パイプの両方に適用されます。メッセージの送信と受信は、実行者のスキーマで実行されます。

メッセージがクラウド・オブジェクト・ストアに格納されるプライベート・パイプを使用すると、location_uriパラメータで識別されるクラウド・オブジェクト・ストアでの認証に資格証明オブジェクトが必要です。起動するユーザーは、オブジェクト・ストアへのアクセスに使用されるcredential_nameパラメータで指定された資格証明オブジェクトに対するEXECUTE権限を持っている必要があります。

パブリック・パイプを使用するには、ユーザー、データベース・セッションにDBMS_PIPEに対する実行権限が必要です。永続メッセージを使用し、クラウド・オブジェクト・ストアにメッセージを格納するパブリック・パイプの場合、ユーザー、データベース・セッションには、DBMS_CLOUDに対する実行権限と、資格証明オブジェクトに対する実行権限が必要です(または、メッセージを含む場所URIへのアクセスを許可される資格証明オブジェクトを作成できます)。

DBMS_PIPEの制限

DBMS_PIPEパッケージでは、異なる文字セットを使用するデータベース間でのメッセージの送信はサポートされていません。たとえば、AL32UTF8を使用するAutonomous Databaseインスタンスと、WE8MSWIN1252を使用する別のインスタンスがある場合、これら2つのデータベース間でDBMS_PIPEを含むメッセージを送信することはできません。この場合、これらの2つのデータベース間でDBMS_PIPEのメッセージを送信しようとすると、エラーORA-12704が発生します。

詳細については、Choose a Character Set for Autonomous Databaseを参照してください。

明示的な永続パイプの作成およびメッセージの送信

指定されたパイプ名(明示パイプ)で永続的なパイプを作成する手順について説明します。

  1. プロシージャDBMS_CLOUD.CREATE_CREDENTIALを使用してオブジェクト・ストアの資格証明を保存します。例:
    BEGIN
      DBMS_CLOUD.CREATE_CREDENTIAL(
        credential_name => 'my_persistent_pipe_cred',
        username => 'adb_user@example.com',
        password => 'password'
      );
    END;
    /

    この操作によって、資格証明が暗号化された形式でデータベースに格納されます。資格証明には任意の名前を使用できます。オブジェクト・ストアの資格証明を変更しないかぎり、このステップが必要なのは1回のみです。資格証明を格納した後、同じ資格証明名を使用してクラウド・オブジェクト・ストアにアクセスし、DBMS_PIPEを使用してメッセージを送受信できます。

    パラメータの詳細は、CREATE_CREDENTIALプロシージャを参照してください。Oracle Cloud Infrastructure Object Storageの場合、資格証明はネイティブOracle Cloud Infrastructure認証を使用する必要があります。

    リソース・プリンシパル資格証明を有効にする場合、Oracle Cloud Infrastructure Object Storeにアクセスするための資格証明を作成する必要はありません。詳細は、リソース・プリンシパルを使用したOracle Cloud Infrastructureリソースへのアクセスを参照してください。

    ノート

    SQL*PlusやSQL Developerなどの一部のツールは、特殊文字としてアンパサンド文字(&)を使用します。パスワードにアンパサンド文字が含まれる場合、例に示すように、これらのツールでSET DEFINE OFFコマンドを使用して特殊文字を無効にし、資格証明を適切に作成します。
  2. メッセージを送受信する明示的なパイプを作成します。たとえば、ORDER_PIPEという名前のパイプを作成します。
    DECLARE
      r_status INTEGER;
    BEGIN
        r_status := DBMS_PIPE.CREATE_PIPE(pipename => 'ORDER_PIPE');
    END;
    /

    詳細は、CREATE_PIPEファンクションを参照してください。

  3. パイプが作成されていることを確認します。
    SELECT ownerid, name, type FROM v$db_pipes 
           WHERE name = 'ORDER_PIPE';
    OWNERID NAME       TYPE    
    ------- ---------- ------- 
         80 ORDER_PIPE PRIVATE 
  4. DBMS_PIPEプロシージャを使用して、デフォルトのアクセス資格証明およびロケーションURIを設定し、永続メッセージをクラウド・オブジェクト・ストアに格納します。
    BEGIN
        DBMS_PIPE.SET_CREDENTIAL_NAME('my_persistent_pipe_cred');
        DBMS_PIPE.SET_LOCATION_URI('https://objectstorage.us-phoenix-1.oraclecloud.com/n/namespace-string/b/bucketname1/'); 
    END;
    /

    これらのプロシージャは、DBMS_PIPEプロシージャで使用するデフォルトの資格証明名およびデフォルトの場所URIを設定します。

    Oracle Cloud Infrastructure Object Storageを使用してメッセージを格納する場合は、Oracle Cloud InfrastructureネイティブURIまたはSwift URIを使用できます。ただし、ロケーションURIと資格証明は、次のようにタイプで一致する必要があります。

    • ネイティブURI形式を使用してOracle Cloud Infrastructure Object Storageにアクセスする場合は、資格証明オブジェクトでネイティブのOracle Cloud Infrastructure署名キー認証を使用する必要があります。

    • Swift URI形式を使用してOracle Cloud Infrastructure Object Storageにアクセスする場合は、資格証明オブジェクトで認証トークン認証を使用する必要があります。

    詳細は、SET_CREDENTIAL_NAMEプロシージャおよびSET_LOCATION_URIプロシージャを参照してください。

  5. パイプにメッセージを送ります。
    DECLARE
      l_result INTEGER;
      l_date   DATE;
    BEGIN
        l_date := sysdate;
        DBMS_PIPE.PACK_MESSAGE(l_date);         -- date of order
        DBMS_PIPE.PACK_MESSAGE('C123');         -- order number
        DBMS_PIPE.PACK_MESSAGE(5);              -- number of items in order
        DBMS_PIPE.PACK_MESSAGE('Printers');     -- type of item in order
    
     
        l_result := DBMS_PIPE.SEND_MESSAGE(
                        pipename => 'ORDER_PIPE',
                        credential_name => DBMS_PIPE.GET_CREDENTIAL_NAME,
                        location_uri => DBMS_PIPE.GET_LOCATION_URI);
         
        IF l_result = 0 THEN
            DBMS_OUTPUT.put_line('DBMS_PIPE sent order successfully');
        END IF;
     
    END;
    /

    詳細は、PACK_MESSAGEプロシージャおよびSEND_MESSAGEファンクションを参照してください。

同じデータベースでの永続メッセージの取得

同じAutonomous Databaseインスタンス(メッセージが送信されたインスタンス)上の明示的なパイプから永続メッセージを取得するステップについて説明します。

Autonomous Databaseインスタンスでは、別のセッションからパイプに送信されたメッセージを受信できます。DBMS_PIPEプロシージャは、実行者権限プロシージャであり、現在起動されているユーザーとして実行されます。

プライベートパイプは、パイプを作成する現在のユーザーが所有します。プライベートパイプには、パイプを作成したユーザーと同じユーザーしかアクセスできません。これは、インメモリー・メッセージを使用するパイプ、およびクラウド・オブジェクト・ストアに格納されているメッセージを含む永続メッセージを使用するパイプに適用されます。

パブリック・パイプには、DBMS_PIPEに対する実行権限を持つデータベース・セッションからアクセスできます。これは、インメモリー・メッセージを使用するパイプ、およびクラウド・オブジェクト・ストアに格納されているメッセージを含む永続メッセージを使用するパイプに適用されます。

  1. パイプが作成されていることを確認します。
    SELECT ownerid, name, type FROM v$db_pipes 
           WHERE name = 'ORDER_PIPE';
    
    OWNERID NAME       TYPE    
    ------- ---------- ------- 
         80 ORDER_PIPE PRIVATE 

    同じAutonomous Databaseインスタンス上にパイプが存在する場合、メッセージを受信する前にDBMS_PIPE.CREATE_PIPEを実行する必要はありません。これは、Create an Explicit Persistent Pipe and Send a Messageに示すように、パイプが同じインスタンスに作成された場合に適用されます。

  2. パイプからメッセージを受信します。
    DECLARE
        message1  DATE;
        message2  VARCHAR2(100);
        message3  INTEGER;
        message4  VARCHAR2(100);
        l_result  INTEGER;
    
    BEGIN
    
        DBMS_PIPE.SET_CREDENTIAL_NAME('my_persistent_pipe_cred');
        DBMS_PIPE.SET_LOCATION_URI('https://objectstorage.us-phoenix-1.oraclecloud.com/n/namespace-string/b/bucketname1/'); 
        l_result := DBMS_PIPE.RECEIVE_MESSAGE (
                      pipename => 'ORDER_PIPE',
                      timeout  => DBMS_PIPE.MAXWAIT,
                      credential_name => DBMS_PIPE.GET_CREDENTIAL_NAME,
                      location_uri => DBMS_PIPE.GET_LOCATION_URI);
     
        IF l_result = 0 THEN
            DBMS_PIPE.unpack_message(message1);
            DBMS_PIPE.unpack_message(message2);
            DBMS_PIPE.unpack_message(message3);
            DBMS_PIPE.unpack_message(message4);
     
            DBMS_OUTPUT.put_line('Order Received Successfully On: ' || TO_CHAR(sysdate, 'dd-mm-yyyy hh24:mi:ss'));
            DBMS_OUTPUT.put_line('Date of Order: ' || message1);
            DBMS_OUTPUT.put_line('Order Number: ' || message2);
            DBMS_OUTPUT.put_line('Number of Items In Order: ' || message3);
            DBMS_OUTPUT.put_line('Item Type in Order: ' || message4);
        END IF;
     
    END;
    /

    同じAutonomous Databaseインスタンス上にある場合、資格証明はすでに存在するため、メッセージを受信するためにDBMS_CLOUD.CREATE_CREDENTIALを実行する必要はありません。これは、Create an Explicit Persistent Pipe and Send a Messageに示すように、パイプが同じインスタンスに作成された場合に適用されます。

詳細は、SET_CREDENTIAL_NAMEプロシージャおよびSET_LOCATION_URIプロシージャを参照してください。

詳細は、RECEIVE_MESSAGEファンクションを参照してください。

別のデータベースでのパイプの作成による永続メッセージの取得

メッセージを送信したインスタンスとは異なるAutonomous Databaseインスタンス上の明示的なパイプを使用して、クラウド・オブジェクト・ストアに格納されている永続メッセージを取得するステップについて説明します。

  1. プロシージャDBMS_CLOUD.CREATE_CREDENTIALを使用してオブジェクト・ストアの資格証明を保存します。たとえば:
    BEGIN
      DBMS_CLOUD.CREATE_CREDENTIAL(
        credential_name => 'my_persistent_pipe_cred',
        username => 'adb_user@example.com',
        password => 'password'
      );
    END;
    /

    この操作によって、資格証明が暗号化された形式でデータベースに格納されます。資格証明には任意の名前を使用できます。オブジェクト・ストアの資格証明を変更しないかぎり、このステップが必要なのは1回のみです。資格証明を一度格納したら、同じ資格証明名を使用してクラウド・オブジェクト・ストアにアクセスし、DBMS_PIPEでメッセージを送受信できます。

    パラメータの詳細は、CREATE_CREDENTIALプロシージャを参照してください。

    リソース・プリンシパル資格証明を有効にする場合、Oracle Cloud Infrastructure Object Storeにアクセスするための資格証明を作成する必要はありません。詳細は、リソース・プリンシパルを使用したOracle Cloud Infrastructureリソースへのアクセスを参照してください。

    ノート

    SQL*PlusやSQL Developerなどの一部のツールは、特殊文字としてアンパサンド文字(&)を使用します。パスワードにアンパサンド文字が含まれる場合、例に示すように、これらのツールでSET DEFINE OFFコマンドを使用して特殊文字を無効にし、資格証明を適切に作成します。
  2. メッセージを送信したパイプと同じ名前の明示的なパイプを作成します。たとえば、ORDER_PIPEという名前のパイプを作成します。
    DECLARE
      r_status INTEGER;
    BEGIN
        r_status := DBMS_PIPE.CREATE_PIPE(pipename => 'ORDER_PIPE');
    END;
    /

    CREATE_PIPEファンクションを参照してください。

  3. パイプが作成されていることを確認します。
    SELECT ownerid, name, type FROM v$db_pipes 
           WHERE name = 'ORDER_PIPE';
    
    OWNERID NAME       TYPE    
    ------- ---------- ------- 
         80 ORDER_PIPE PRIVATE 
  4. DBMS_PIPEプロシージャを使用して、DBMS_PIPEが永続メッセージにアクセスできるように、オブジェクト・ストアのデフォルトのアクセス資格証明および場所URIを設定します。
    BEGIN
        DBMS_PIPE.SET_CREDENTIAL_NAME('my_persistent_pipe_cred');
        DBMS_PIPE.SET_LOCATION_URI('https://objectstorage.us-phoenix-1.oraclecloud.com/n/namespace-string/b/bucketname1/'); 
    END;
    /

    これらのプロシージャは、DBMS_PIPEプロシージャで使用するデフォルトの資格証明名およびデフォルトの場所URIを設定します。

    Oracle Cloud Infrastructure Object Storageを使用してメッセージを格納する場合は、Oracle Cloud InfrastructureネイティブURIまたはSwift URIを使用できます。ただし、ロケーションURIと資格証明は、次のようにタイプで一致する必要があります。

    • ネイティブURI形式を使用してOracle Cloud Infrastructure Object Storageにアクセスする場合は、資格証明オブジェクトでネイティブのOracle Cloud Infrastructure署名キー認証を使用する必要があります。

    • Swift URI形式を使用してOracle Cloud Infrastructure Object Storageにアクセスする場合は、資格証明オブジェクトで認証トークン認証を使用する必要があります。

    詳細は、SET_CREDENTIAL_NAMEプロシージャおよびSET_LOCATION_URIプロシージャを参照してください。

  5. 永続パイプからメッセージを受信します。
    DECLARE
        message1  DATE;
        message2  VARCHAR2(100);
        message3  INTEGER;
        message4  VARCHAR2(100);
        l_result  INTEGER;
    
    BEGIN
    
        DBMS_PIPE.SET_CREDENTIAL_NAME('my_persistent_pipe_cred');
        DBMS_PIPE.SET_LOCATION_URI('https://objectstorage.us-phoenix-1.oraclecloud.com/n/namespace-string/b/bucketname1/'); 
        l_result := DBMS_PIPE.RECEIVE_MESSAGE (
                      pipename => 'ORDER_PIPE',
                      timeout  => DBMS_PIPE.MAXWAIT,
                      credential_name => DBMS_PIPE.GET_CREDENTIAL_NAME,
                      location_uri => DBMS_PIPE.GET_LOCATION_URI);
     
        IF l_result = 0 THEN
            DBMS_PIPE.unpack_message(message1);
            DBMS_PIPE.unpack_message(message2);
            DBMS_PIPE.unpack_message(message3);
            DBMS_PIPE.unpack_message(message4);
     
            DBMS_OUTPUT.put_line('Order Received Successfully On: ' || TO_CHAR(sysdate, 'dd-mm-yyyy hh24:mi:ss'));
            DBMS_OUTPUT.put_line('Date of Order: ' || message1);
            DBMS_OUTPUT.put_line('Order Number: ' || message2);
            DBMS_OUTPUT.put_line('Number of Items In Order: ' || message3);
            DBMS_OUTPUT.put_line('Item Type in Order: ' || message4);
        END IF;
     
    END;
    /

    詳細は、RECEIVE_MESSAGEファンクションを参照してください。

永続的なパイプを削除する

永続的なパイプを取り外す手順について説明します。

永続パイプは、メッセージをクラウド・オブジェクト・ストアに格納して、メッセージを送受信します。DBMS_PIPE.REMOVE_PIPEを使用して、Autonomous Databaseインスタンス上の永続パイプを削除します。

  1. DBMS_PIPE.REMOVE_PIPE関数をコールしてパイプを削除します。
    DECLARE
       l_result  INTEGER;
    BEGIN
         l_result := DBMS_PIPE.REMOVE_PIPE('ORDER_PIPE');
    END;
    /

    REMOVE_PIPE関数は、実行されているAutonomous Databaseインスタンスからパイプを削除しますが、REMOVE_PIPEは、同じ場所URIを使用する同じ名前のパイプを持つ他のAutonomous Databaseインスタンスには影響しません。

  2. Autonomous DatabaseインスタンスでDBMS_PIPE.REMOVE_PIPEを実行し、パイプが削除されていることを確認します。
    SELECT ownerid, name, type FROM v$db_pipes 
           WHERE name = 'ORDER_PIPE';
    
    No rows selected