データ主権のユースケース

架空の大手金融機関であるShard Bankは、複数の国でユーザーにクレジット・サービスを提供しようとしています。クレジット・サービスが提供される各国には独自のデータ・プライバシ規制があり、個人を特定できる情報(PII)データを当該国に保存する必要があります。

データへのアクセスを制限する必要があり、ある国のデータ管理者は他の国のデータを表示できません。このユースケースのソリューションは、様々な国でシャードが構成されたユーザー定義のシャーディングと、データ・アクセス制御のためのReal Application Security (RAS)または仮想プライベート・データベース(VPD)です。

データ主権ソリューションの概要

このデータ主権ソリューションは、国内のデータ記憶域を提供し、すべてのデータのグローバル・ビューもサポートしています。

次の例は、複数のリージョンにまたがるOCIデータ・センターとオンプレミス間のハイブリッドOracle Globally Distributed Databaseユーザー定義デプロイを示しています。この構成では、すべてのデータをローカルに保存および処理できます。各データベース(各主権リージョン内)はシャードになり、シャードは単一の分散データベースに属します。Oracle Globally Distributed Databaseでは、1つのシャード(1か国)のデータを問い合せることができます。Oracle Globally Distributed Databaseでは、(すべての国からデータを問合せできる)マルチシャード問合せがサポートされています。

図16-2 分散データベース



グローバル分散データベースは、そのデータベースが存在する必要がある国を示すキーによってパーティション化されます。国内のアプリケーションは通常どおりローカル・データベースに接続し、すべてのデータはローカルに保存および処理されます。

マルチシャード問合せは、シャード・コーディネータに転送されます。コーディネータは問合せをリライトし、必要なデータがある各シャード(国)に送信します。コーディネータは、すべての国からの結果を処理して集計し、結果を返します。

Oracle Globally Distributed Databaseでは、次の機能でこのユースケースが可能になります。

  • 国内の問合せのシャードへの直接ルーティング。
  • ユーザー定義のシャーディング方法により、国の範囲またはリストを使用して、シャード間でデータをパーティション化できます。
  • Oracle Active Data Guardを使用してレプリケーションを自動構成し、レプリカを国内に制限します。
  • 既存のデータベースを分散データベースに変換および追加するためのデータ・フェデレーション・サポート(Oracle Database 21c以降)。詳細は、フェデレーテッド分散データベースの作成を参照してください。
  • シャーディング・キーの自動導出(Oracle Database 21c以降)。

この方法のメリットは次のとおりです。

  • 各シャードは、国内のクラウドまたはオンプレミスに配置できます。
  • シャードは様々なクラウド・プロバイダを使用でき(マルチクラウド戦略)、シャードのレプリカを異なるクラウドまたはオンプレミスに配置できます。
  • オンライン再シャーディングにより、クラウド間、またはクラウドとオンプレミスとの間でデータを移動できます。
  • データ主権の厳格な施行により、不注意によるリージョンをまたいだデータ漏えいを防止します。
  • データの重複を低減した単一のマルチモデル・ビッグ・データ・ストア。
  • 1つのリージョン/LOB内の計画/計画外停止時間が他のリージョン/LOBに影響しないため、より優れた障害分離が実現します。
  • ビジー状態のパーティションとシャードを必要に応じて分割できます。
  • 完全なACIDプロパティのサポートは、トランザクション・アプリケーションにとって重要です。

データ主権のデプロイ・トポロジ

このユースケースの例では、フランクフルト(Region1 FRA)、アムステルダム(リージョン2 AMS)、およびロンドン(リージョン3 LON)の3つのリージョンにまたがるOracle Cloud Infrastructureに分散データベースを作成します。

各リージョンは、シャード・ディレクタ(仮想マシン・グローバル・サービス・マネージャ(GSM))と1つのシャード(それぞれシステム・データベース・シャード1、2および3)をホストし、リージョン1 (FRA)はシャード・カタログ(システム・データベースGSMカタログ・データベース)をホストします。

