はじめに
PL/SQL SDKとDBMS_SCHEDULERによるジョブの自動実行を組み合わせて、Always FreeのAutonomous Databaseのみを使用してComputeインスタンスの自動起動/停止をスケジューリングしてみました。
こちらの手順では、リソース・プリンシパルを使用していますので、こちらのドキュメントを参考にして、あらかじめadminユーザーに対して、Autonomous Databaseインスタンスのリソース・プリンシパルを有効にしておく必要があります。
また、こちらの内容はあくまで検証のため、エラーハンドリング等は行っておりません。
本番環境で行う際はきちんとエラーハンドリング、リトライ処理を実装されることをお勧めします。
1.自動起動/停止の対象となるインスタンスの情報を格納するテーブルの作成
データベース・アクションまたはSQL*Plusから、adminユーザとしてAutonomous Databaseにアクセスします。
自動起動/停止の対象となるComputeインスタンスの情報を格納するテーブル"instance_list"を作成します。
SQL> CREATE TABLE instance_list
2 (
3 instance_ocid VARCHAR2(128),
4 enable_flg NUMBER NOT NULL,
5 PRIMARY KEY (instance_ocid)
6 );
表が作成されました。
2.自動起動/停止の対象となるインスタンスの情報をテーブルに追加
対象となるComputeインスタンスのOCIDをinstance_listテーブルに追加します。
instance_ocid列に自動起動/停止の対象となるComputeインスタンスのOCIDを、enable_flgに1をセットします。
※enable_flgに0を入れると、レコードを削除せずに自動起動/停止の対象から外せるようにしています。
SQL> INSERT INTO instance_list VALUES ('ocid1.instance.oc1.ap-tokyo-1.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',1);
1行が作成されました。
SQL> INSERT INTO instance_list VALUES ('ocid1.instance.oc1.ap-tokyo-1.yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',1);
1行が作成されました。
SQL> INSERT INTO instance_list VALUES ('ocid1.instance.oc1.ap-tokyo-1.zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz',1);
1行が作成されました。
SQL> commit;
コミットが完了しました。
SQL>
以上で準備が整いました。
3.対象インスタンスを起動/停止するPL/SQLブロックの作成
instance_listテーブルから起動対象となるComputeインスタンスのOCIDのリストを取得し、行数分だけループしてComputeインスタンスを起動するPL/SQLブロックを作成しました。
DECLARE
response_body dbms_cloud_oci_core_instance_t;
response dbms_cloud_oci_cr_compute_instance_action_response_t;
-- instance_listテーブルからenable_flgが1になっているレコードセットを取得するカーソル
CURSOR target_ocid_cur IS SELECT * FROM instance_list WHERE enable_flg = 1;
-- 処理対象のレコードを保持する変数
target_ocid target_ocid_cur%ROWTYPE;
BEGIN
-- カーソルのオープン
OPEN target_ocid_cur;
--ループ処理開始
LOOP
-- 1行フェッチ
FETCH target_ocid_cur into target_ocid;
EXIT WHEN target_ocid_cur%NOTFOUND;
-- 確認のためにテーブルから取得したOCIDを表示
DBMS_OUTPUT.PUT_LINE('OCID:'||target_ocid.instance_ocid);
-- 取得したOCIDのインスタンスを起動
response := DBMS_CLOUD_OCI_CR_COMPUTE.instance_action (
instance_id => target_ocid.instance_ocid,
action => 'START',
region => 'ap-tokyo-1',
credential_name => 'OCI$RESOURCE_PRINCIPAL'
);
-- ループ処理終了
END LOOP;
-- カーソルのクローズ
CLOSE target_ocid_cur;
END;
/
コンソールで対象のComputeインスタンスの状態を確認します。

対象のComputeインスタンスは停止済の状態です。
Computeインスタンスを起動するPL/SQLブロックを実行してみます。
SQL> set serveroutput on
SQL> DECLARE
2 response_body dbms_cloud_oci_core_instance_t;
3 response dbms_cloud_oci_cr_compute_instance_action_response_t;
4 -- instance_listテーブルからenable_flgが1になっているレコードを取得するカーソル
5 CURSOR target_ocid_cur IS SELECT * FROM instance_list WHERE enable_flg = 1;
6 -- 処理対象のレコードを保持する変数
7 target_ocid target_ocid_cur%ROWTYPE;
8
9 BEGIN
10 -- カーソルのオープン
11 OPEN target_ocid_cur;
12 --ループ処理開始
13 LOOP
14 -- 1行フェッチ
15 FETCH target_ocid_cur into target_ocid;
16 EXIT WHEN target_ocid_cur%NOTFOUND;
17 -- 確認のためにテーブルから取得したOCIDを表示
18 DBMS_OUTPUT.PUT_LINE('OCID:'||target_ocid.instance_ocid);
19 -- 取得したOCIDのインスタンスを起動
20 response := DBMS_CLOUD_OCI_CR_COMPUTE.instance_action (
21 instance_id => target_ocid.instance_ocid,
22 action => 'START',
23 region => 'ap-tokyo-1',
24 credential_name => 'OCI$RESOURCE_PRINCIPAL'
25 );
26 -- ループ処理終了
27 END LOOP;
28 -- カーソルのクローズ
29 CLOSE target_ocid_cur;
30 END;
31 /
OCID:ocid1.instance.oc1.ap-tokyo-1.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
OCID:ocid1.instance.oc1.ap-tokyo-1.yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
OCID:ocid1.instance.oc1.ap-tokyo-1.zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
PL/SQLプロシージャが正常に完了しました。
SQL>
問題なく実行されました。
コンソールでComputeインスタンスが起動されたかを確認してみます。

