アプリケーション・コンティニュイティ

 アプリケーション・コンティニュイティ

https://oracle-code-tokyo-dev.connpass.com/event/186771/
Oracle Maximum Availability Architecture (MAA) は、Oracleの実証済み高可用性テクノロジと推奨事項に基づいた Oracleのベスト・プラクティスのブループリントであり、
これはクラウドでもオンプレミスでも基本的な考え方は変わりません。
本スライドはOracle Databaseの高可用性機能の一つであるアプリケーション・コンティニュイティについて詳細に解説しています。

Oracle Cloud Infrastructure / OCI / Oracle Database
Database Cloud Service / DBCS
Exadata Cloud Service / ExaCS
Autonomous Database / ADB
Oracle Application Continuity

3115a782126be714b5f94d24073c957d?s=128

oracle4engineer

September 25, 2020
Tweet

Transcript

  1. 2020年9月25日 日本オラクル株式会社 日下部明 セッション異常切断時の更新トランザクション自動再実行 アプリケーション・コンティニュイティ

  2. 以下の事項は、弊社の一般的な製品の方向性に関する概要を説明するものです。また、情報提供を唯一の目的とする ものであり、いかなる契約にも組み込むことはできません。以下の事項は、マテリアルやコード、機能を提供することを確約 するものではないため、購買決定を行う際の判断材料になさらないで下さい。 オラクル製品に関して記載されている機能の開発、リリース、時期及び価格については、弊社の裁量により決定され、変 更される可能性があります。 Safe harbor statement Copyright ©

    2020, Oracle and/or its affiliates 2
  3. Copyright © 2020, Oracle and/or its affiliates 3 基本からわかる!高性能×高可用性データベースシステムの作り方 https://blogs.oracle.com/otnjp/kusakabe-index

    翔泳社 これは使えるOracle新機能活用術 (DB Magazine連載記事をまとめたもの) 日本オラクル株式会社 日下部明 @akirak00 主にOracle Databaseの高可用性領域 RAC、ASM、Data Guard、RMAN、 Oracle Net等々とベンチマークを担当 講師
  4. Copyright © 2020, Oracle and/or its affiliates 4 概要 •

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

  6. Copyright © 2020, Oracle and/or its affiliates 6 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)
  7. Copyright © 2020, Oracle and/or its affiliates 7 セッションが切断されても自動再接続&更新トランザクション自動再実行 アプリケーション・コンティニュイティ

    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) アプリケーションからは何も起きて いないように見える
  8. Copyright © 2020, Oracle and/or its affiliates 8 アプリケーションはエラーになる 更新トランザクションの途中で異常終了するとROLLBACKされる

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

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

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

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

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

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

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

    Oracle接続ドライバがセッション切断を検出すると自動 再接続。 COMMIT時の障害はトランザクション・ガードでトランザク ションの状態を確認してCOMMIT完了していなければト ランザクションを自動再実行。 Oracle接続ドライバがセッション切断を検出すると (1) 再接続 (2) トランザクション状態の確認 (3) トランザクション再実行 まで自動で行う。 アプリケーションから見るとエラーを検出せずにトランザ クションが完了する。 更新トランザクションを安全に自動再実行 アプリケーション・コンティニュイティ (1) 再接続 (2) 状態確認 (3) 再実行 Oracleクライアント RAC SELECT INSERT UPDATE COMMIT
  16. Copyright © 2020, Oracle and/or its affiliates 16 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: オプション込み オンプレミス: 要オプション
  17. 構成 アプリケーション・コンティニュイティ

  18. Copyright © 2020, Oracle and/or its affiliates 18 Oracleクライアント •

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

    Real Application Clusters管理およびデプロイメント・ガイド データベース・クライアント側 (アプリケーション・コンティニュイティ対応の各言語用接続ドライバ) • JDBC開発者ガイド • Data Provider for .NET開発者ガイド • Oracle Call Interfaceプログラマーズ・ガイド アプリケーション・コンティニュイティの関連マニュアル
  20. データベース・サーバー側 アプリケーション・コンティニュイティの構成

  21. Copyright © 2020, Oracle and/or its affiliates 21 • アプリケーション・コンティニュイティはサービスの属性として設定

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

    Application Continuity (12c Release 1~) • Oracleサーバー障害を検出すると自動再接続しトランザクションを自動再実行 • DBMS外部に副作用のあるプロシージャの再実行を制御可能 透過的アプリケーション・コンティニュイティ / Transparent Application Continuity (18c~) • アプリケーション・コンティニュイティで制御可能だったいくつかの動作を決め打ち • ほとんどのアプリケーションで適用可能な動作 • リプレイ境界(後述)を自動挿入 • サード・パーティ製Javaアプリケーション・サーバーでもコード修正なしに使用可能(19c~) 2種類の動作モード アプリケーション・コンティニュイティ
  23. Copyright © 2020, Oracle and/or its affiliates 23 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 -failoverretry 30 -failoverdelay 10 -commit_outcome TRUE -replay_init_time 1800 -retention 86400
  24. Copyright © 2020, Oracle and/or its affiliates 24 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
  25. Copyright © 2020, Oracle and/or its affiliates 25 サービスの属性で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
  26. Copyright © 2020, Oracle and/or its affiliates 26 サービスの属性 -commit_outcome

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

    DatabaseはExadataを基盤としており、つまりEnterprise Edition RAC。 アプリケーション・コンティニュイティに対応しているが、srvctlコマンド操作ができないので専用の設定プロシージャが用意さ れている。サービス名を指定するとそのサービスで有効になる。ただしShared Infrastructureでは動作モードはAC決め 打ち。 OSコマンド(srvctl)操作ができないのでAC/TAC設定用のプロシージャが用意されている Oracle Autonomous Database BEGIN DBMS_CLOUD_ADMIN.ENABLE_APP_CONT( service_name => ‘adb1_high.adwc.oraclecloud.com‘ ); END; / Autonomous Database 動作モード 設定プロシージャ Shared Infrastructure AC DBMS_CLOUD_ADMIN.ENABLE_APP_CONT() Dedicated Infrastructure AC DBMS_APP_CONT_ADMIN.ENABLE_AC() TAC ※ DBMS_APP_CONT_ADMIN.ENABLE_TAC() ※Dedicated InfrastructureではTP, TP_TLS, TPURGENT, TPURGENT_TLSのサービスはデフォルトでTACが有効
  28. Copyright © 2020, Oracle and/or its affiliates 28 サービスに関するビュー 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
  29. データベース・クライアント側 アプリケーション・コンティニュイティの構成

  30. Copyright © 2020, Oracle and/or its affiliates 30 • リクエスト境界の概念

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

    Oracle製コネクション・プールからコネクション取得 • Javaでは場合分けが発生(後述) 2. DML発行 3. 最後に1回だけCOMMIT 4. コネクション・プールに返却 一般的なオンライン・トランザクション処理ならばこうなって いるはず。 コネクション・プールからコネクションを取得し、返却するま でをリクエスト境界と呼ぶ。 アプリケーション・コンティニュイティが再実行するのはリクエ スト境界の先頭から。 リクエスト境界の概念 アプリケーション・コンティニュイティ ConnectionPool ConnectionPool getConnection() close() DML 1 DML n COMMIT リクエスト境界
  32. Copyright © 2020, Oracle and/or its affiliates 32 リクエスト境界の概念(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挿入が不要。
  33. Copyright © 2020, Oracle and/or its affiliates 33 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は非対応 アプリケーション・コンティニュイティ対応クライアント
  34. Copyright © 2020, Oracle and/or its affiliates 34 コネクション・プール機能はどの階層の持ち物か 言語によって事情が異なる

    Application Server Pool Application Server Pool Javaアプリケーション・サーバー • JDBC thinドライバ Java以外のアプリケーション・サーバー • OCI Session Pool • ODP.NET Unmanaged Driver • コネクション・プール機能はアプリケーション・サーバーの役割。 • UCPが使用できるかで場合分けが発生。 • コネクション・プール機能はOracle接続ドライバと一体。 • リクエスト境界のAPI挿入無しでACが使用可能。
  35. Copyright © 2020, Oracle and/or its affiliates 35 コネクション・プールだけのjarファイルを提供 Oracle

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

    12.1.2以降でアプリケーション・コン ティニュイティに対応。 Generic Data Souce • beginRequest()/endRequest()の追加不要。 Active GridLink Data Source • beginRequest()/endRequest()の追加不要。 • 内部的にUCPを使用しているのでFANにも対応。 Oracle WebLogic Server Application Server Pool Generic Data Source Active GridLink Data Source ACは接続ドライバの機能 (プールも関係する) Javaアプリケーション・サーバーではコネクション・プール 機能はアプリケーション・サーバーの役割
  37. Copyright © 2020, Oracle and/or its affiliates 37 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アプリケーション・サーバーではコネクション・プール 機能はアプリケーション・サーバーの役割
  38. Copyright © 2020, Oracle and/or its affiliates 38 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が必要。
  39. Copyright © 2020, Oracle and/or its affiliates 39 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?
  40. アプリケーション・コード上の考慮点 アプリケーション・コンティニュイティの構成

  41. Copyright © 2020, Oracle and/or its affiliates 41 • 可変オブジェクト

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

    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);
  43. Copyright © 2020, Oracle and/or its affiliates 43 再実行前の値が保持されるのでトランザクションとして矛盾しない 可変オブジェクトの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実行 同じ値
  44. Copyright © 2020, Oracle and/or its affiliates 44 19cではデフォルトで以下の動作になるためKEEP属性の設定をしなくともアプリケーション・コンティニュイティが使用できる。 •

    アプリケーションが直接SQLを発行する場合は再実行前の値が保持される。 • PL/SQL内でSQLを発行した場合は再実行前の値が保持されない。再実行後の値が採用される。 Autonomous Databaseでは権限がないためGRANT KEEPが発行できないが、19cではGRANT KEEPしなくともア プリケーション・コンティニュイティが構成可能。 Oracle Database 19cでは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;
  45. Copyright © 2020, Oracle and/or its affiliates 45 以下の具象クラスは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
  46. Copyright © 2020, Oracle and/or its affiliates 46 アプリケーション・コンティニュイティでトランザクションが再実 行されるときにこれらのプロシージャも再実行するか。

    アプリケーション・コンティニュイティ • 再実行される • 再実行したくない場合はアプリケーションのコードに再 実行させない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
  47. Copyright © 2020, Oracle and/or its affiliates 47 自律トランザクションはトランザクションの中で入れ子になったトランザクション。 自律トランザクション内で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された更新はそのままで再 実行される
  48. Copyright © 2020, Oracle and/or its affiliates 48 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-41431: アプリケーション・コンティニュイティでは、ISOLATION_LEVEL=SERIALIZABLEはサポートされません。 フェイルオーバーを続行できません。 エラー・コードから見る制限事項
  49. Copyright © 2020, Oracle and/or its affiliates 49 アプリケーション・コンティニュイティが想定するコード: 1.

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

  53. Copyright © 2020, Oracle and/or its affiliates 53 再実行時に値が変化するとORA-41412のエラーになる。 アプリケーション・コンティニュイティは再実行前の値が保存されている必要がある。

    可変オブジェクトでKEEP属性を設定したのはこのため。 V$INSTANCEの値(接続しているOracleインスタンスの情報)を読まないこと。 一般的なアプリケーションではV$INSTANCEにアクセスするようなことはないが、検証だと「このコネクションが接続している Oracleインスタンスはどれか」を調べたくなるのでV$INSTANCEの値を読むSQLを埋め込む場合がある。 RAC構成でOracleサーバーに障害が発生し再接続すると異なるOracleインスタンスに接続されるためV$INSTANCE が返す値が変化する。 アプリケーション・コンティニュイティの検証をするときの注意点 再実行できないケース: 再実行時に値が変化した ORA-41412
  54. Copyright © 2020, Oracle and/or its affiliates 54 動作検証などで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); アプリケーション・コンティニュイティはセッションが切断されたことを検出すると発動する セッションを切断する操作
  55. Copyright © 2020, Oracle and/or its affiliates 55 サービスを設定する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で設定
  56. Copyright © 2020, Oracle and/or its affiliates 56 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 Enterprise Editionであればアプリケーション・コンティニュイティは実験可能 シングル・インスタンス構成でアプリケーション・コンティニュイティを試したい 148.4 DBMS_SERVICEのプロシージャの使用 次のプロシージャは、Oracle Real Applications Clusterware、Oracle RestartおよびOracle Global Data Servicesとともには使用できません。 • CREATE_SERVICEプロシージャ • DELETE_SERVICEプロシージャ • MODIFY_SERVICEプロシージャ • START_SERVICEプロシージャ • STOP_SERVICEプロシージャ
  57. Copyright © 2020, Oracle and/or its affiliates 57 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('FAILOVER_DELAY'):=10; params('FAILOVER_RETRIES'):=30; params('commit_outcome'):='true'; params('aq_ha_notifications'):='true'; DBMS_SERVICE.MODIFY_SERVICE('pdba1svc2ac',params); end; / -- サービス起動 execute DBMS_SERVICE.START_SERVICE('pdba1svc2ac');
  58. Copyright © 2020, Oracle and/or its affiliates 58 セッション切断を検出するとOracle接続ドライバが (1)再接続

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