図16-3 データ主権のデプロイ・トポロジ



データ主権ユース・ケースの構成

次のトピックのステップを実行して、Oracle Globally Distributed Databaseデータ主権ユース・ケースを構成します。

3つのOCIリージョンすべてにおけるVCNネットワークの構成

Oracle Cloud Infrastructure (OCI)では、仮想クラウド・ネットワークは、インスタンスが実行される従来のネットワークの仮想バージョンです。各リージョン(FRA、AMSおよびLON)に仮想クラウド・ネットワーク(VCN)をデプロイして構成します。

各リージョンで、パブリックとプライベートの2つのサブネットを持つVCNを作成します。
  1. プライベート・サブネットの新しいルート表を作成し、プライベート・サブネットに関連付けます。デフォルトのルート表はパブリック・サブネットにのみ使用し、プライベート・サブネットには専用のプライベート・ルート表を設定することが適切です。
  2. インターネット・ゲートウェイを作成し、デフォルトのルート表に関連付けます。
  3. ネットワーク・アドレス変換(NAT)ゲートウェイであるサービス・ゲートウェイを作成し、プライベート・サブネットのルート表に関連付けます。
FRAの例:
  • VCN名/CIDER: シャーディングVCN FRA 10.0.0.0/16
  • パブリック・サブネット名/CIDER: public_fra 10.0.5.0/24
  • プライベート・サブネット名/CIDER: private_fra 10.0.6.0/24

ノート:

シャーディング・デプロイメントで使用されるすべてのリージョンでステップを繰り返します。サブネットCIDERは各リージョンで異なる必要があり、VCN/サブネット名にリージョン接頭辞を指定する必要があります。

3つのリージョン間のリモートVCNピアリングの構成

リモートVCNピアリングは、異なるリージョンにある2つのVCNを接続することで、トラフィックをインターネット経由でルーティングすることなく、プライベートIPアドレスを使用してVCNのリソースが通信できるようにするプロセスです。

トポロジ内の他の2つのリージョンに接続するために、各リージョンに2つのリモート・ピアリング接続(RPC)を構成します。
  1. RPCを構成するステップについては、RPCを使用したリモートVCNピアリングに関する項を参照してください。
  2. パブリック・サブネット/VCNのルーティング・ルールを構成します。
  3. プライベート・サブネット/VCNのルーティング・ルールを構成します。
  4. セキュリティ・ルールを構成します。
たとえば、リージョン1 (FRA)では次のようになります。

リージョン間のネーミング解決のためのプライベートDNSの構成

各リージョンのドメインごとにパブリック・サブネットとプライベート・サブネットのプライベート・ビューを作成し、1つのゾーン内に合計6つのプライベート・ゾーンを作成します。その後、すべてのエントリが各プライベート・ゾーン構成に追加されます。

  1. プライベートDNSゾーンを作成および管理するには、プライベートDNSに関する項を参照してください。
  2. 次のタスクに進む前に、すべての名前が正しく解決されていることを確認します。

ノート:

これらの手順は、名前を正しく解決できるように、すべてのVCN/VMの各リージョンで実行する必要があります。

各リージョンへのグローバル・サービス・マネージャのインストール

Oracle Global Data Servicesグローバル・サービス・マネージャ(GSM)は、Oracle Globally Distributed Databaseによって、アプリケーションから分散データベース内の正しいシャードに問合せをルーティングするために使用されます。

ソフトウェアをダウンロードし、次のタスクを実行します。
  • グローバル・サービス・マネージャ(Oracle Database 19c)ソフトウェアを要塞VMにダウンロードします。
  • 最新バージョンのOPatchを適用します。
  • 新しくインストールされたグローバル・サービス・マネージャ(Oracle Database 19c)に、利用可能な最新のOracle Databaseバンドル・パッチを適用します。