対象のインスタンスの状態が実行中となっており、インスタンスが起動されたことが確認できました。
同様に、instance_listテーブルから停止対象となるComputeインスタンスのOCIDのリストを取得し、行数分だけループしてComputeインスタンスを停止するPL/SQLブロックを作成しました。
DECLARE
response_body dbms_cloud_oci_core_instance_t;
response dbms_cloud_oci_cr_compute_instance_action_response_t;
-- instance_listテーブルからenable_flgが1になっているレコードセットを取得するカーソル
CURSOR target_ocid_cur IS SELECT * FROM instance_list WHERE enable_flg = 1;
-- 処理対象のレコードを保持する変数
target_ocid target_ocid_cur%ROWTYPE;
BEGIN
-- カーソルのオープン
OPEN target_ocid_cur;
--ループ処理開始
LOOP
-- 1行フェッチ
FETCH target_ocid_cur into target_ocid;
EXIT WHEN target_ocid_cur%NOTFOUND;
-- 確認のためにテーブルから取得したOCIDを表示
DBMS_OUTPUT.PUT_LINE('OCID:'||target_ocid.instance_ocid);
-- 取得したOCIDのインスタンスを停止
response := DBMS_CLOUD_OCI_CR_COMPUTE.instance_action (
instance_id => target_ocid.instance_ocid,
action => 'SOFTSTOP',
region => 'ap-tokyo-1',
credential_name => 'OCI$RESOURCE_PRINCIPAL'
);
-- ループ処理終了
END LOOP;
-- カーソルのクローズ
CLOSE target_ocid_cur;
END;
/
Computeインスタンスを停止するPL/SQLブロックを実行してみます。
SQL> DECLARE
2 response_body dbms_cloud_oci_core_instance_t;
3 response dbms_cloud_oci_cr_compute_instance_action_response_t;
4
5 -- instance_listテーブルからenable_flgが1になっているレコードセットを取得するカーソル
6 CURSOR target_ocid_cur IS SELECT * FROM instance_list WHERE enable_flg = 1;
7 -- 処理対象のレコードを保持する変数
8 target_ocid target_ocid_cur%ROWTYPE;
9
10 BEGIN
11 -- カーソルのオープン
12 OPEN target_ocid_cur;
13 --ループ処理開始
14 LOOP
15 -- 1行フェッチ
16 FETCH target_ocid_cur into target_ocid;
17 EXIT WHEN target_ocid_cur%NOTFOUND;
18 -- 確認のためにテーブルから取得したOCIDを表示
19 DBMS_OUTPUT.PUT_LINE('OCID:'||target_ocid.instance_ocid);
20 -- 取得したOCIDのインスタンスを停止
21 response := DBMS_CLOUD_OCI_CR_COMPUTE.instance_action (
22 instance_id => target_ocid.instance_ocid,
23 action => 'SOFTSTOP',
24 region => 'ap-tokyo-1',
25 credential_name => 'OCI$RESOURCE_PRINCIPAL'
26 );
27 -- ループ処理終了
28 END LOOP;
29 -- カーソルのクローズ
30 CLOSE target_ocid_cur;
31 END;
32 /
OCID:ocid1.instance.oc1.ap-tokyo-1.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
OCID:ocid1.instance.oc1.ap-tokyo-1.yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
OCID:ocid1.instance.oc1.ap-tokyo-1.zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
PL/SQLプロシージャが正常に完了しました。
SQL>
問題なく実行されました。
コンソールでComputeインスタンスが停止されたかを確認してみます。

