8 マルチテナント・データソースの共有プール・サポート

Oracle Database 12cリリース2(12.2.0.1)以降、マルチテナント・データソースの複数のデータソースでは、UCPで接続の共通プールを共有し、必要に応じて共通接続プールの接続を再利用できます。この項では、新しい共有プール機能に関連する次の概念について説明します。

注意:

  • JDBC Thinドライバのみ、JDBC OCIドライバではなく共有プール機能をサポートします。

  • 共有プール機能は、Oracle Databaseリリース18cのデータベース常駐接続プール(DRCP)ではサポートされていません。

  • この機能を使用するには、XML構成ファイルを使用する必要があります

8.1 共有プール・サポートの概要

UCPでは、プール・インスタンスはデータソースと1対1のマッピングがあります。同じデータベースおよびサービスへの接続を内部的に作成してキャッシュしても、各データソースは固有の接続プール・インスタンスを作成するため、そのインスタンスは別のデータソースによってアクセスできず、共有されません。このアーキテクチャでは、多くの分離された接続プールが作成され、データベースが特定の数の接続のみスケール・アップできるため、スケーラビリティの問題が発生します。

Oracle Database 12cリリース2(12.2.0.1)以降、UCPは、同じ接続プールを共有する同じデータベースに接続された複数のデータソースをサポートします。この共通接続プールは共有プールと呼ばれます。共有プールは、Oracle Databaseマルチテナント環境のマルチテナントJavaアプリケーションのスケーラビルなデプロイメントのためにシステム・リソースを最適化します。各データソースで均一でない負荷が存在する場合、この機能はさらに柔軟性を提供します。データソースごとの個別のプールが作成される場合、アイドル状態の接続プールから負荷状態にアイドル状態のリソースを移動できません。ただし、共有プールを使用する場合、データソース間の接続を共有して再利用し、効率的な方法で接続を利用できます。そのため、この機能により、データベース接続の合計数が減り、データベース・サーバーでのリソース使用、診断能力、管理性およびスケーリングが向上します。

この機能を実装できる2つのシナリオは、次のとおりです。

  • 共有プールを使用した単一マルチテナント・データソース

  • 共有プールを使用したテナントごとの1つのデータソース

共有プールを使用した単一マルチテナント・データソース

この構成を使用する場合、次の図に示すように、複数のテナントが共通データソースおよび共通プールを使用して、各テナントに適用される異なるサービスの接続を提供します。

図8-1 共有プールを使用した単一マルチテナント・データソース

図8-1の説明が続きます
「図8-1 共有プールを使用した単一マルチテナント・データソース」の説明

次のコードでは、この機能の動作方法について説明します。

    PoolDataSource multiTenantDS = PoolDataSourceFactory.getPoolDataSource();

    //common user for the CDB
    multiTenantDS.setUser("c##common_user");
    multiTenantDS.setPassword("password");   

    //Points to the root service of the CDB
    multiTenantDS.setURL("jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)"
        + "(HOST=myhost)(PORT=5521))(CONNECT_DATA=(SERVICE_NAME=root.oracle.com)))");   

    // password enabled role for tenant-1
    Properties tenant1Roles = new Properties();
    tenant1Roles.put("tenant1-role", "tenant1-password"); 

    //Create Connection to Tenant-1 and apply the tenant specific PDB roles.
    Connection tenant1Connection =
        multiTenantDS.createConnectionBuilder()
                     .serviceName("tenant1Svc.oracle.com")
                     .pdbRoles(tenant1Roles)
                     .build();

    // password enabled role for tenant-2
    Properties tenant2Roles = new Properties();
    tenant1Roles.put("tenant2-role", "tenant2-password");

    //Create Connection to Tenant-2 and apply the tenant specific PDB roles.
    Connection tenant2Connection =
        multiTenantDS.createConnectionBuilder()
                     .serviceName("tenant2Svc.oracle.com")
                     .pdbRoles(tenant2Roles)
                     .build();

新しいAPIの詳細は、「共有プール・サポートのUCP API」を参照してください。

共有プールを使用したテナントごとの1つのデータソース

この構成を使用する場合、マルチテナント・アプリケーションには、テナントごとの個別のデータソースおよび接続のための共通共有プールがあります。これにより、次の図に示すように、テナント固有のサービス情報で構成されて共通プールを共有する個別のデータソースが発生します。

図8-2 共有プールを使用したテナントごとの1つのデータソース

図8-2の説明が続きます
「図8-2 共有プールを使用したテナントごとの1つのデータソース」の説明