各リージョンにGSMをインストールするには:
  1. iSCSIを使用して200 GBのブロック・ストレージを作成します。GSM用OCIコンピュートでiSCSIを構成します。ブロック・ストレージを/u01にマウントします。
    ブロック・ストレージのマウント・プロセスについては、一貫性のあるデバイス・パスを使用したボリュームへの接続に関する項を参照してください。
  2. rootユーザーとして、必要なすべてのパッケージをインストールします。
    # yum install -y oracle-database-preinstall-19c
  3. rootユーザーとして、/u01oracle:oinstallによって所有されていることを確認します。
    # chown oracle:oinstall /u01
  4. GSMソフトウェアを指定されたシャード・ディレクタVMにダウンロードし、サイレント・モードでインストールします。
  5. gsm home/etc/oratabに追加します。
    gsm:/u01/app/oracle/product/19.0.0.0/dbhome_1:N
  6. 最新のOPatchバージョンを適用します。
  7. Oracle Database 19cに利用可能な最新のバンドル・パッチ・バージョンを適用します。
  8. ファイアウォールでGSMポートを開きます。
    $ systemctl start firewalld.service
    $ systemctl enable firewalld.service
    $ firewall-cmd --permanent --zone=public --add-port=1522/tcp # firewall-cmd --reload
    $ firewall-cmd --permanent --zone=public --list-ports
    1522/tcp 22/tcp 
    
  9. アプリケーションがGSMに接続できるように、GSM VMに割り当てられたセキュリティ・リストで必要なポートが開いていることを確認します。

シャード・カタログおよびシャードのTNSエントリの収集

シャード・カタログ・データベースおよびシャード・データベースの構成用にGSMサーバーを準備するには、TNSエントリのコレクションが必要です。

シャード・カタログ・データベースは、シャード・カタログ・データベース・オブジェクトを格納するPDBにのみアクセスする必要があります。ただし、シャード・データベースには、アプリケーション・スキーマを格納する各シャードCDBおよびPDBのエントリを準備します。

  1. シャード・カタログ・データベースおよびすべてのシャード(シャード・カタログとシャード)にアクセスするためのtnsnamesエントリを準備します。
  2. これらのエントリをGSM VMの$ORACLE_HOME/network/admin/tnsnames.oraに追加します。

    ノート:

    接続文字列のホスト名にはFQDNを使用します。
    db_unique_name =
      (DESCRIPTION =
        (ADDRESS = (PROTOCOL = TCP)(HOST = host_name_fqdn)(PORT = 1521))
        (CONNECT_DATA =
          (SERVER = DEDICATED)
          (SERVICE_NAME = cdb_service_name)
        )
      )
    
    pdb_name =
      (DESCRIPTION =
        (ADDRESS = (PROTOCOL = TCP)(HOST = host_name_fqdn)(PORT = 1521))
        (CONNECT_DATA =
          (SERVER = DEDICATED)
          (SERVICE_NAME = pdb_service_name)
        )
      )
    

シャード・カタログの構成

シャード・カタログは、Oracle Globally Distributed Databaseのメタデータを管理します。シャード・カタログ・データベースとなるリージョン1 (FRA)でデータベースを構成します。

  1. すべてのDBCSインスタンスに接続し、sqlnet.oraファイルに構成されているsqlnet暗号化アルゴリズムを更新し、クライアントおよびサーバーでサポートされるアルゴリズムとしてRC4_256暗号化方法を追加します。

    ノート:

    AES暗号化はGSM: Enh 29496977 - GDS ONLY USES RC4_256 TYPE ENCRYPTIONではデフォルトではサポートされていないため、AES暗号化を有効にするためにパッチが必要です。AES暗号化を有効にするには、Oracle Database 19cでパッチを適用します。ただし、このパッチはOracle Database 21cでは必要ありません。

    ノート:

    RC4_256アルゴリズムは、Oracle Database 19cでのみ必要です。
  2. Oracle Globally Distributed Databaseの要件を使用して、シャード・カタログ・データベースを構成します。
    SQL> alter system set open_links=16 scope=spfile;
    SQL> alter system set open_links_per_instance=16 scope=spfile;
    SQL> shu immediate
    SQL> startup
    
  3. シャード・カタログ・データベースでユーザーを構成します。
    SQL> alter user gsmcatuser account unlock.
    SQL> alter user gsmcatuser identified by password;
    # Switch to PDB dedicated for catalog database
    SQL> alter session set container=catalog_db_pdb;
    SQL> create user mysdbadmin identified by password;
    SQL> grant connect, create session, gsmadmin_role to mysdbadmin; 
    SQL> grant inherit privileges on user SYS to GSMADMIN_INTERNAL;
    

