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

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

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

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

DBMS_PIPEの永続メッセージ:

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

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

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

  • 同じクラウド・オブジェクト・ストアの場所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の説明が続きます
図database-pipe-persistent-messaging.epsの説明

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

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

永続メッセージを使用した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を使用する1つのAutonomous Databaseインスタンスと、WE8MSWIN1252を使用する別のインスタンスがある場合、これら2つのデータベース間でDBMS_PIPEを含むメッセージを送信することはできません。この場合、これらの2つのデータベース間でDBMS_PIPEを含むメッセージを送信しようとすると、エラーORA-12704が発生します。

詳細は、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オブジェクト・ストアにアクセスするための資格証明の作成は必要ありません。詳細は、リソース・プリンシパルを使用した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オブジェクト・ストアにアクセスするための資格証明の作成は必要ありません。詳細は、リソース・プリンシパルを使用した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