次のコードでは、この機能の動作方法について説明します。


    // UCP XML configuration file path in case of Unix 
    String file_URI = "file:/user/app/sharedpool/initial-shared-pool-config.xml";

    // UCP XML configuration file path in case of Windows 
    String file_URI = "file:/D:/user/app/sharedpool/initial-shared-pool-config.xml";

    // Java system property to specify XML configuration file location
    System.setProperty("oracle.ucp.jdbc.xmlConfigFile",<file_URI>);

    // Get the datasource instance, named as "pds1" in XML configuration file(initial-shared-pool-config.xml)
    PoolDataSource pds1 = PoolDataSourceFactory.getPoolDataSource("pds1");
    Connection pds1Conn = pds1.getConnection();
   
    // Get the datasource instance, named as "pds2" in XML configuration file(initial-shared-pool-config.xml)
    PoolDataSource pds2 = PoolDataSourceFactory.getPoolDataSource("pds2");
    Connection pds2Conn = pds2.getConnection();
   
    // Reconfigure datasource(pds1) using the new properties
    Properties newProps = new Properties();
    newProps.put("serviceName", <newServiceName>);
    pds1.reconfigureDataSource(newProps);
   
    // Configure a new datasource(pds3) to running pool using the new data source properties
    Properties dataSourceProps = new Properties();
    dataSourceProps.put("serviceName", <serviceName>);
    dataSourceProps.put("connectionPoolName", <poolName>);
    dataSourceProps.put("dataSourceName", <dataSourceName>);
    PoolDataSource pds3 = PoolDataSourceFactory.getPoolDataSource(dataSourceProps);
   
    // Reconfigure connection pool("pool1") using the new properties

    Properties newPoolProps = new Properties();
    newPoolProps.put("initialPoolSize", <newInitialPoolSizeValue>);
    newPoolProps.put("maxPoolSize", <newMaxPoolSizeValue>);
    UniversalConnectionPoolManager ucpMgr = UniversalConnectionPoolManagerImpl.getUniversalConnectionPoolManager();
    ucpMgr.reconfigureConnectionPool("pool1", newPoolProps);

注意:

  • UCPは、この機能を実装するためにサービス・スイッチを使用します。ただし、共有プールのサービス・スイッチは、同種のサービスでのみサポートされます。共有プールの異機種間サービス(Transaction Guardおよびアプリケーション・コンティニュイティなどのサービス属性の点からの異種性)はサポートされていません。

  • コード・スニペットで使用されているXML構成ファイルは、共有プール・サポートに必要なXML構成ファイルに関する項を参照してください。

8.2 共有プールをサポートするための前提条件

共有プールを使用するマルチテナント・データソースの前提条件は、次のとおりです。

  • XML構成ファイルを使用して、共有プールの初期構成を提供する必要があります。システム・プロパティoracle.ucp.jdbc.xmlConfigFileを使用して、UCPの初期XML構成ファイルを指定できます。初期XML構成ファイルの場所は、URIとして指定する必要があります。たとえば、file:/user_directory/ucp.xmlなどです。

    configuration.xsdスキーマ・ファイルは、参照用のucp.jarファイルに含まれます。UCP XML構成ファイルの作成中に、このファイルを参照します。

  • 共有プールの再構成中に、再構成APIを介して更新されたプール・プロパティが提供されます。

  • 共有プールおよび個別のテナント・データソース固有サービスに使用されるサービスのアプリケーション・サービスを常に使用します。管理サービスまたはデフォルトのPDBサービスが使用される場合、接続は再利用されません。

  • 共有プールを介してアクセスする様々なサービスは同種である必要があります。つまり、アプリケーション・コンティニュイティ(AC)などに関して、類似したプロパティを持つ必要があります。

  • 共有プールは単一のユーザーで構成する必要があります。このユーザーは、CDBで構成された共通ユーザーである必要があります。共通ユーザーには次の権限が必要です - CREATE SESSIONALTER SESSIONおよびSET CONTAINER。また、共通ユーザーには、DBMS_SERVICE_PRVTパッケージの実行権限も必要です。

    注意:

    • 共通ユーザーにテナントごとの特定のロールまたはパスワード対応のロールが必要な場合、これらのロールは、各テナント・データソース・プロパティで指定する必要があります。

    • SET CONTAINER文の利点は、別のPDBへの既存の接続があれば、プールはPDBへの新しい接続を作成する必要がないことです。プールでは、既存の接続を使用でき、SET CONTAINER文を通して、目的のPDBに接続できます。

  • プールの接続の合計数が接続再利用しきい値(プールで構成されている場合)および最小プール・サイズに達する場合のみ、共有プールの様々なテナント接続の接続再利用が発生します。

  • XML構成ファイルの共有プールに指定されたURLは、サービス名を明示的に指定したLONG形式である必要があります。短い形式または簡易接続URLはサポートされていません。