シャード・データベースの構成

各リージョンに、分散データベース構成でシャードになるデータベースを構成します。

  1. すべてのDBCSインスタンスに接続し、sqlnet.oraファイルに構成されているsqlnet暗号化アルゴリズムを更新し、クライアントおよびサーバーでサポートされるアルゴリズムとしてRC4_256暗号化方法を追加します。

    ノート:

    AES暗号化はGSM: Enh 29496977 - GDS ONLY USES RC4_256 TYPE ENCRYPTIONではデフォルトではサポートされていないため、AES暗号化を有効にするためにパッチが必要です。AES暗号化を有効にするには、Oracle Database 19cでパッチを適用します。ただし、このパッチはOracle Database 21cでは必要ありません。

    ノート:

    RC4_256アルゴリズムは、Oracle Database 19cでのみ必要です。
  2. 次のコマンドを実行します。
    SQL> alter database flashback on;
    SQL> alter system set dg_broker_start=true;
    SQL> alter user GSMROOTUSER account unlock;
    SQL> alter user GSMUSER account unlock;
    SQL> alter user GSMADMIN_INTERNAL account unlock;
    SQL> alter user GSMROOTUSER identified by password;
    SQL> alter user GSMUSER identified by password;
    SQL> alter user GSMADMIN_INTERNAL identified by password;
    SQL> grant sysdg to gsmuser;
    SQL> grant SYSBACKUP to gsmuser;
    SQL> grant sysdg to GSMROOTUSER;
    SQL> grant SYSBACKUP to GSMROOTUSER;
    SQL> alter system set global_names=false;
    SQL> shu immediate
    SQL> startup
    # Switch to PDB used as shared database
    SQL> alter session set container= pdb_name;
    SQL> grant read,write on directory DATA_PUMP_DIR to GSMADMIN_INTERNAL;
    SQL> grant sysdg to gsmuser;
    SQL> grant SYSBACKUP to gsmuser;
    

Oracle Globally Distributed Databaseの作成

