Oracle Database Application Continuityを使用したPHP OCI8の高可用性 (2025/03/29)
Oracle Database Application Continuityを使用したPHP OCI8の高可用性 (2025/03/29)
これは、Oracle Database Application Continuity機能が、予期しない接続およびデータベースの停止中にPHP OCI8アプリケーションの円滑な実行を継続するためにどのように役立つかを示すデモンストレーションです。ユーザーは問題に気づいていないままです。複雑なアプリケーション・エラー処理ロジックは必要ありません。
Photo by Martin Sanchez on Unsplashはじめに
Oracle Database Application Continuity機能は、データベース接続停止後に中断された処理中のトランザクションを自動的に再接続してリプレイすることで、アプリケーション・エラーの発生率を低減します。アプリケーションの状態をシームレスに復元します。ACは、ハードウェア、ソフトウェア、ネットワーク、ストレージのエラー、およびタイムアウトをマスクします。アプリケーションは引き続き実行され、ユーザーは停止を認識しません。アプリケーションのコードには、不要で複雑なリカバリ・ロジックは必要ありません。ACとその兄弟である透過的アプリケーション・コンティニュイティは、RACやOracle Autonomous Databaseなど、Oracle Databaseの様々な構成で使用できます。
ACおよびTACは、PHP OCI8を含む多くの言語ドライバでサポートされています。
アプリケーション・コンティニュイティは、Oracle Databaseドライバ・プール(Oracle Call Interfaceセッション・プールなど)を使用するOLTPアプリケーション、または明示的なリクエスト境界を提供するアプリケーションにお薦めします。透過的アプリケーション・コンティニュイティ(TAC)は、アプリケーション・コンティニュイティの機能モードで、Oracleセッション・プールを使用するためにアプリケーションを必要としません。セッションとトランザクション状態を透過的に追跡および記録します。
Oracle Databaseドライバ・プールを使用するアプリケーションの場合、ACを使用するかTACを使用するかを選択できます。
ACとTACのすべての違いを理解し、ベストプラクティスの情報と細かい印刷物を見るには、この記事の最後にある参照を確認してください。
デモ
Oracle Application Continuityの以前のブログ投稿に続いて、Oracle Autonomous Databaseの「high」サービスでTACを有効にしました。
$ sqlplus -l admin@'tcps://adb.melb.oraclecloud.com:1522/abc_cjmtls_high.adb.oraclecloud.com?wallet_location=/Users/cjones/alwaysfree/CJMTLS'
SQL> execute dbms_app_cont_admin.enable_tac('abc_cjmtls_high.adb.oraclecloud.com', 'AUTO', 600);
有効になっていることを確認しました:
SQL> set pagesize 1000 linesize 150
SQL> col name format a60
SQL> col failover_type format a15
SQL> select name, failover_type from dba_services;
NAME FAILOVER_TYPE
------------------------------------------------------------ ---------------
ABC_CJMTLS_tp.adb.oraclecloud.com
ABC_CJMTLS_high.adb.oraclecloud.com AUTO
ABC_CJMTLS_medium.adb.oraclecloud.com
ABC_CJMTLS_low.adb.oraclecloud.com
ABC_CJMTLS_tpurgent.adb.oraclecloud.com
ABC_CJMTLS
実生活では、ドキュメントに従って「TP」サービスで有効にすることもできます。
PHP OCI8アプリケーション
私が使ったPHPアプリは、ここでGitHubギストとして入手可能です。
まず、DBAが接続の破棄に使用できる便利なkill文として、接続の一意のセッションIDおよびシリアル番号が出力されます。実行中のアプリケーションに対するこの中断は、デモが計画外の接続停止をシミュレートする方法です。
// Display the SQL that an administrator can run to kill the connection
$killsql = "select unique 'alter system kill session '''||sid||','||serial#||''';'||'' from v\$session_connect_info where sid = sys_context('USERENV', 'SID')";
$s = oci_parse($c, $killsql);
oci_execute($s);
$r = oci_fetch_row($s);
print("While this script is running, use SQL*Plus to execute:\n ".$r[0]. "\n");
たとえば、次のように出力します。
While this script is running, use SQL*Plus to execute:
alter system kill session '16198,41975';
メイン・コード・ループは、データを挿入し、接続の現在の一意のセッションIDとシリアル番号を表示し、コミットする前に数秒間スリープします。
for ($i = 1; $i <= 10; $i++) {
$data = "a" . $i;
$s1 = oci_parse($c, "insert into demo (username) values(:un)");
oci_bind_by_name($s1, ":un", $data);
oci_execute($s1, OCI_NO_AUTO_COMMIT);
// Show the unique session ID and serial number that identify this connection
$sidsql = "select unique sid || '-' || serial# from v\$session_connect_info where sid = sys_context('USERENV','SID')";
$s2 = oci_parse($c, $sidsql);
oci_execute($s2);
$r = oci_fetch_row($s2);
print("SID-serial#: ". $r[0]. " inserted data ". $i . "\n");
sleep(2);
oci_commit($c);
}
表は、次のように作成されました。
create table demo (id number generated by default as identity,
username varchar2(40));
TACあり
最初に、TACが有効になっているデータベース・サービスを使用するようにアプリケーションを編集しました。
$service = 'high'; // TAC
その後、アプリを実行しました:
$ php tac-php.php
これにより、前述のkill SQLが表示され、データの挿入が開始されました。
Using service: high
While this script is running, use SQL*Plus to execute:
alter system kill session '16198,41975';
SID-serial#: 16198-41975 inserted data a1
SID-serial#: 16198-41975 inserted data a2
SID-serial#: 16198-41975 inserted data a3
SID-serial#: 16198-41975 inserted data a4
SID-serial#: 16198-41975 inserted data a5
次に示すように、いくつかの挿入を続行します。次に、SQL*Plusを特権ユーザーADMINとして実行している別のウィンドウで、表示されたSQL文を実行してPHP接続を強制終了し、アプリケーションの失敗を試みました。
SQL> alter system kill session '16198,41975';
しかし、PHPが実行されていたターミナルに戻ると、私が見たのは、16198–41975から21130–3914への接続変更のSIDとシリアル番号だけでした。エラーはスローされませんでした。10行すべてが挿入されたことを証明する問合せ出力を表示して、最終的にアプリが正しく完了しました。
SID-serial#: 21130-3914 inserted data a6
SID-serial#: 21130-3914 inserted data a7
SID-serial#: 21130-3914 inserted data a8
SID-serial#: 21130-3914 inserted data a9
SID-serial#: 21130-3914 inserted data a10
The data inserted was:
a1
a2
a3
a4
a5
a6
a7
a8
a9
a10
これは、TACが成功し、正常にデータベース「障害」を処理したことを示しています。Oracle TACは、実行されているSQL文を記録していたため、最初の接続が強制終了された後、内部的に再接続して未処理のデータベース操作をリプレイできました。ユーザは問題があることを知らなかった。アプリケーションに特別な再接続およびデータ再試行ロジックは必要ありませんでした。
ACまたはTACなし
アプリケーションをダブルチェックするには、ACまたはTACが有効になっていない「低」サービスを使用するようにファイルを編集しました。
$service = 'low'; // No AC or TAC
アプリの再編:
$ php tac-php.php
Using service: low
While this script is running, use SQL*Plus to execute:
alter system kill session '11981,61556';
SID-serial#: 11981-61556 inserted data a1
SID-serial#: 11981-61556 inserted data a2
SID-serial#: 11981-61556 inserted data a3
SID-serial#: 11981-61556 inserted data a4
SID-serial#: 11981-61556 inserted data a5
数回繰り返した後、SQL*Plusでkill文を実行しました。
SQL> alter system kill session '11981,61556';
そして今回は、PHPアプリが接続が終了したため、すぐにさまざまなエラーで終了しました。
Warning: oci_commit(): ORA-03113: end-of-file on communication channel
Process ID: 64045
Session ID: 11981 Serial number: 61556
Help: https://docs.oracle.com/error-help/db/ora-03113/ in tac-php.php on line 166
ゲームオーバー! ユーザーを不幸に!
まとめ
ACおよびTACは、計画外のデータベース・ノードまたは接続の障害からアプリケーションを保護するのに役立ちます。ユーザーは、自分で処理する問題を認識しません。開発者は、不完全なトランザクションを再実行するために、データ再試行ロジックをコーディングする必要はありません。PHP OCI8はOracle Call Interfaceセッション・プールを使用するため、ACおよびTACをサポートしています。
Oracle高可用性ソリューションの詳細は、次のリファレンスを参照してください。
参照
サンプルコードtac-php.php
Use Application Continuity on Autonomous Database Serverless
https://docs.oracle.com/en/cloud/paas/autonomous-database/serverless/adbsb/application-continuity1.html
High Availability Overview and Best Practices
https://docs.oracle.com/en/database/oracle/oracle-database/23/haovw/index.html
Application Checklist for Continuous Service for MAA Solutions
https://www.oracle.com/a/tech/docs/application-checklist-for-continuous-availability-for-maa.pdf
The Underground PHP and Oracle Manual
https://www.oracle.com/technetwork/database/database-technologies/php/201212-ug-php-oracle-1884760.pdf
PHP Oracle OCI8 Manual
https://www.php.net/manual/en/book.oci8.php
Oracle Call Interface and Application Continuity
https://docs.oracle.com/en/database/oracle/oracle-database/23/lnoci/high-availability-in-oci.html#GUID-A8DD9422-2F82-42A9-9555-134296416E8F
コメント
コメントを投稿