8.3 共有プールの構成

次の項では、共有プール構成について説明します。
  • プールの初期構成

  • プールの再構成

プールの初期構成

プールの初期構成では、XML構成ファイルを使用してデータソース・インスタンスを取得し、そのデータソースを使用して共有プールから接続を取得します。

    // Get the data source instance, named as "pds1" in the XML configuration file(initial-shared-pool-config.xml)
    PoolDataSource pds1 = PoolDataSourceFactory.getPoolDataSource("pds1");
    Connection pds1Conn = pds1.getConnection();

プールの再構成

  • 次のコードでは、プールの初期構成中に取得したデータソースの再構成方法を示します。

     // Reconfigure datasource(pds1) using the new propertries for reconfiguration
    
    Properties newProps = new Properties();
    newProps.put("serviceName",<newServiceName>);
    pds1.reconfigureDataSource(newProps);
  • 次のコードでは、新しいデータソースをすでに実行されている共有プールに追加する方法を示します。

    // Configure a new datasource(pds3) to the running pool using the new data source properties
    
    Properties dataSourceProps = new Properties();
    dataSourceProps.put("serviceName", <serviceName>);
    dataSourceProps.put("connectionPoolName", <poolName>);
    dataSourceProps.put("dataSourceName", <dataSourceName>);
    PoolDataSource pds3 = PoolDataSourceFactory.getPoolDataSource(dataSourceProps);
  • 次のコードでは、接続プールの再構成方法を示します。

    // Reconfigure connection pool("pool1") using the new properties
    
    Properties newPoolProps = new Properties();
    newPoolProps.put("initialPoolSize", <newInitialPoolSizeValue>);
    newPoolProps.put("maxPoolSize", <newMaxPoolSizeValue>);
    UniversalConnectionPoolManager ucpMgr = UniversalConnectionPoolManagerImpl.getUniversalConnectionPoolManager();
    ucpMgr.reconfigureConnectionPool("pool1", newPoolProps);

8.4 共有プール・サポートのUCP API

PoolDataSourceインタフェースの新しいメソッド

次のメソッドがoracle.ucp.jdbc.PoolDataSourceインタフェースで導入されました。

  • reconfigureDataSource(Properties configuration)

  • getMaxConnectionsPerService()

  • getServiceName()

  • getPdbRoles()

  • getConnectionRepurposeThreshold()

  • setConnectionRepurposeThreshold(int threshold)

PoolDataSourceFactoryクラスの新しいメソッド

次のメソッドがoracle.ucp.jdbc.PoolDataSourceFactoryクラスで導入されました。

  • getPoolDataSource(String dataSourceName)

  • getPoolDataSource(Properties configuration)

  • getPoolXADataSource(String dataSourceName)

  • getPoolXADataSource(Properties configuration)

oracle.ucp.admin.UniversalConnectionPoolManagerインタフェースの新しいメソッド

次のメソッドがoracle.ucp.admin.UniversalConnectionPoolManagerインタフェースで導入されました。

reconfigureConnectionPool(String poolName , Properties configuration)

oracle.ucp.admin.UniversalConnectionPoolインタフェースの新しいメソッド

次のメソッドがoracle.ucp.admin.UniversalConnectionPoolインタフェースで導入されました。

  • isShareable()

  • getMaxConnectionsPerService()

  • setMaxConnectionsPerService(int maxConnectionsPerService)

関連項目:

詳細は、『Oracle Universal Connection Pool Java API Reference』を参照してください。

8.5 共有プールのサンプルのXML構成ファイル

initial-shared-pool-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<ucp-properties>
    <connection-pool
        connection-pool-name="pool1"
        connection-factory-class-name="oracle.jdbc.pool.OracleDataSource"
        url="jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(HOST=host_name)(PORT=1521)(PROTOCOL=tcp))( CONNECT_DATA=(SERVICE_NAME=myorcldbservicename)))"
        user="C##CommonUser"
        password=password        
        initial-pool-size="10"
        min-pool-size="5" 
        max-pool-size="20"
        connection-repurpose-threshold="13"
        max-connections-per-service="15"
        validate-connection-on-borrow="true"
        sql-for-validate-connection="select 1 from dual"    
        shared="true"
    >

        <connection-property name="oracle.jdbc.ReadTimeout" value="2000"/>
        <connection-property name="oracle.net.OUTBOUND_CONNECT_TIMEOUT" value="2000"/> 

        <data-source
            data-source-name="pds1"
            service=pdb1_service_name
            description="pdb1 data source"/>
   
        <data-source
            data-source-name="pds2"
            service=pdb2_service_name
            description="pdb2 data source"/>

  
    </connection-pool>
</ucp-properties>