Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Application Continuity

oracle4engineer
March 10, 2024
190

Application Continuity

Oracle Database 12c Release 1から、データベース・サーバーのクラッシュなどによりコネクションが異常切断された場合に自動再接続とトランザクションの自動実行をアプリケーションから透過的に行うアプリケーション・コンティニュイティ/Application Continuityの機能があります。
更新トランザクションの再実行には繊細な配慮が必要ですが、アプリケーション・コンティニュイティはそれらを自動化し、オンライン・トランザクション処理系のアプリケーションのかなり広い範囲に適用することができます。

oracle4engineer

March 10, 2024
Tweet

More Decks by oracle4engineer

Transcript

  1. Copyright © 2024, Oracle and/or its affiliates 3 概要 •

    更新トランザクションの途中で異常終了すると何が起こる? • エラーになったからといって更新トランザクションを単純に再実行してもよいか? • アプリケーション・コンティニュイティはなにを自動化しているか アプリケーション・コンティニュイティの構成 • データベース・サーバー側 • データベース・クライアント側 • アプリケーション・コード上の考慮点 - アプリケーション・コンティニュイティで再実行できないケース アプリケーション・コンティニュイティ
  2. Copyright © 2024, Oracle and/or its affiliates 5 COMMITされていない更新はROLLBACKされる 更新トランザクションの途中で異常終了すると何が起こる?

    SQL> INSERT INTO tbl1 VALUES(SYSDATE,1,seq1.NEXTVAL); 1行が作成されました。 SQL> SELECT * FROM tbl1; C1 C2 C3 ------------------- ---------- ---------- 2020/07/21 15:15:26 1 121 SQL> SELECT * FROM tbl1; SELECT * FROM tbl1 * 行1でエラーが発生しました。: ORA-00028: セッションは強制終了されました。 SQL> SELECT * FROM tbl1; レコードが選択されませんでした。 再接続するとROLLBACKされている セッション切断後のSQL実行はエラー ここでセッション切断 ALTER SYSTEM KILL SESSION (1) (2) (3) (4) (5)
  3. Copyright © 2024, Oracle and/or its affiliates 6 セッションが切断されても自動再接続&更新トランザクション自動再実行 アプリケーション・コンティニュイティ

    SQL> INSERT INTO tbl1 VALUES(SYSDATE,1,seq1.NEXTVAL); 1行が作成されました。 SQL> SELECT * FROM tbl1; C1 C2 C3 ------------------- ---------- ---------- 2020/07/21 15:21:29 1 122 -- ALTER SYSTEM KILL SESSION SQL> SELECT * FROM tbl1; C1 C2 C3 ------------------- ---------- ---------- 2020/07/21 15:21:29 1 122 ここでセッション切断 自動再接続&自動再実行された 更新トランザクション継続 セッション切断後にSQL発行 (1) (2) (3) (4) アプリケーションからは何も起きて いないように見える
  4. Copyright © 2024, Oracle and/or its affiliates 7 アプリケーションはエラーになる 更新トランザクションの途中で異常終了するとROLLBACKされる

    アプリケーション Oracle接続ドライバ SQL 1 SQL 2 SQL 3 SQL 1 SQL 2 SQL 3 Oracleサーバー SQL 1 SQL 2 SQL 3 COMMITされていない更 新はROLLBACKされる アプリケーションはエラーを 観測する
  5. 再接続 Copyright © 2024, Oracle and/or its affiliates 8 セッションが切断されても自動再接続&更新トランザクション自動再実行

    アプリケーション・コンティニュイティ アプリケーション Oracle接続ドライバ SQL 1 SQL 2 SQL 3 SQL n COMMIT SQL 1 SQL 2 SQL 3 SQL n COMMIT Oracleサーバー SQL 1 SQL 2 SQL 3 SQL n COMMIT SQL 1 SQL 2 SQL 3 Oracle接続ドライバは 何を発行したかを記憶し ているので自動再実行
  6. Copyright © 2024, Oracle and/or its affiliates 9 Oracleインスタンスがクラッシュ •

    正常Oracleインスタンスによって自動的にリカバリ処理 (ROLLFORWRD & ROLLBACK)が開始される 障害インスタンスと接続していたクライアント • セッションが切断されてエラーになる • COMMITされていないトランザクションによる更新は正 常Oracleインスタンスによってロールバックされる 正常インスタンスと接続していたクライアント • エラーにはならない • リカバリ処理(ごく短時間)の間SQL処理の進行がフ リーズする RACを構成するどのOracleインスタンスに接続しても全データにアクセス可能 Oracle Real Application ClustersでのOracleインスタンス障害からのリカバリ Oracle インスタンス Oracle インスタンス Oracleクライアント oracle oracle ERROR 継続 RACノード1 RACノード2 共有ストレージ
  7. Copyright © 2024, Oracle and/or its affiliates 10 Oracle接続ドライバがセッション切断を検出すると再接 続からトランザクション再実行まで自動実行。

    アプリケーションから見るとエラーを検出せずにトランザクショ ンが完了する。 一般的なWebアプリケーションのコードはほとんどの場合 変更不要。 Enterprise Edition RACもしくはActive Data Guardで使用可能。 更新トランザクションを安全に自動再実行(12c Release 1~) アプリケーション・コンティニュイティ ただし、更新トランザクションの再実行は繊細な配慮が必要 これを自動化するのがアプリケーション・コンティニュイティ 自動再接続→自動再実行 Oracleクライアント RAC SELECT INSERT UPDATE COMMIT
  8. Copyright © 2024, Oracle and/or its affiliates 11 Oracleクライアント上のアプリケーションはトランザクション の最後にCOMMITを発行する。

    COMMIT情報がオンラインREDOログ・ファイルに書き込 み完了した時点(永続化)でCOMMITされたことになる (DURABILITYの保証)。 Oracleインスタンスが異常終了しても、再起動後にオン ラインREDOログ・ファイルを読むことでトランザクションが完 了したかがわかる。 すると、そのトランザクションによる中途半端なデータ・ブ ロックの更新をROLLFORWARDまたはROLLBACKす ればよいかがわかる。 オンラインREDOログ・ファイルにCOMMIT情報が永続化されると更新が確定したことになる COMMIT oracle lgwr COMMIT Oracleクライアント SELECT INSERT UPDATE COMMIT Oracleサーバー オンライン REDOログ・ ファイル 書き込み完了
  9. Copyright © 2024, Oracle and/or its affiliates 12 アプリケーションがCOMMITを発行したけれども、オンライ ンREDOログ・ファイルへのCOMMIT書き込み完了が

    Oracleクライアントに通知される前にサーバー側の障害 が発生することがあり得る。 Oracleクライアントから見るとトランザクションが完了する 前にエラーになる。 サーバー側でCOMMIT書き込みが完了していたかは見 えていない。 Oracleクライアントはこの更新トランザクションを再実行し てもよいか? アプリケーションはエラーを観測したからといって単純に更 新トランザクションを再実行するとデータが不正になる場 合がある。 更新トランザクションの再実行にまつわる問題 COMMIT発行時の障害 oracle lgwr COMMIT Oracleクライアント SELECT INSERT UPDATE COMMIT Oracleサーバー オンライン REDOログ・ ファイル Oracleクライアントからは COMMIT書き込み完了し たかがわからない
  10. Copyright © 2024, Oracle and/or its affiliates 13 トランザクション・ガードはアプリケーション・コンティニュイティ 実装のために追加された機能。

    論理トランザクションID(LTXID)を指定してそのトランザク ションが完了していたのかを確認する (要Enterprise Edition)。 トランザクションの状態を管理する内部的な表を維持する 必要があるため論理レプリケーション機能(GoldenGate など)では動作しない。 特定のトランザクションが完了したのかを確認する(12c Release 1~) トランザクション・ガード oracle COMMIT Oracleクライアント LTXID=xx COMMIT済 ? Oracleサーバー オンライン REDOログ・ ファイル トランザクション状態を管 理する内部表
  11. Copyright © 2024, Oracle and/or its affiliates 14 アプリケーション・コンティニュイティ対応接続ドライバは Oracleサーバーに発行した処理を記憶している。

    Oracle接続ドライバがセッション切断を検出すると自動 再接続。 COMMIT時の障害はトランザクション・ガードでトランザク ションの状態を確認してCOMMIT完了していなければト ランザクションを自動再実行。 Oracle接続ドライバがセッション切断を検出すると (1) 再接続 (2) トランザクション状態の確認 (3) トランザクション再実行 まで自動で行う。 アプリケーションから見るとエラーを検出せずにトランザ クションが完了する。 更新トランザクションを安全に自動再実行 アプリケーション・コンティニュイティ (1) 再接続 (2) 状態確認 (3) 再実行 Oracleクライアント RAC SELECT INSERT UPDATE COMMIT
  12. Copyright © 2024, Oracle and/or its affiliates 15 Oracle Database

    19c Database ライセンス情報ユーザー・マニュアル https://docs.oracle.com/cd/F19136_01/dblic/Licensing-Information.html#GUID-0F9EB85D- 4610-4EDF-89C2-4916A0E7AC87 Real Application ClustersまたはActive Data Guardのライセンスが必要 アプリケーション・コンティニュイティに必要なライセンス 機能/オプション/パック SE2 EE EE-ES DBCS SE DBCS EE DBCS EE-HP DBCS EE-EP ExaCS 注意事項 アプリケーション・コン ティニュイティ N Y Y N N N Y Y EEおよびEE-ES: Oracle Active Data Guardオプショ ンまたはOracle Real Application Clustersオプ ションが必要 ただし技術的な実験自体はEnterprise Editionのシングル・インスタンス構成でも可能(後述)。 Database Cloud Service: オプション込み オンプレミス: 要オプション
  13. Copyright © 2024, Oracle and/or its affiliates 17 Oracleクライアント •

    アプリケーション・コンティニュイティ対応の接続ドライバ • DBMS外部に副作用を持つプロシージャがトランザク ションに含まれている場合のアプリケーション・コードの 扱い • アプリケーション・コンティニュイティで再実行できないア プリケーション・コードになっていないか Oracleサーバー(RAC) • アプリケーション・コンティニュイティはサービスの属性とし て設定 • トランザクション・ガードの有効化 • 可変オブジェクトが値を保存する設定 OracleクライアントとOracleサーバーの連係機能 アプリケーション・コンティニュイティの構成 Oracleサーバー(RAC) • サービス • トランザクション・ガード • 可変オブジェクト Oracleクライアント • 接続ドライバ • アプリケーション・コード
  14. Copyright © 2024, Oracle and/or its affiliates 18 データベース・サーバー側 •

    Real Application Clusters管理およびデプロイメント・ガイド データベース・クライアント側 (アプリケーション・コンティニュイティ対応の各言語用接続ドライバ) • JDBC開発者ガイド • Data Provider for .NET開発者ガイド • Oracle Call Interfaceプログラマーズ・ガイド アプリケーション・コンティニュイティの関連マニュアル
  15. Copyright © 2024, Oracle and/or its affiliates 20 • アプリケーション・コンティニュイティはサービスの属性として設定

    • トランザクション・ガードの有効化 データベース・サーバー側 アプリケーション・コンティニュイティの構成
  16. Copyright © 2024, Oracle and/or its affiliates 21 アプリケーション・コンティニュイティ /

    Application Continuity (12c Release 1~) • Oracleサーバー障害を検出すると自動再接続しトランザクションを自動再実行 • DBMS外部に副作用のあるプロシージャの再実行を制御可能 透過的アプリケーション・コンティニュイティ / Transparent Application Continuity (18c~) • アプリケーション・コンティニュイティで制御可能だったいくつかの動作を決め打ち • ほとんどのアプリケーションで適用可能な動作 • リプレイ境界(後述)を自動挿入 • サード・パーティ製Javaアプリケーション・サーバーでもコード修正なしに使用可能(19c~) 2種類の動作モード アプリケーション・コンティニュイティ
  17. Copyright © 2024, Oracle and/or its affiliates 22 AC/TACはsrvctlコマンドでサービスの属性として設定。 -failovertype

    -failover_restore -commit_outcome ACとTACの指定 サービスの属性 Oracleクライアントは サービス名を指定して接続 SERVICE_NAME=service_A Oracleクライアント RAC service_A AC/TACはサービスの属性 srvctl modify service ... -failovertype AUTO -failover_restore AUTO -commit_outcome TRUE -replay_init_time 60 -retention 86400
  18. Copyright © 2024, Oracle and/or its affiliates 23 TAFとAC/TACの指定 サービスの属性

    -failovertypeの属性 セッション・フェイルオーバー機能 SESSION 透過的アプリケーション・フェイルオーバー(要OCIクライアント) セッション再接続 SELECT 透過的アプリケーション・フェイルオーバー(要OCIクライアント) SELECT文自動再実行 TRANSACTION (12c Release 1~) アプリケーション・コンティニュイティ 更新トランザクション自動再実行 AUTO (18c~) 透過的アプリケーション・コンティニュイティ 更新トランザクション自動再実行 Oracle8から存在する透過的アプリケーション・フェイルオーバー(Transparent Application Failover: TAF)機能もサー ビスの属性として設定可能。 TAFはOCIの機能なのでJDBC thinドライバでは使用できない。 TAFはトランザクションの中にひとつでも更新処理があるとエラーになる。SELECT文しか対応できない。 AC/TACは更新トランザクションを再実行可能。 srvctl modify service ... -failovertype SESSION | SELECT | TRANSACTION | AUTO
  19. Copyright © 2024, Oracle and/or its affiliates 24 サービスの属性でTAC(-failovertype AUTO)を設定すると自動的にセッション状態復元(-failover_restore

    AUTO)が設定される。 AC (-failovertype TRANSACTION)の場合は明示的に-failover_restore LEVEL1を指定する。 復元される項目のリストは使用するバージョンのマニュアル「 Real Application Clusters管理およびデプロイメント・ガイ ド」を参照のこと。 ALTER SESSIONなどによる変更 セッション状態の復元 nls_nchar_conv_excp nls_calendar nls_comp nls_currency nls_date_format nls_date_language nls_dual_currency nls_iso_currency nls_language nls_length_semantics nls_numeric_characters nls_sort nls_territory nls_time_format nls_time_tz_format nls_timestamp_format nls_timestamp_tz_format allow_rowid_column_type approx_for_aggregation approx_for_count_distinct approx_for_percentile cursor_sharing default_collation optimizer_capture_sql_plan_baselines srvctl modify service ... -failover_restore NONE | LEVEL1 | AUTO optimizer_ignore_hints optimizer_ignore_parallel_hint optimizer_use_sql_plan_baselines parallel_degree_limit parallel_degree_policy parallel_min_time_threshold plscope_settings plsql_ccflags plsql_debug plsql_optimize_level plsql_warnings recyclebin result_cache_mode
  20. Copyright © 2024, Oracle and/or its affiliates 25 サービスの属性 -commit_outcome

    TRUE データベース・ユーザーに権限付与 ※19cでは設定不要。 データベース・ユーザーの権限とサービスの属性 トランザクション・ガードの有効化 SQL> GRANT EXECUTE ON DBMS_APP_CONT TO user; srvctl modify service ... -failovertype AUTO -failover_restore AUTO -commit_outcome TRUE -replay_init_time 60 -retention 86400
  21. Copyright © 2024, Oracle and/or its affiliates 26 Oracle Autonomous

    DatabaseはExadataを基盤としており、つまりEnterprise Edition RAC。 アプリケーション・コンティニュイティに対応しているが、srvctlコマンド操作ができないので専用の設定プロシージャが用意さ れている。サービス名を指定するとそのサービスで有効になる。 OSコマンド(srvctl)操作ができないのでAC/TAC設定用のプロシージャが用意されている Oracle Autonomous Database execute DBMS_APP_CONT_ADMIN.ENABLE_AC( 'databaseid_tpurgent.adb.oraclecloud.com', 'LEVEL1', 600); execute DBMS_APP_CONT_ADMIN.ENABLE_TAC( 'databaseid_high.adb.oraclecloud.com', 'AUTO', 1200); 動作モード 設定プロシージャ AC DBMS_APP_CONT_ADMIN.ENABLE_AC() TAC ※ DBMS_APP_CONT_ADMIN.ENABLE_TAC() ※Dedicated InfrastructureではTP, TP_TLS, TPURGENT, TPURGENT_TLSのサービスはデフォルトでTACが有効
  22. Copyright © 2024, Oracle and/or its affiliates 27 サービスに関するビュー DBA_SERVICES(ALL_SERVICES,

    CDB_SERVICES) • FAILOVER_TYPE TAF/AC/TACのモード • COMMIT_OUTCOME トランザクション・ガード アプリケーション・コンティニュイティのサービス設定確認 SQL> select name, failover_type, commit_outcome from dba_services; NAME FAILOVER_TYPE COMMIT_OUTCOME -------------------- -------------------- -------------------- SIPDB19A1 NO pdba1svc1 NO pdba1svc2ac TRANSACTION YES pdba1svc3tac AUTO YES
  23. Copyright © 2024, Oracle and/or its affiliates 29 • リクエスト境界の概念

    • Javaとそれ以外の言語で事情が異なる • 可変オブジェクトが値を保存する設定 データベース・クライアント側 アプリケーション・コンティニュイティの構成
  24. Copyright © 2024, Oracle and/or its affiliates 30 アプリケーション・コンティニュイティが想定するコード: 1.

    Oracle製コネクション・プールからコネクション取得 • Javaでは場合分けが発生(後述) 2. DML発行 3. 最後に1回だけCOMMIT 4. コネクション・プールに返却 一般的なオンライン・トランザクション処理ならばこうなって いるはず。 コネクション・プールからコネクションを取得し、返却するま でをリクエスト境界と呼ぶ。 アプリケーション・コンティニュイティが再実行するのはリクエ スト境界の先頭から。 リクエスト境界の概念 アプリケーション・コンティニュイティ ConnectionPool ConnectionPool getConnection() close() DML 1 DML n COMMIT リクエスト境界
  25. Copyright © 2024, Oracle and/or its affiliates 31 リクエスト境界の概念(Javaの場合) アプリケーション・コンティニュイティ

    Connection con = ods.getConnection(); // コネクション取得 ((OracleConnection)con).beginRequest(); // リクエスト境界開始 ... // SQL実行 con.commit(); // トランザクション完了 ((OracleConnection)con).endRequest(); // リクエスト境界終了 con.close(); // コネクション・クローズ この間が自動再実行の対象 Javaのコード beginRequest()とendRequest()をリクエスト境界と呼び、これらのAPIで囲った範囲が自動再実行の対象。 Javaの場合beginRequest()とendRequest()挿入の要不要の場合分けが発生: • Oracleのコネクション・プールを使わないとこのAPI挿入が必要。 • Oracle Universal Connection Pool (UCP)やOracle WebLogic Serverのコネクション・プールからコネク ションを取得するとこれらのAPI挿入が不要。 • Oracle JDBC Driver 19c(以降)とOracle Database 19c(以降)で透過的アプリケーション・コンティニュイ ティを使用するとUCPがなくともリクエスト境界のAPI挿入が不要。
  26. Copyright © 2024, Oracle and/or its affiliates 32 JDBC thin

    driver (12c Release 1~) • リプレイ・ドライバのクラス(新しいクラス)を指定 oracle.jdbc.replay.OracleDataSourceImpl • Universal Connection Pool(UCP)を使用するとリクエスト境界のAPI挿入のコード変更が不要 • 19cのTACではUCP無しでもリクエスト境界のAPI挿入不要 OCI Session Pool (12c Release 2~) • Pro*CとPro*COBOLはOCI Session Poolに対応していないのでACは使用できない • SQL*PlusはAC対応 ODP.NET Unmanaged Driver (12c Release 2~) • 接続文字列 Application Continuity=true • Managed Driverと.NET Core Driverは非対応 アプリケーション・コンティニュイティ対応クライアント
  27. Copyright © 2024, Oracle and/or its affiliates 33 コネクション・プール機能はどの階層の持ち物か 言語によって事情が異なる

    Application Server Pool Application Server Pool Javaアプリケーション・サーバー • JDBC thinドライバ Java以外のアプリケーション・サーバー • OCI Session Pool • ODP.NET Unmanaged Driver • コネクション・プール機能はアプリケーション・サーバーの役割。 • UCPが使用できるかで場合分けが発生。 • コネクション・プール機能はOracle接続ドライバと一体。 • リクエスト境界のAPI挿入無しでACが使用可能。
  28. Copyright © 2024, Oracle and/or its affiliates 34 コネクション・プールがFANイベントを解釈 高速接続フェイルオーバー(FCF)

    • Oracleサーバーの異常で即コネクションを切断 • 計画停止時のコネクションのドレイニング ランタイム接続ロード・バランス(RCLB) • 定期的なリバランス 接続ドライバの機能 アプリケーション・コンティニュイティ(AC/TAC) • コネクションの異常切断でトランザクション自動再実行 • JavaではUCPがあるとリクエスト境界のAPI埋め込み が不要 Oracleサーバーとの連携 Oracleクライアントのコネクション管理機能 Pool コネクション・プールが FANイベントを解釈 • FCF • RCLB ACは接続ドライバの機能 (プールも関係する) Clusterware Clusterware FANイベント
  29. Copyright © 2024, Oracle and/or its affiliates 35 JavaアプリケーションサーバーではFANイベントを解釈するのはUCPであるが、UCPを使用できない環境でも (Transparent)

    Application Continuityは使用可能。 FANとAC/TACは組み合わせると都合の良い機能であって、使用すること自体はそれぞれ独立している。 異常を検出する機能と検出した異常に対処する機能 FANのFCFとAC/TACは独立した別の機能 発生した異常を検出 検出した異常に対処 Pool • (Transparent) Application Continuity は切断されたことを検出すると自動再接続& 自動再実行する機能 • 切断検出のきっかけは何でもよい • Fast Connection Failover (FCF)は Oracleサーバー障害時に異常が発生したこと を明示的に通知する機能 • TCPレベルで応答がないケースでもコネクショ ン・プールから障害ノードとのコネクションを削除
  30. Copyright © 2024, Oracle and/or its affiliates 36 コネクション・プールだけのjarファイルを提供 Oracle

    Universal Connection Pool (UCP) JDBCドライバのjarファイルとは独立したコネクション・プールだけのucp.jarファイルを提供。 Oracle JDBCドライバのダウンロード・ページから取得可能。
  31. Copyright © 2024, Oracle and/or its affiliates 37 WebLogic Server

    12.1.2以降でアプリケーション・コン ティニュイティに対応。 以下のデータ・ソースで beginRequest()/endRequest()の追加不要。 Generic Data Souce Active GridLink Data Source • 内部的にUCPを使用しているのでFANにも対応 • WebLogic Suiteのライセンスが必要 UCP Data Source (WLS 12.2.1~) • FAN対応 • WLSの一部の機能がインテグレートされていない Oracle WebLogic Server Application Server Pool Generic Data Source Active GridLink Data Source UCP Data Source ACは接続ドライバの機能 (プールも関係する) Javaアプリケーション・サーバーではコネクション・プール 機能はアプリケーション・サーバーの役割
  32. Copyright © 2024, Oracle and/or its affiliates 38 どちらもUCPがベースでRAC連係機能(FAN)が有効 UCP

    Data SourceとActive GridLink Data Source Fast Connection Failover: FCF (高速接続フェイルオーバー) • Node/Public Network DOWNイベント • Service DOWNイベント • Service UPイベント Runtime Connection Load Balancing: RCLB (ランタイム接続ロード・バランス) • 負荷配分イベント指示に応じたプールからのコネクション取り出し • 物理コネクションの再作成 Web Session Affinity • 同一Web Sessionのリクエストを同一Oracleインスタンスに発行 XA Affinity • 同一XAトランザクションを同一Oracleインスタンスに発行 UCPが持っている機能 追加プログラミング不要で使 用可能な機能 • UCP Data Sourceで使 用可能 • Active GridLink Data Sourceで使用可能 追加プログラミング必要で使 用可能な機能 • Active GridLink Data Sourceで追加プログラミン グ不要で使用可能
  33. Copyright © 2024, Oracle and/or its affiliates 39 2020年3月時点で明示的にUCPのサポートが公開され ているもの:

    IBM WebSphere IBMのWebページにUCPの組み込み方が掲載されてい る。UCPがサポートされている記述がある。 https://www.ibm.com/support/pages/enabling-oracle-universal- connection-pooling-ucp-websphere-application-server NEC Web OTX マニュアルにV8.4からUCPをサポートする記述がある。 https://www.manuals.nec.co.jp/contents/system/files/nec_manuals/node/290/W ebOTX/101/html/index.html?/indexwithtoc.html&/update/old_update/v840/featu re.html これら以外のJavaアプリケーション・サーバーはコネクショ ン・プールにUCPを使用することを想定していない。 アプリケーション・サーバーの機能の一部を入れ替えることは基本的に想定されていない サード・パーティ製Javaアプリケーション・サーバーとUCP Application Server Pool コネクション・プールにUCPを使用 することが可能か(FAN対応) ACは接続ドライバの機能 (プールも関係する) Javaアプリケーション・サーバーではコネクション・プール 機能はアプリケーション・サーバーの役割
  34. Copyright © 2024, Oracle and/or its affiliates 40 AC/TACはOracleクライアントとOracleサーバーの連係機能 JDBC

    thinドライバでのAC/TAC リリース JDBC thinドライバのAC/TAC RAC 12c Release 1 Application Continuity実装 リクエスト境界のAPI記述を省略するにはUCPが 必要 Application Continuity実装 12c Release 2 (OCI/ODP.NETでもACを実装) (OCI/ODP.NETクライアントのACに対応) 18c Transparent Application Continuity実装 リクエスト境界のAPI記述を省略するにはUCPが 必要 Transparent Application Continuity 実装 19c Transparent Application Continuityがリクエ スト境界を自動判別するようになったのでUCPを使 わずともリクエスト境界のAPI記述を省略可能に なった TACのリクエスト境界の自動判別に対応 サード・パーティ製Javaアプリケーション・サーバーでUCPを使わずにbeginRequest()とendRequest()の埋め込みなし にするにはJDBC thin 19c + Oracle Database 19cでTransparent Application Continuityが必要。
  35. Copyright © 2024, Oracle and/or its affiliates 41 JDBCドライバとJDKのバージョン リリース

    JDBC thinドライバのAC/TAC JARファイルとJDKバージョン 12c Release 1 Application Continuity実装 リクエスト境界のAPI記述を省略するにはUCPが 必要 ojdbc7.jar with JDK 7 and JDK 8 ojdbc6.jar with JDK 6 12c Release 2 (OCI/ODP.NETでもACを実装) ojdbc8.jar with JDK 8 18c Transparent Application Continuity実装 リクエスト境界のAPI記述を省略するにはUCPが 必要 ojdbc8.jar with JDK8, JDK9, JDK10, JDK11 19c Transparent Application Continuityがリクエ スト境界を自動判別するようになったのでUCPを使 わずともリクエスト境界のAPI記述を省略可能に なった ojdbc10.jar with JDK10, JDK11 ojdbc8.jar with JDK8, JDK9, JDK11 JARファイルとJDKバージョンの対応 https://www.oracle.com/database/technologies/faq-jdbc.html What are the Oracle JDBC releases Vs JDK versions?
  36. Copyright © 2024, Oracle and/or its affiliates 43 • 可変オブジェクト

    • 副作用のあるプロシージャの扱い(アプリケーションのコードを修正するか) • 自律トランザクション(Autonomous Transaction) • アプリケーション・コンティニュイティで再実行できないケース アプリケーション・コード上の考慮点
  37. Copyright © 2024, Oracle and/or its affiliates 44 読みだすたびに値が変化するオブジェクト •

    SYSDATE, SYSTIMESTAMP (現在時刻) • SYS_GUID (一意な識別子) • SEQUENCE.NEXTVAL (一意な数値) 再実行時に使用されるのは元の値 再実行時に値が変化するとORA-41412のエラー 再実行前の値が保存される設定が必要 KEEP属性の指定(後述) 読みだすたびに値が変化する可変オブジェクトの再実行時の扱い 可変オブジェクト(Mutable Object) INSERT INTO tbl1 VALUES(SYSDATE); 障害検出 ACで自動再実行 時間 時刻t0 時刻t1 COMMIT; INSERTされるのはt0 or t1 ? ⇒ 元の時刻t0 INSERT INTO tbl1 VALUES(SYSDATE);
  38. Copyright © 2024, Oracle and/or its affiliates 45 再実行前の値が保持されるのでトランザクションとして矛盾しない 可変オブジェクトのKEEP属性

    SQL> INSERT INTO tbl1 VALUES(SYSDATE,1,seq1.NEXTVAL); 1行が作成されました。 SQL> SELECT * FROM tbl1; C1 C2 C3 ------------------- ---------- ---------- 2020/07/21 15:21:29 1 122 -- ALTER SYSTEM KILL SESSION SQL> SELECT * FROM tbl1; C1 C2 C3 ------------------- ---------- ---------- 2020/07/21 15:21:29 1 122 ここでALTER SYSTEM KILL SESSION ACでINSERTが再実行されても 再実行前の値が保持されている SYSDATEとSEQUENCE.NEXTVALを INSERT INSERTされた値を確認 (1) (2) (3) (4) セッション切断後にSQL実行 同じ値
  39. Copyright © 2024, Oracle and/or its affiliates 46 透過的アプリケーション・コンティニュイティではデフォルトで以下の動作になるためKEEP属性の設定をしなくともアプリケー ション・コンティニュイティが使用できる。

    • アプリケーションが直接SQLを発行する場合は再実行前の値が保持される。 • PL/SQL内でSQLを発行した場合は再実行前の値が保持されない。再実行後の値が採用される。 Autonomous Databaseでは権限がないためGRANT KEEPが発行できないが、19cではGRANT KEEPしなくともア プリケーション・コンティニュイティが構成可能。 可変オブジェクトのKEEP属性の設定 -- SEQUENCE所有ユーザー SQL> ALTER SEQUENCE sequence_object KEEP; -- 管理者ユーザー SQL> GRANT KEEP DATE TIME TO user; SQL> GRANT KEEP SYSGUID TO user; SQL> GRANT KEEP SEQUENCE on owner.sequence_object TO user;
  40. Copyright © 2024, Oracle and/or its affiliates 47 以下の具象クラスはJDBC Driver

    12.2まではACをサポートしていない。18cからサポートされた。 一般的にはSQL用のデータ型にはjava.sql.*のクラスが使用されるので、これらのoracle.sqlパッケージの具象クラスが 使用されていることはほとんどないはず。 • oracle.sql.CLOB • oracle.sql.NCLOB • oracle.sql.BLOB • oracle.sql.BFILE • oracle.sql.STRUCT • oracle.sql.REF • oracle.sql.ARRAY アプリケーション・コンティニュイティに対応していないクラスが一部ある Java
  41. Copyright © 2024, Oracle and/or its affiliates 48 アプリケーション・コンティニュイティでトランザクションが再実 行されるときにこれらのプロシージャも再実行するか。

    アプリケーション・コンティニュイティ • 再実行される • 再実行したくない場合はアプリケーションのコードに再 実行させないAPIを埋め込む • Java : disableReplay • OCI : OCIRequestDisableReplay • つまり制御可能 透過的アプリケーション・コンティニュイティ • 再実行されない • 動作が決め打ちで制御不可 DBMS外部に対し副作用を持つプロシージャを実行する とROLLBACKしても取り消せない。 ROLLBACKしても取り消せない処理を再実行させるか DBMS外部に対し副作用をもつプロシージャが含まれている場合 UTL_HTTP UTL_URL DBMS_FILE DBMS_FILE_TRANSFER UTL_SMTP UTL_TCP UTL_MAIL EXTPROC DBMS_PIPE DBMS_ALERT
  42. Copyright © 2024, Oracle and/or its affiliates 49 自律トランザクションはトランザクションの中で入れ子になったトランザクション。 自律トランザクション内でCOMMITされた変更は確定しているがアプリケーション・コンティニュイティで再実行すると自律ト

    ランザクションも再実行される。 自律トランザクション(Autonomous Transaction)は再実行される CREATE PROCEDURE dosomething (...) IS BEGIN autonomousprocedure(...) INSERT INTO tbl1 ... END; / CREATE PROCEDURE autonomousprocedure (...) IS PRAGMA AUTONOMOUS_TRANSACTION; BEGIN INSERT INTO tbl2 ... COMMIT; -- このプロシージャ内でのみ完結 END; / アプリケーション・ロジックのプロシージャ ロギング用自律トランザクションのプロシージャ アプリケーション・ロジックのプロシージャはROLLBACKさ れて再実行される 自律トランザクションでCOMMITされた更新はそのままで再 実行される
  43. Copyright © 2024, Oracle and/or its affiliates 50 Oracle Database

    19c Database エラー・メッセージ https://docs.oracle.com/cd/F19136_01/errmg/ORA-41001.html#GUID-658C153A-91D4-42B9-85D8- E500A7155A33 ORA-41408: 最後のコールにCOMMITが埋め込まれていました。フェイルオーバーを続行できません ORA-41409: コミットされたトランザクションを再実行できません。フェイルオーバーを続行できません ORA-41410: コールによりトランザクションがコミットされ、新しいトランザクションが開始されました。フェイルオーバーを続行できません ORA-41411: リクエスト内のラウンド・トリップが多すぎます。再実行が無効化されました ORA-41412: 再実行中に結果が変更されました。フェイルオーバーを続行できません ORA-41413: コール取得内のデータが多すぎます。再実行が無効化されました ORA-41425: リプレイは、トランザクション処理モニター(TPM)によって管理された2フェーズ・コミット(2PC)を使用したグローバル・トラン ザクションに対して無効です ORA-41429: 失敗した接続で再実行できない副次的作用 ORA-41431: アプリケーション・コンティニュイティでは、ISOLATION_LEVEL=SERIALIZABLEはサポートされません。フェイルオー バーを続行できません。 エラー・コードから見る制限事項
  44. Copyright © 2024, Oracle and/or its affiliates 51 アプリケーション・コンティニュイティが想定するコード: 1.

    Oracle製コネクション・プールからコネクション取得 • Javaでは場合分けが発生(後述) 2. DML発行 3. 最後に1回だけCOMMIT 4. コネクション・プールに返却 一般的なオンライン・トランザクション処理ならばこうなって いるはず。 コネクション・プールからコネクションを取得し、返却するま でをリクエスト境界と呼ぶ。 アプリケーション・コンティニュイティが再実行するのはリクエ スト境界の先頭から。 リクエスト境界の概念 アプリケーション・コンティニュイティ ConnectionPool ConnectionPool getConnection() close() DML 1 DML n COMMIT リクエスト境界 この形でないと何が起こる?
  45. Copyright © 2024, Oracle and/or its affiliates 52 1リクエスト境界内で複数回COMMITしている場合はアプリケーション・コンティニュイティで再実行できない。 再接続するとCOMMIT完了したところまでは確定してしまっているため全体を再実行できない。

    バッチ処理にあり得るケース 再実行できないケース: 複数回COMMIT ORA-41408 CREATE PROCEDURE multicommit (...) IS BEGIN FOR i IN 1..itelation LOOP INSERT INTO ... ; COMMIT; END LOOP; END; / COMMITが複数 回発行される ORA-41408: 最後のコールにCOMMITが埋め込ま れていました。フェイルオーバーを 続行できません COMMIT COMMIT COMMIT END BEGIN COMMITされたところまで は確定しているので全体を 再実行できない
  46. Copyright © 2024, Oracle and/or its affiliates 53 1リクエスト境界内で複数回COMMITしている場合はアプリケーション・コンティニュイティで再実行できない。 再接続するとCOMMIT完了したところまでは確定してしまっているため全体を再実行できない。

    バッチ処理にあり得るケース 再実行できないケース: 複数回COMMIT ORA-41409 SQL> INSERT INTO tbl1 VALUES(SYSDATE,1,seq1.nextval); SQL> COMMIT; SQL> INSERT INTO tbl1 VALUES(SYSDATE,1,seq1.nextval); SQL> SELECT * FROM tbl1; SELECT * FROM tbl1 * 行1でエラーが発生しました。: ORA-41409: コミットされたトランザクションを再実行できません。フェイルオーバーを続行できません ここでALTER SYSTEM KILL SESSION セッション切断後にSQL発行 COMMIT後にDML発行
  47. Copyright © 2024, Oracle and/or its affiliates 54 アプリケーション・コンティニュイティ対応のOracle接続ドライバはリクエスト境界中にOracleサーバーに発行した処理を記 憶している。

    OCIクライアント(OCI Session PoolとODP.Net Unmanaged Driver)はメモリ枯渇が発生しないように1リクエスト 境界中に発行できる処理数に上限が設けられている。 これを超えてアプリケーション・コンティニュイティが発動するとORA-25420になる。 バッチ処理などで大量のSQLを発行している場合やSELECT文が大量の行を返す場合にこれに抵触することがある。 対処策 アプリケーション・ロジックをストアド・プロシージャ化する (接続ドライバからのcall回数が減る) SELECT文が多数の行を返す場合にarray fetchのサイズを大きくする (FETCHのcall回数が減る) OCIクライアント側もRU19.11以降を適用する。 1リクエスト境界中の処理発行数に上限がある 再実行できないケース: (OCIクライアントのみ)コール回数が多い ORA-25420
  48. Copyright © 2024, Oracle and/or its affiliates 55 再実行できないケース: 分散トランザクションには未対応

    DB-A DB-B Service-A Service-B データベース・クライアント XAで分散トランザクション DB-A DB-B Service-A Service-B データベース・クライアント データベース・リンク ※ JDBC replay XAドライバがAC対応と言っているのは 1つのデータベースのみのトランザクションの場合 ※ データベース・リンクは内部的には分散トランザクション
  49. Copyright © 2024, Oracle and/or its affiliates 56 データベース・リンク越しのアクセスがあると再実行できない 再実行できないケース:

    データベース・リンク越しのアクセスがある ORA-41429 SQL> select * from tdblink@dblink2tac; SQL> select * from tdblink@dblink2tac; select * from tdblink@dblink1 * 行1でエラーが発生しました。: ORA-41429: 失敗した接続で再実行できない副次的作用 ここでインスタンスをクラッシュ セッション切断後にSQL発行 データベース・リンク越しの表にアクセス
  50. Copyright © 2024, Oracle and/or its affiliates 57 自動再実行できないケースは、自動再実行されずにエラーになる。 COMMITを複数回実行しているケースでも二重再実行されない安全装置が付いている。

    自動再実行できるケース • ほとんどのトランザクション系アプリケーションは自動再実行できる 自動再実行できないケース • エラーになり再実行されない • アプリケーション・コンティニュイティがない場合と同じ エラーになるという点ではアプリケーション・コンティニュイティがない場合と同じ アプリケーション・コンティニュイティで自動再実行できないケース アプリケーション・コンティニュイティはほとんどリスクなしにアプリケーションが観測する障害エラーを軽減できる
  51. Copyright © 2024, Oracle and/or its affiliates 59 再実行時に値が変化するとORA-41412のエラーになる。 アプリケーション・コンティニュイティは再実行前の値が保存されている必要がある。

    可変オブジェクトでKEEP属性を設定したのはこのため。 V$INSTANCEの値(接続しているOracleインスタンスの情報)を読まないこと。 一般的なアプリケーションではV$INSTANCEにアクセスするようなことはないが、検証だと「このコネクションが接続している Oracleインスタンスはどれか」を調べたくなるのでV$INSTANCEの値を読むSQLを埋め込む場合がある。 RAC構成でOracleサーバーに障害が発生し再接続すると異なるOracleインスタンスに接続されるためV$INSTANCE が返す値が変化する。 アプリケーション・コンティニュイティの検証をするときの注意点 再実行できないケース: 再実行時に値が変化した ORA-41412
  52. Copyright © 2024, Oracle and/or its affiliates 60 動作検証などでOracleインスタンスを停止させる以外でセッションを切断する方法 1本のセッションを指定して切断

    1. V$SESSIONから切断したいセッションのSIDとSERIAL#を特定 2. ALTER SYSTEM KILL SESSION 'sid, serial#'; Autonomous Databaseではこの方法のみ可能(その他の手段の権限がない) 再実行させたくない場合はNOREPLAYを指定する ALTER SYSTEM KILL SESSION ‘sid, serial#‘ NOREPLAY; ORA-00045: セッションは、再実行せずに終了しました。 特定のサービスに接続しているすべてのセッションを切断 EXECUTE DBMS_SERVICE.DISCONNECT_SESSION(‘service’, DBMS_SERVICE.IMMEDIATE); 再実行させたくない場合はNOREPLAYを指定する EXECUTE DBMS_SERVICE.DISCONNECT_SESSION(‘service’, DBMS_SERVICE.NOREPLAY); アプリケーション・コンティニュイティはセッションが切断されたことを検出すると発動する セッションを切断する操作
  53. Copyright © 2024, Oracle and/or its affiliates 61 サービスを設定するsrvctlコマンドはOracle Grid

    Infrastructureが必要。 アプリケーション・コンティニュイティを使用するにはEE RAC もしくはActive Data Guardのライセンスが必要である が、実験するための技術的な最低要件はEnterprise Editionであること。 Oracle Grid Infrastructureをインストールしていない シングル・インスタンス構成でも、サービスを設定する DBMS_SERVICEパッケージのプロシージャを使用してア プリケーション・コンティニュイティの設定をすることは可能。 Enterprise Editionであればアプリケーション・コンティニュイティは実験可能 シングル・インスタンス構成でアプリケーション・コンティニュイティを試したい Oracle インスタンス service_A oracle Oracleクライアント Oracleサーバー ALTER SYSTEM KILL SESSIONで切断 DBMS_SERVICEで設定
  54. Copyright © 2024, Oracle and/or its affiliates 62 Oracle Grid

    Infrastructureが構成されている環境ではsrvctlコマンドは内部的にDBMS_SERVICEパッケージのプ ロシージャを実行しているため、ユーザーはこれらのプロシージャを実行してはならない。状態に矛盾が生じるため。 Oracle Database 19c PL/SQLパッケージおよびタイプ・リファレンス https://docs.oracle.com/cd/F19136_01/arpls/DBMS_SERVICE.html#GUID-5AF6F739-9543- 42F0-8745-D7650809AB4F サービスの設定をsrvctlコマンドを使用せずに行う シングル・インスタンス構成でアプリケーション・コンティニュイティを試したい 148.4 DBMS_SERVICEのプロシージャの使用 次のプロシージャは、Oracle Real Applications Clusterware、Oracle RestartおよびOracle Global Data Servicesとともには使用できません。 • CREATE_SERVICEプロシージャ • DELETE_SERVICEプロシージャ • MODIFY_SERVICEプロシージャ • START_SERVICEプロシージャ • STOP_SERVICEプロシージャ
  55. Copyright © 2024, Oracle and/or its affiliates 63 DBMS_SERVICEを使ってサービスを構成する例 シングル・インスタンス構成でアプリケーション・コンティニュイティを試したい

    -- サービスを構成したいPDBに移動 alter session set container=sipdb19a1; -- サービス作成 execute DBMS_SERVICE.CREATE_SERVICE('pdba1svc2ac','pdba1svc2ac’); -- サービスのパラメータを用意して設定 declare params DBMS_SERVICE.SVC_PARAMETER_ARRAY; begin params('FAILOVER_TYPE'):='TRANSACTION'; params('REPLAY_INITIATION_TIMEOUT'):=1800; params('RETENTION_TIMEOUT'):=604800; params('commit_outcome'):='true'; params('aq_ha_notifications'):='true'; DBMS_SERVICE.MODIFY_SERVICE('pdba1svc2ac',params); end; / -- サービス起動 execute DBMS_SERVICE.START_SERVICE('pdba1svc2ac');
  56. Copyright © 2024, Oracle and/or its affiliates 64 UCPのトレース・レベルをFINESTにすると、(T)ACで自動再接続するセッションでRECONNECTINGというメッセージが 出力される。

    2023-08-03 14:11:17.643 FINEST oracle.ucp.logging.ClioSupport _log oracle.ucp.jdbc.oracle.OracleReplayableConnectionConnectionPool:initialize:oracle.ucp.jdbc.ora cle.OracleReplayableConnectionConnectionPool@6a1079f:AC initialize(): found UPC for oracle.jdbc.driver.T4CConnection@5c609d68, status: RECONNECTING 2023-08-03 14:11:17.643 FINEST oracle.ucp.logging.ClioSupport _log :::instance start time string: 2023-03-17 23:37:11 GMT+00:00 2023-08-03 14:11:17.644 FINEST oracle.ucp.logging.ClioSupport _log oracle.ucp.jdbc.oracle.OracleReplayableConnectionConnectionPool:initialize:oracle.ucp.jdbc.ora cle.OracleReplayableConnectionConnectionPool@6a1079f:AC initialize(): metadata update done for oracle.jdbc.driver.T4CConnection@5c609d68, status: NORMAL UCPのトレース JDBC thin接続の(T)ACで自動再接続されたセッションを判別する方法
  57. Copyright © 2024, Oracle and/or its affiliates 65 セッション切断を検出するとOracle接続ドライバが (1)再接続

    (2)トランザクション状態の確認 (3)トランザクション再実行 まで自動で行う。 アプリケーションから見るとエラーを検出せずにトランザクショ ンが完了する。 • COMMIT時のタイミング依存のケースも安全に処理 • 可変オブジェクトを使用してもデータが矛盾しない 一般的なWebアプリケーションならばアプリケーション・コー ドの改修は不要。 それ以外の操作が含まれているといくつかの考慮点が発 生する。 更新トランザクションを安全に自動再実行 アプリケーション・コンティニュイティ (1) 再接続 (2) 状態確認 (3) 再実行 Oracleクライアント RAC SELECT INSERT UPDATE COMMIT