対象のインスタンスが停止されていることが確認できました。
4.対象インスタンスを起動/停止するストアド・プロシージャの作成
対象のComputeインスタンスを起動するストアド・プロシージャ "start_compute_instance" を作成します。
SQL> CREATE OR REPLACE PROCEDURE start_compute_instance
2 IS
3 response_body dbms_cloud_oci_core_instance_t;
4 response dbms_cloud_oci_cr_compute_instance_action_response_t;
5
6 CURSOR target_ocid_cur IS SELECT * FROM instance_list WHERE enable_flg = 1;
7 target_ocid target_ocid_cur%ROWTYPE;
8
9 BEGIN
10 OPEN target_ocid_cur;
11 LOOP
12 FETCH target_ocid_cur into target_ocid;
13 EXIT WHEN target_ocid_cur%NOTFOUND;
14
15 response := DBMS_CLOUD_OCI_CR_COMPUTE.instance_action (
16 instance_id => target_ocid.instance_ocid,
17 action => 'START',
18 region => 'ap-tokyo-1',
19 credential_name => 'OCI$RESOURCE_PRINCIPAL'
20 );
21 END LOOP;
22 CLOSE target_ocid_cur;
23 END;
24 /
プロシージャが作成されました。
SQL>
ストアド・プロシージャstart_compute_instanceを実行してみます。
SQL> EXECUTE start_compute_instance;
PL/SQLプロシージャが正常に完了しました。
SQL>
問題なく実行されました。
コンソールでComputeインスタンスが起動されたかを確認してみます。

対象のインスタンスが起動されていることが確認できました。
同様に、対象のComputeインスタンスを停止するストアド・プロシージャ "stop_compute_instance" を作成します。
SQL> CREATE OR REPLACE PROCEDURE stop_compute_instance
2 IS
3 response_body dbms_cloud_oci_core_instance_t;
4 response dbms_cloud_oci_cr_compute_instance_action_response_t;
5
6 CURSOR target_ocid_cur IS SELECT * FROM instance_list WHERE enable_flg = 1;
7 target_ocid target_ocid_cur%ROWTYPE;
8
9 BEGIN
10 OPEN target_ocid_cur;
11 LOOP
12 FETCH target_ocid_cur into target_ocid;
13 EXIT WHEN target_ocid_cur%NOTFOUND;
14
15 response := DBMS_CLOUD_OCI_CR_COMPUTE.instance_action (
16 instance_id => target_ocid.instance_ocid,
17 action => 'SOFTSTOP',
18 region => 'ap-tokyo-1',
19 credential_name => 'OCI$RESOURCE_PRINCIPAL'
20 );
21 END LOOP;
22 CLOSE target_ocid_cur;
23 END;
24 /
プロシージャが作成されました。
SQL>
ストアド・プロシージャstop_compute_instanceを実行してみます。
SQL> EXECUTE stop_compute_instance;
PL/SQLプロシージャが正常に完了しました。
SQL>
問題なく実行されました。
コンソールでComputeインスタンスが停止されたかを確認してみます。

対象のインスタンスが停止されていることが確認できました。
5.DBMS_SCHEDULERジョブの作成
作成したストアド・プロシージャをDBMS_SCHEDULERのジョブとして登録します。
Computeインスタンスを起動するストアド・プロシージャstart_compute_instanceを毎日日本時間8:00に実行するジョブ"start_compute_instance_job"を作成します。
SQL> BEGIN
2 DBMS_SCHEDULER.CREATE_JOB (
3 job_name => 'START_COMPUTE_INSTANCE_JOB',
4 job_type => 'STORED_PROCEDURE',
5 job_action => 'ADMIN.START_COMPUTE_INSTANCE', -- ストアド・プロシージャ名
6 start_date => TO_TIMESTAMP_TZ('2022-02-13 08:00:00 +9:00','YYYY-MM-DD HH24:MI:SS TZH:TZM'), -- 初回実行日時(日本時間2022/2/13 8:00を指定)
7 repeat_interval => 'FREQ=DAILY;INTERVAL=1', -- 実行頻度(毎日実行)
8 auto_drop => FALSE,
9 enabled => TRUE
10 );
11 END;
12 /
PL/SQLプロシージャが正常に完了しました。
SQL>
同様に、Computeインスタンスを停止するストアド・プロシージャstop_compute_instanceを毎日日本時間18:00に実行するジョブ"stop_compute_instance_job"を作成します。
SQL> BEGIN
2 DBMS_SCHEDULER.CREATE_JOB (
3 job_name => 'STOP_COMPUTE_INSTANCE_JOB',
4 job_type => 'STORED_PROCEDURE',
5 job_action => 'ADMIN.STOP_COMPUTE_INSTANCE', -- ストアド・プロシージャ名
6 start_date => TO_TIMESTAMP_TZ('2022-02-13 18:00:00 +9:00','YYYY-MM-DD HH24:MI:SS TZH:TZM'), -- 初回実行日時(日本時間2022/2/13 18:00を指定)
7 repeat_interval => 'FREQ=DAILY;INTERVAL=1', -- 実行頻度(毎日実行)
8 auto_drop => FALSE,
9 enabled => TRUE
10 );
11 END;
12 /
PL/SQLプロシージャが正常に完了しました。
SQL>
以上で、Autonomous Databaseを使用してComputeインスタンスの自動起動/停止をスケジューリングすることができました。
参考情報
DBMS_CLOUDでのリソース・プリンシパルの使用
DBMS_CLOUD_OCI_CR_COMPUTE.INSTANCE_ACTIONファンクション
DBMS_SCHEDULER.CREATE_JOBプロシージャ