グローバル・サービス・マネージャ・リスナーを構成し、シャード・カタログ・データベースを作成して、すべてのシャードを構成に追加します。デプロイメント・ステップでは、すべてのシャードを単一のグローバル・データベースとして構成します。

  1. シャード・カタログを構成します。

    ノート:

    デフォルトでは、システム管理のデータ分散が構成されています。他のデータ分散方法が必要な場合は、シャード・カタログの作成時に指定します。
    GDSCTL> create shardcatalog -database catalog_pdb_tns_entry -sharding user -user
          mysdbadmin/password -region region1
  2. GSMリスナーを追加して起動します。GDSCTLからリスナーを実行します。
    GDSCTL> add gsm -gsm sharddirector1 -listener 1522 -pwd password -catalog pdb_tns_entry
          -region region1
  3. 次のテンプレートを使用して、構成にシャードを追加します。シャード・データベースごとに繰り返します。

    FRAでシャードを追加します。

    GDSCTL> add invitednode shard_hostname
    GDSCTL> add cdb -connect cdb_conn_tns_entry -pwd gsmrootuser_pwd
    GDSCTL> add shardspace -shardspace primary_shardspace_fra
    GDSCTL> add shard -cdb cdb_conn_string -connect pdb_conn_string
     -shardspace primary_shardspace_fra -pwd gsmuser_pwd -deploy_as PRIMARY

    AMSでシャードを追加します。

    GDSCTL> add invitednode shard_hostname
    GDSCTL> add cdb -connect cdb_conn_tns_entry -pwd gsmrootuser_pwd
    GDSCTL> add shardspace -shardspace primary_shardspace_ams
    GDSCTL> add shard -cdb cdb_conn_string -connect pdb_conn_string
     -shardspace primary_shardspace_ams -pwd gsmuser_pwd -deploy_as PRIMARY

    LONでシャードを追加します。

    GDSCTL> add invitednode shard_hostname
    GDSCTL> add cdb -connect cdb_conn_tns_entry -pwd gsmrootuser_pwd
    GDSCTL> add shardspace -shardspace primary_shardspace_lon
    GDSCTL> add shard -cdb cdb_conn_string -connect pdb_conn_string
     -shardspace primary_shardspace_lon -pwd gsmuser_pwd -deploy_as PRIMARY
  4. 分散データベース構成をデプロイします。
    GDSCTL DEPLOYコマンドを実行して、次の出力を取得します。
    GDSCTL> deploy
    deploy: examining configuration...
    deploy: requesting Data Guard configuration on shards via GSM
    deploy: shards configured successfully
    The operation completed successfully
    
  5. アプリケーションからの着信接続リクエストを処理するために、シャードでグローバル・データベース・サービスを作成します。グローバル・サービスは、従来のデータベース・サービスの拡張です。グローバル・サービスでは、従来のサービスのすべてのプロパティがサポートされます。分散データベースの場合、グローバル・サービスに追加のプロパティが設定されます。「グローバル・データベース・サービスの作成と開始」を参照してください。
    たとえば、データベース・ロール、レプリケーション・ラグの許容範囲、クライアントとシャードの間のリージョン・アフィニティなどです。読取り/書込みトランザクション・ワークロードの場合は、分散データベースのプライマリ・シャードのデータにアクセスするために、単一のグローバル・サービスを作成します。Active Data Guardを使用した高可用性シャードの場合は、個別の読取り専用グローバル・サービスを作成します。
    GDSCTL> add service -service oltp_rw_srvc -role primary
「シャード・データベースへの移行」で説明されている方法を使用して、データをシャードにロードします

セッション・ベースのアプリケーション・コンテキスト・ポリシーの実装

