Oracle Active Data Guardを使用したOracle Application ContinuityのJava例 (2023/07/18)
Oracle Active Data Guardを使用したOracle Application ContinuityのJava例 (2023/07/18)
https://database-heartbeat.com/2023/07/18/java-ac-adg/
はじめに
Oracleアプリケーション・コンティニュイティは、データベースの中断をエンド・ユーザーおよびアプリケーションから隠します。このブログ投稿では、SQL*Plusを使用した簡単なテストについて説明します。ただし、SQL*Plusは通常、本番で使用する実際のアプリケーションではありません。また、SQL*Plusはプールされたアプリケーションではなく、アプリケーション・コンティニュイティに接続プールを使用することをお薦めします。
このブログ投稿は、Oracle Active Data Guardへのクイック・スタートのためのUniversal Connection Pool (UCP)を持つJDBCドライバを使用する単純なJavaの例を示しています。アプリケーション・コンティニュイティには、Oracle RACまたはOracle Active Data Guardオプション・ライセンスが必要です。
本番実装の推奨事項の完全なリストは、この投稿の最後にある公式のOracleドキュメントを参照してください。
環境
- Oracle Active Data Guardバージョン19.17およびGrid Infrastructure 19.17はOracle Cloudで実行されています。
- Java JDK 11
- ローカルのWindows PC上のEclipse IDE for Java Developers
データベース側
Data Guard構成の確認
Data Guard Brokerにログインし、構成を確認します。
[oracle@londonhost1 ~]$ dgmgrl / as sysdba
DGMGRL> show configuration
Configuration - CDB01_lhr_ad1_CDB01_lhr26k
Protection Mode: MaxAvailability
Members:
CDB01_lhr_ad1 - Primary database
CDB01_lhr26k - Physical standby database
Fast-Start Failover: Disabled
Configuration Status:
SUCCESS (status updated 17 seconds ago)
データベース・サービスの作成
次のように、プライマリおよびスタンバイにカスタム・ロールベースのデータベース・サービスを作成します。
#on primary
[oracle@londonhost1 ~]$ srvctl add service -db CDB01_lhr_ad1 -pdb PDB01 -service acsrv.oracle.com -stopoption IMMEDIATE -replay_init_time 600 -retention 86400 -drain_timeout 10 -notification TRUE -commit_outcome TRUE -failover_restore LEVEL1 -failovertype TRANSACTION -role PRIMARY
[oracle@londonhost1 ~]$ srvctl start service -db CDB01_lhr_ad1 -service acsrv.oracle.com
#on standby
[oracle@londonhost2 ~]$ srvctl add service -db CDB01_lhr26k -pdb PDB01 -service acsrv.oracle.com -stopoption IMMEDIATE -replay_init_time 600 -retention 86400 -drain_timeout 10 -notification TRUE -commit_outcome TRUE -failover_restore LEVEL1 -failovertype TRANSACTION -role PRIMARY
アプリケーション・コンティニュイティは、-failover_restore LEVEL1 -failovertype TRANSACTIONによって有効になります。
サービスはプライマリでのみ起動されます。スイッチオーバーまたはフェイルオーバー後、サービスはプライマリになった後、リモート側で自動的に起動されます。
データベース・ユーザーの作成
ユーザーおよびテスト用の単純な表を作成します。
[oracle@londonhost1 ~]$ sqlplus /
as
sysdba
SQL>
alter
session
set
container=pdb01;
Session altered.
SQL>
create
user
acusr identified
by
VerySecretPW__2023 quota unlimited
on
users;
User
created.
SQL>
grant
connect
to
acusr;
Grant
succeeded.
SQL>
create
table
acusr.actab (text varchar2(128));
Table
created.
高速アプリケーション通知の有効化(FAN)
FANポート(通常は6200)は、データベース側で開く必要があります。
クライアント側では、推奨される接続文字列を使用する場合、FANはGrid Infrastructure 12c、Oracle Database 12cおよびOracleクライアント12c以降から自動構成されます。次を参照してください。
クライアント側
JDKのインストール
常にJavaを使用している場合は、JDKがすでに使用されているはずです。Javaを初めて使用する場合:
Windowsの場合は、ここで説明するようにインストールに従います。
Linuxの場合は、インストールガイドに従うか、yumを使用できます。
sudo yum install java-11-openjdk
Eclipse IDE for Javaのインストール
お気に入りではなく、試してみたい場合は、こちらからダウンロードできます。
Windowsの場合は、インストール手順に従います。
Linuxの場合、バイナリを解凍して実行します。
tar
-zxvf eclipse-java-2022-12-R-linux-gtk-x86_64.
tar
.gz
chmod
744 eclipse
.
/eclipse
JDBCおよびUCP .jarライブラリのダウンロード
JDBCおよびUCPのダウンロード・ページから、圧縮されたJDBCドライバ(ojdbc11.jar)およびコンパニオンJarsファイルojdbc11-full.tar.gzをダウンロードします。
zipファイルを抽出し、次のJARファイルをアプリケーションのCLASSPATHに追加します。
ons.jar、ojdbc11.jarおよびucp11.jar
Eclipseで、プロジェクト名を右クリックし、「Build Path」、「Configure Build Path...」の順にクリックします。
「Libraries、 Classpath」を選択し、「Add External Jars...」をクリックし、zipファイルを抽出するディレクトリから前述の.jarファイルを選択し、「Apply and Close」をクリックします。
Javaの例
次のコード例を使用して、新しいJavaクラス(AC.java)を作成します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | import java.io.FileInputStream; import java.io.InputStream; import java.sql.Connection; import java.sql.Statement; import java.util.Properties; //PoolDataSource import oracle.jdbc.OracleConnection; import oracle.ucp.jdbc.PoolDataSourceFactory; import oracle.ucp.jdbc.PoolDataSource; public class AC { public static void main(String[] args) { usePoolDataSource(); } public static void usePoolDataSource() { try { //use Universal Connection Pool (UCP) PoolDataSource pds = PoolDataSourceFactory.getPoolDataSource(); pds.setConnectionFactoryClassName( "oracle.jdbc.datasource.impl.OracleDataSource" ); pds.setConnectionPoolName( "JDBC_UCP" ); //pds.setInitialPoolSize(10); pds.setMinPoolSize( 4 ); pds.setMaxPoolSize( 20 ); //load properties String PROP_FILE = "C:\Users\SPETRUS\Documents\spetrus\development\java\ACproject\src\config.properties" ; InputStream propInput = new FileInputStream(PROP_FILE); Properties prop = new Properties(); prop.load(propInput); //set properties System.setProperty( "oracle.net.tns_admin" , prop.getProperty( "tns_admin" )); pds.setURL( "jdbc:oracle:thin:@" +prop.getProperty( "tns_alias" )); pds.setUser(prop.getProperty( "db_user" )); pds.setPassword(prop.getProperty( "db_password" )); //enable FAN and connection tests pds.setConnectionWaitTimeout( 3 ); pds.setFastConnectionFailoverEnabled( true ); pds.setValidateConnectionOnBorrow( true ); //disable auto-commit pds.setConnectionProperty(OracleConnection.CONNECTION_PROPERTY_AUTOCOMMIT, "false" ); pds.setConnectionProperty(OracleConnection.CONNECTION_PROPERTY_IMPLICIT_STATEMENT_CACHE_SIZE, "100" ); //get connection from the pool Connection conn = pds.getConnection(); //conn.beginRequest(); //not needed, as connection pool sets explicit begin request boundary at getConnection() conn.setAutoCommit( false ); //execute query Statement stmt = conn.createStatement(); String insert = "insert into acusr.actab values ('Using Application Continuity')" ; int result = stmt.executeUpdate(insert); System.out.println( "insert result is: " + result); //stop here in bedug mode & (relocate | switchover | terminate the session) conn.commit(); //conn.endRequest(); //not needed, as connection pool sets explicit end request boundary at close() conn.close(); conn= null ; } catch (Exception e) { e.printStackTrace(); } } } |
この場合、config.propertiesファイルには、次の値が含まれます。
tns_admin=C:\Users\SPETRUS\Documents\spetrus\development
tns_alias=acsrv
db_user=acusr
db_password=VerySecretPW__2023
テストでは、プロパティ・ファイルを使用するのではなく、値をコードに直接配置することもできます。
接続文字列
TNS_ADMINディレクトリのtnsnames.oraファイルで、次の推奨される接続文字列を使用します。
ACSRV =
(DESCRIPTION = (CONNECT_TIMEOUT=90)(TRANSPORT_CONNECT_TIMEOUT=3)(RETRY_COUNT=50)(RETRY_DELAY=3)
(ADDRESS_LIST=(FAILOVER=ON)(LOAD_BALANCE=OFF)
(ADDRESS=(PROTOCOL=TCP)(HOST=132.145.41.207)(PORT=1521))
(ADDRESS=(PROTOCOL=TCP)(HOST=132.145.52.177)(PORT=1521))
)
(CONNECT_DATA=(
SERVICE_NAME=acsrv.oracle.com)
)
)
ADDRESS_LISTには、プライマリ・ホストとスタンバイ・ホストが含まれます。プライマリおよびスタンバイがRACデータベースの場合は、SCANを使用します。
テスト時間
コミットが実行される前とリクエストの終了前に、2つのブレーク・ポイントを設定します。
デバッグ・モードで実行:
コミットが実行される前にプログラムが停止します。
この時点で、プライマリ・データベースにログインし、ユーザーACUSRの既存のセッションを問い合せます。
set
lines 300
col db_unique_name
for
a15
col username
for
a10
col service_name
for
a20
SQL>
select
db_unique_name, database_role, open_mode
from
v$
database
;
SQL>
select
username, sid, serial#, service_name
from
gv$session
where
username =
'ACUSR'
;
ユーザーはプライマリ・データベースCDB01_lhr_ad1に接続されています。
次に、Data Guard Brokerを使用してスタンバイ・データベースにスイッチオーバーします。
DGMGRL> switchover to CDB01_lhr26k;
オプションで、WAITオプションを使用してドレイン・タイムアウトを指定できます。
DGMGRL> switchover to CDB01_lhr26k WAIT 30;
WAITオプションに値が指定されていない場合、Data Guard Brokerは、すべてのアクティブ・サービスの中で、最大構成drain_timeoutで指定された時間待機します。
指定されたドレイン・タイムアウトが経過し、スイッチオーバーが進行中になるまで待機します。
Performing switchover NOW, please wait...
New primary database "CDB01_lhr26k" is opening...
Oracle Clusterware is restarting database "CDB01_lhr_ad1" ...
Eclipseに戻り、実行を再開します。
スタンバイが新しいプライマリ・データベースに昇格するまで、実行は短期間ハングアップします。その後、実行は続行され、次のブレーク・ポイントで停止します。
最も重要なことは、サービスが停止したにもかかわらず、アプリケーションはエラー・メッセージを表示せずに継続したことです。
新しいプライマリ・データベースに接続します。
アプリケーションを中断せずにコミットが正常に完了しました:
ロールベースのカスタム・データベース・サービスは、新しいプライマリ・ホストで自動的に起動されました。
#on new primary host
[oracle@londonhost2 ~]$ srvctl status service -db cdb01_lhr26k -service acsrv.oracle.com
Service acsrv.oracle.com is running on instance(s) CDB01
まとめ
Oracle Application Continuityは、使用可能なデータベース・インスタンス上で処理中のトランザクションをリプレイすることで、エンド・ユーザーからデータベースの中断を隠します。エンド・ユーザーに対しては完全に透過的で、アプリケーション・コードの変更は不要です。
提供されているJavaコードは、JavaでOracle Application Continuityの使用を開始する例です。本番実装の場合は、Oracleが提供する手順および推奨事項に従ってください。
追加文書
- Application Continuity for Java – JDBC Developer’s Guide
- Ensuring Application Continuity – Universal Connection Pool Developer’s Guide
- Application Checklist for Continuous Service with Autonomous Database on Shared Infrastructure
- Best Practices for Applications Using Autonomous Database – Dedicated
- Application Checklist for Continuous Service for MAA Solutions
- Best Practices for Adopting Transparent Application Continuity
- Application Continuity for the Oracle Database
- Oracle JDBC Drivers – What JDBC driver version to choose
- Java Development with Autonomous Transaction Processing Dedicated (ATP-D)
コメント
コメントを投稿