[OCI]毎日決まった時間に行うCPU自動スケーリングのオン/オフをAutonomous Database単体で実現してみた


# はじめに
Autonomous DatabaseにはCPUの自動スケーリングという便利な機能があります。

https://docs.oracle.com/ja-jp/iaas/autonomous-database-shared/doc/autonomous-add-resources.html

この機能を使用すると、自動スケーリングが無効な状態で動作しているAutonomous Datbaseと比較して、ワークロードの要求を満たすために最大3倍のCPUおよびIOリソースを自動的に使用できます。
そのため、ピーク負荷に合わせたリソースをあらかじめ準備する必要がないため、コスト効率よくサービスが利用できます。

今回は、CPUの自動スケーリングの有効化/無効化を毎日決まった時間を行いたいというご要望があったため、Oracle Cloud Infrastructure SDK for PL/SQL a.k.a. PL/SQL SDKを使用してAutonomous Database単体で実現する方法を検証してみました。

# 1. CPUの自動スケーリングを有効化するPL/SQLプロシージャの作成
プロシージャを実行するAutonomous DatabaseのCPUの自動スケーリングをオンにするプロシージャ「enable_cpu_autoscaling」を作成します。

```sql:プロシージャ enable_cpu_autoscaling
CREATE OR REPLACE PROCEDURE enable_cpu_autoscaling
IS
	autonomous_database_details	dbms_cloud_oci_database_update_autonomous_database_details_t;
	response					dbms_cloud_oci_db_database_update_autonomous_database_response_t;
	target_adb_region           VARCHAR2(200);
	target_adb_ocid             VARCHAR2(200);

BEGIN
-- ADBのリージョン、OCIDを取得
    SELECT json_value(cloud_identity, '$.REGION'), LOWER(json_value(cloud_identity, '$.DATABASE_OCID'))
      INTO target_adb_region, target_adb_ocid FROM v$pdbs;
-- 変数の初期化
	autonomous_database_details := dbms_cloud_oci_database_update_autonomous_database_details_t();
-- CPU自動スケーリングをオンに設定
	autonomous_database_details.is_auto_scaling_enabled := 1;
-- ADBのリージョン、OCIDを指定してCPU自動スケーリングの設定を実行
	response := DBMS_CLOUD_OCI_DB_DATABASE.UPDATE_AUTONOMOUS_DATABASE (
		          autonomous_database_id             => target_adb_ocid,
		          update_autonomous_database_details => autonomous_database_details,
		          region                             => target_adb_region,
		          credential_name                    => 'OCI$RESOURCE_PRINCIPAL'
	);
END;
/
```

# 2. CPUの自動スケーリングを無効化するPL/SQLプロシージャの作成
プロシージャを実行するAutonomous DatabaseのCPUの自動スケーリングをオフにするプロシージャ「disable_cpu_autoscaling」を作成します。

```sql:プロシージャ disable_cpu_autoscaling
CREATE OR REPLACE PROCEDURE disable_cpu_autoscaling
IS
	autonomous_database_details	dbms_cloud_oci_database_update_autonomous_database_details_t;
	response					dbms_cloud_oci_db_database_update_autonomous_database_response_t;
	target_adb_region           VARCHAR2(200);
	target_adb_ocid             VARCHAR2(200);

BEGIN
-- ADBのリージョン、OCIDを取得
    SELECT json_value(cloud_identity, '$.REGION'), LOWER(json_value(cloud_identity, '$.DATABASE_OCID'))
      INTO target_adb_region, target_adb_ocid FROM v$pdbs;
-- 変数の初期化
	autonomous_database_details := dbms_cloud_oci_database_update_autonomous_database_details_t();
-- CPU自動スケーリングをオフに設定
	autonomous_database_details.is_auto_scaling_enabled := 0;
-- ADBのリージョン、OCIDを指定してCPU自動スケーリングの設定を実行
	response := DBMS_CLOUD_OCI_DB_DATABASE.UPDATE_AUTONOMOUS_DATABASE (
		          autonomous_database_id             => target_adb_ocid,
		          update_autonomous_database_details => autonomous_database_details,
		          region                             => target_adb_region,
		          credential_name                    => 'OCI$RESOURCE_PRINCIPAL'
	);
END;
/
```

# 3. CPUの自動スケーリングを有効化するPL/SQLプロシージャの自動実行の設定
DBMS_SCHEDULERを使用して、毎日決まった時間にCPUの自動スケーリングを有効化するPL/SQLプロシージャ「enable_cpu_autoscaling」を自動実行するジョブ「ENABLE_CPU_AUTOSCALING_JOB」を作成します。
この例では、日本時間2023/3/8 8時に初回実行、その後毎日同じ時刻にenable_cpu_autoscalingを実行する設定をしています。

```sql:ジョブ ENABLE_CPU_AUTOSCALING_JOB
BEGIN
  DBMS_SCHEDULER.CREATE_JOB (
    job_name            => 'ENABLE_CPU_AUTOSCALING_JOB', -- ジョブの名前
    job_type            => 'STORED_PROCEDURE', -- ジョブのタイプ
    job_action          => 'ADMIN.ENABLE_CPU_AUTOSCALING', --実行するプロシージャ名
    start_date          => TO_TIMESTAMP_TZ('2023-03-08 08:00:00 +9:00','YYYY-MM-DD HH24:MI:SS TZH:TZM'),  --初回実行のタイムスタンプ
    repeat_interval     => 'FREQ=DAILY;INTERVAL=1', -- 実行頻度
    auto_drop           => FALSE); -- 自動削除するかどうか
END;
/
```
ジョブ「ENABLE_CPU_AUTOSCALING_JOB」を有効化します。
```sql
EXEC DBMS_SCHEDULER.ENABLE('ENABLE_CPU_AUTOSCALING_JOB');
```

# 4. CPUの自動スケーリングを無効化するPL/SQLプロシージャの自動実行の設定
同様に、DBMS_SCHEDULERを使用して、毎日決まった時間にCPUの自動スケーリングを無効化するPL/SQLプロシージャ「disable_cpu_autoscaling」を自動実行するジョブ「DISABLE_CPU_AUTOSCALING_JOB」を作成します。
この例では、日本時間2023/3/8 18時に初回実行、その後毎日同じ時刻にdisable_cpu_autoscalingを実行する設定をしています。


```sql:ジョブ DISABLE_CPU_AUTOSCALING_JOB
BEGIN
  DBMS_SCHEDULER.CREATE_JOB (
    job_name            => 'DISABLE_CPU_AUTOSCALING_JOB', -- ジョブの名前
    job_type            => 'STORED_PROCEDURE', -- ジョブのタイプ
    job_action          => 'ADMIN.DISABLE_CPU_AUTOSCALING', --実行するプロシージャ名
    start_date          => TO_TIMESTAMP_TZ('2023-03-08 18:00:00 +9:00','YYYY-MM-DD HH24:MI:SS TZH:TZM'),  --初回実行のタイムスタンプ
    repeat_interval     => 'FREQ=DAILY;INTERVAL=1', -- 実行頻度
    auto_drop           => FALSE); -- 自動削除するかどうか
END;
/
```
ジョブ「DISABLE_CPU_AUTOSCALING_JOB」を有効化します。
```sql
EXEC DBMS_SCHEDULER.ENABLE('DISABLE_CPU_AUTOSCALING_JOB');
```
# まとめ
以上で、毎日8時にCPUの自動スケーリングを有効にし、毎日18時にCPUの自動スケーリングを無効にする仕組みがAutonomous Database単体で実現できました。