単一のシャード問合せとマルチシャード問合せの両方に対して、Oracle Database仮想プライベート・データベース(VPD)機能と組み合せて、分散データベースに行レベルのデータ・アクセス制御を追加します。Oracle Global Data Servicesグローバル・サービス・マネージャ(GSM)は、Oracle Globally Distributed Databaseで、アプリケーションから分散データベース内の正しいシャードに問合せをルーティングするために使用されます。

  1. シャード・カタログにユーザー・アカウントとサンプル表を作成します。
    connect / as sysdba
    alter session enable shard ddl;
    create user bt identified by bt;
    grant dba, all privileges to bt;
    
    --CREATE USER sysadmin_vpd IDENTIFIED BY password CONTAINER = CURRENT;
    CREATE USER sysadmin_vpd IDENTIFIED BY password ; --CONTAINER = CURRENT;
    
    GRANT CREATE SESSION, CREATE ANY CONTEXT, CREATE PROCEDURE, CREATE TRIGGER, ADMINISTER DATABASE TRIGGER, ALTER SESSION TO sysadmin_vpd;
    GRANT EXECUTE ON DBMS_SESSION TO sysadmin_vpd;
    GRANT EXECUTE ON DBMS_RLS TO sysadmin_vpd;
    
    CREATE USER CT identified by ct;
    CREATE USER DT identified by dt;
    GRANT CREATE SESSION TO CT, DT;
    
    GRANT EXECUTE ON sys.exec_shard_plsql to bt, ct, dt, sysadmin_vpd;
    
    connect bt/bt
    create tablespace set ts1 in shardspace shd1;
    CREATE SHARDED TABLE customers (custid number, name varchar2(20), constraint pk1 primary key(custid)) PARTITION BY CONSISTENT HASH(custid) PARTITIONS AUTO TABLESPACE SET ts1;
    -- user-defined:
    -- CREATE SHARDED TABLE customers (custid number primary key, name varchar2(20)) PARTITION BY RANGE (custid) (PARTITION p1 values less than (100) TABLESPACE  ts1, PARTITION p2 values less than(200) TABLESPACE  ts2, PARTITION p3 values less than(300) TABLESPACE  ts11, PARTITION p4 values less than(400) TABLESPACE  ts12);
    
    insert into customers(custid, name) values(1,'CT');
    insert into customers(custid, name) values(2,'DT');
    insert into customers(custid, name) values(4,'ET');
    insert into customers(custid, name) values(5,'FT');
    commit;
    
    GRANT READ ON customers TO sysadmin_vpd;
    
    create sharded table orders(oid number not null, custid number not null, constraint ordfk foreign key(custid) references customers(custid)) partition by reference(ordfk);
    -- user-defined:
    -- CREATE SHARDED TABLE orders(oid number not null, custid number not null, constraint orders_fk1 foreign key(custid) references customers(custid)) partition by reference(orders_fk1);
    
    insert into orders values(9876, 1);
    insert into orders values(8888, 2);
    insert into orders values(7777, 2);
    insert into orders values(7771, 4);
    insert into orders values(7772, 4);
    insert into orders values(7773, 5);
    commit;
    
    GRANT READ ON orders TO CT, DT;
    
  2. データベース・セッション・ベースのアプリケーション・コンテキストを作成します。
    CONNECT sysadmin_vpd/password
    CREATE OR REPLACE CONTEXT orders_ctx USING orders_ctx_pkg;
  3. アプリケーション・コンテキストを設定するPL/SQLパッケージを作成します。
    CONNECT sysadmin_vpd/password
    CREATE OR REPLACE PACKAGE orders_ctx_pkg IS 
    --  PROCEDURE set_custnum SHARD_ENABLE;
      PROCEDURE set_custnum;
     END;
    /
    CREATE OR REPLACE PACKAGE BODY orders_ctx_pkg IS
      --PROCEDURE set_custnum SHARD_ENABLE
      PROCEDURE set_custnum
      AS
        custnum NUMBER;
        cnt number;
        cname varchar2(256);
      BEGIN
        -- workaround for bug 33131789: run a CSQ before SET_CONTEXT
        SELECT count(*) INTO cnt FROM BT.CUSTOMERS;
        SELECT SYS_CONTEXT('USERENV', 'SESSION_USER') INTO cname FROM dual;
        SELECT custid INTO custnum FROM BT.CUSTOMERS WHERE name = cname;
        DBMS_SESSION.SET_CONTEXT('orders_ctx', 'cust_no', custnum);
      EXCEPTION
       WHEN NO_DATA_FOUND THEN NULL;
      END set_custnum;
    END;
    /
    
  4. アプリケーション・コンテキストのPL/SQLパッケージを実行するログオン・トリガーを作成します。
    /* create trigger fails to propagate from catalog.
        CREATE TRIGGER set_custno_ctx_...
        DDL Error: ORA-06550: line 1, column 7:
        PLS-00352: Unable to access another database \'GDS$CATALOG.SYSLOCLINK\'
        ORA-06512: at "GSMADMIN_INTERNAL.EXECUTECOMMAND", line 166
        ORA-06550: line 1, column 7:
        PLS-00201: identifier \'SYS@GDS$CATALOG.SYSLOCLINK\' must be declared
        ORA-06550: line 1, column 7:
        PL/SQL: Statement ignored
        ORA-06512: at "SYS.DBMS_GSM_FIXED", line 3764
        ORA-06512: at "SYS.DBMS_GSM_FIXED", line 3866
        ORA-06512: at "GSMADMIN_INTERNAL.EXECUTECOMMAND", line 118
        ORA-06512: at "GSMADMIN_INTERNAL.EXECUTEDDL", line
      So we create it on shards as well manually. => Use alter session enable  shard operations before creating the trigger.
    */
    /* execute sys.exec_shard_plsql('CREATE OR REPLACE TRIGGER set_custno_ctx_trig AFTER LOGON ON DATABASE  BEGIN  sysadmin_vpd.orders_ctx_pkg.set_custnum; END;');
    ORA-03753: The procedure cannot be propagated.
    */
    -- run on catalog and all shards
    CONNECT sysadmin_vpd/password
    CREATE OR REPLACE TRIGGER set_custno_ctx_trig AFTER LOGON ON DATABASE  BEGIN  sysadmin_vpd.orders_ctx_pkg.set_custnum; END;
    /
    
  5. ログオン・トリガーをテストします。
    connect dt/dt
    SELECT SYS_CONTEXT('orders_ctx', 'cust_no') custnum FROM DUAL;
    connect ct/ct
    SELECT SYS_CONTEXT('orders_ctx', 'cust_no') custnum FROM DUAL;
    /* Example output:
    SQL> SELECT SYS_CONTEXT('orders_ctx', 'cust_no') custnum FROM DUAL;
    CUSTNUM
    --------------------------------------------------------------------------------
    2
    */
    
  6. シャード・カタログおよびシャードで、ユーザー・アクセスをオーダーのみに制限するPL/SQLポリシー関数を作成します。
    /* IF you see following error while propagation of DDL to shards, create the function on catalog and each shards manually.
        PLS-00352: Unable to access another database \'GDS$CATALOG.SYSLOCLINK\'
    */
    connect sysadmin_vpd/password
    CREATE OR REPLACE FUNCTION get_user_orders(
      schema_p   IN VARCHAR2,
      table_p    IN VARCHAR2)
     RETURN VARCHAR2
     AS
      orders_pred VARCHAR2 (400);
      cnum NUMBER;
     BEGIN
      SELECT NVL(SYS_CONTEXT('orders_ctx', 'cust_no'), 0) INTO cnum FROM dual;
      --orders_pred := 'custid = '||cnum;
      orders_pred := 'custid = SYS_CONTEXT(''orders_ctx'', ''cust_no'')'; 
     RETURN orders_pred;
    END;
    /
    
  7. 新しいセキュリティ・ポリシーを作成します。
    execute sys.exec_shard_plsql(' SYS.DBMS_RLS.ADD_POLICY (object_schema => ''BT'',   object_name => ''orders'', policy_name => ''orders_policy'',  function_schema => ''sysadmin_vpd'', policy_function  => ''get_user_orders'', statement_types  => ''select'',  policy_type => DBMS_RLS.CONTEXT_SENSITIVE,  namespace => ''orders_ctx'',  attribute => ''cust_no'')');
    
    -- exec sys.exec_shard_plsql('sys.DBMS_RLS.DROP_POLICY(''BT'', ''orders'', ''orders_policy'')');
    -- exec sys.exec_shard_plsql('sys.DBMS_RLS.REFRESH_POLICY(''BT'', ''orders'', ''orders_policy'')');
    
  8. 新しいポリシーをテストします。
    connect ct/ct
    select * from bt.orders;
    connect dt/dt
    select * from bt.orders;
    /*
    connect dt/dt
    SQL> select * from bt.orders;
           OID     CUSTID
    ---------- ----------
          8888        2
          7777        2
          
    connect ct/ct
    SQL> select * from bt.orders;
           OID     CUSTID
    ---------- ----------
          9876        1
    */