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

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へのアクセスを許可される資格証明オブジェクトを作成できます)。

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

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

  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認証を使用する必要があります。

    Creating a credential to access Oracle Cloud Infrastructure Object Store is not required if you enable resource principal credentials.詳細は、リソース・プリンシパルを使用した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プロシージャを参照してください。

    Creating a credential to access Oracle Cloud Infrastructure Object Store is not required if you enable resource principal credentials.詳細は、リソース・プリンシパルを使用した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