Application Continuity を sqlplus と Autonomous Database の ATP で試してみる。(Oracle Cloud Infrastructure)

昨日の Oracle Tech Night(下記) は実にディープな内容でした。
その余勢を駆って、Application Continuity を検証してみたやで彡(^)(^)

> MAA - アプリケーションの継続性
> https://oracle-code-tokyo-dev.connpass.com/event/186771/
> 
> oracle4engineer - アプリケーション・コンティニュイティ(Speakerdeck)
> https://speakerdeck.com/oracle4engineer/apurikesiyonkonteiniyuitei

# 1. Application Continuity とは？

Application Continuity は Oracle Database の高可用性機能の一つで、トランザクションでエラーが発生した際に、
そのエラーをクライアント側に返すことなく、透過的に再実行する機能となります。

> アプリケーション・コンティニュイティ
> https://www.oracle.com/technetwork/jp/database/options/clustering/applicationcontinuity/overview/ac-overview-1967264-ja.html
> 
> 6 アプリケーション・コンティニュイティの確保
> https://docs.oracle.com/cd/E82638_01/racad/ensuring-application-continuity.html#GUID-C1EF6BDA-5F90-448F-A1E2-DC15AD5CFE75

# 2. 参考ドキュメント／マニュアル

以下のマニュアルやドキュメントを参考にしてみました。彡(ﾟ)(ﾟ)

> アプリケーション・コンティニュイティの有効化および無効化
> https://docs.oracle.com/cd/E83857_01/paas/atp-cloud/atpug/application-continuity.html#GUID-8874CB1D-0B20-461F-91D2-24E2EE4148A3
> > DBMS_CLOUD_ADMIN.ENABLE_APP_CONTを使用して、選択したサービスでアプリケーション・コンティニュイティを有効にします。
> 
> 6.3.2.6 SQL*Plusによるアプリケーション・コンティニュイティの使用
> https://docs.oracle.com/cd/E82638_01/racad/ensuring-application-continuity.html#GUID-A16F0586-D9A1-48E2-9FAA-7154C361FF5C
> > 次に示すように、-acフラグを使用します。
> > sqlplus -ac user/password@ACservice


# 3. サンプルプログラムの実行 と ATP再起動

以下のサンプルプログラムを動かしてみます。1行 INSERT して1秒ずつスリープする簡単な SQL ……

```sql
sqlplus /nolog

CONNECT ADMIN/xxxxxxxxxxxxxx@aysatp1_tp

SET TIMING ON;

CREATE TABLE TBL1 (C1 NUMBER);

BEGIN
  FOR i IN 1..60
  LOOP
    INSERT INTO TBL1 VALUES(i);
    DBMS_LOCK.SLEEP(1);
  END LOOP;
  COMMIT;
END;
/
```

これを動かした状態で ATP を Console から Restart すると……
![AC001.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110066/529270df-651a-eaaa-827e-adcba91f9b18.jpeg)

```sql
ERROR at line 1:
ORA-03113: end-of-file on communication channel
Process ID: 61009
Session ID: 15678 Serial number: 18067

Elapsed: 00:00:29.11
```

ORA-3113 を検知して、エラーになります。

# 4. Application Continuity の有効化(DBMS_CLOUD_ADMIN.ENABLE_APP_CONT の実行)

Autonomous Database で Application Continuity を有効化するには、サービス名を確認して
そのサービスに対して DBMS_CLOUD_ADMIN.ENABLE_APP_CONT を実行します。

```sql
SELECT name, drain_timeout FROM v$services;

BEGIN
    DBMS_CLOUD_ADMIN.ENABLE_APP_CONT(
        service_name => 'NTNCQ7OHFQU238D_AYSATP1_tp.adb.oraclecloud.com'
    );
END;
/

SELECT name, drain_timeout FROM v$services;
```

これを実行すると……彡(ﾟ)(ﾟ)

```sql
NAME                                                             DRAIN_TIMEOUT
---------------------------------------------------------------- -------------
NTNCQ7OHFQU238D_AYSATP1_tp.adb.oraclecloud.com                               0
ntncq7ohfqu238d_aysatp1                                                      0
NTNCQ7OHFQU238D_AYSATP1_tpurgent.adb.oraclecloud.com                         0
NTNCQ7OHFQU238D_AYSATP1_low.adb.oraclecloud.com                              0
NTNCQ7OHFQU238D_AYSATP1_high.adb.oraclecloud.com                             0
NTNCQ7OHFQU238D_AYSATP1_medium.adb.oraclecloud.com                           0

PL/SQL procedure successfully completed.

NAME                                                             DRAIN_TIMEOUT
---------------------------------------------------------------- -------------
NTNCQ7OHFQU238D_AYSATP1_tp.adb.oraclecloud.com                             300
ntncq7ohfqu238d_aysatp1                                                      0
NTNCQ7OHFQU238D_AYSATP1_tpurgent.adb.oraclecloud.com                         0
NTNCQ7OHFQU238D_AYSATP1_low.adb.oraclecloud.com                              0
NTNCQ7OHFQU238D_AYSATP1_high.adb.oraclecloud.com                             0
NTNCQ7OHFQU238D_AYSATP1_medium.adb.oraclecloud.com                           0
```

DRAIN_TIMEOUT が 0 ⇒ 300 になりました。

# 5. サンプルプログラム(その2) の実行 と ATP再起動

サンプルプログラム(その2) を実行して、ATP を再起動してみます。
その2 と言っても、sqlplus に -ac オプションを付けただけ。
彡(ﾟ)(ﾟ)

```sql
sqlplus -ac /nolog

CONNECT ADMIN/xxxxxxxxxxxxxx@aysatp1_tp

SET TIMING ON;

BEGIN
  FOR i IN 1..60
  LOOP
    INSERT INTO TBL1 VALUES(i);
    DBMS_LOCK.SLEEP(1);
  END LOOP;
  COMMIT;
END;
/

SELECT COUNT(*) FROM TBL1;
```

これを動かした状態で ATP を Console から Restart すると……
![AC001.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110066/529270df-651a-eaaa-827e-adcba91f9b18.jpeg)

```sql
PL/SQL procedure successfully completed.

Elapsed: 00:02:03.16

  COUNT(*)
----------
        60
```

再起動分の時間が掛かっていますが、プログラム自体は正常終了してレコードも挿入されています。やったぜ。彡(^)(^)

# 6. まとめ

Application Continuity を Autonomous Database で動かせたやで！
今回は sqlplus + PL/SQL で検証してみましたが、次は Java(ucp.jar) でチャレンジしてみたいなぁ……彡(ﾟ)(ﾟ)