pg_cron は、AnalyticDB for PostgreSQL に組み込まれた cron ベースのジョブスケジューラです。外部スケジューラを必要とせず、データベース内から直接スケジュールに基づいて PostgreSQL コマンドを実行します。
pg_cron を使用すると、定期的なデータベースタスクを自動化できます。
-
期限切れデータのスケジュールに基づく削除またはアーカイブ
-
オフピーク時の
VACUUMまたはVACUUM FULLの実行 -
定期的なストアドファンクションの呼び出し
-
メンテナンス SQL ステートメントの自動実行
使用上の注意
スケジュールされたすべてのジョブは、GMT (グリニッジ標準時、UTC と同等) で実行されます。スケジュールを設定する前に、現地時間を GMT に変換してください。
すべてのジョブは、対象のデータベースに関係なく、デフォルトの postgres データベースに保存され、クエリも同データベースから実行する必要があります。
このトピックで説明する一部の機能には、最小インスタンスバージョンが必要です。
-
AnalyticDB for PostgreSQL V6.0:v6.3.6.0 以降
-
AnalyticDB for PostgreSQL V7.0:v7.0.3.0 以降
-
AnalyticDB for PostgreSQL Serverless mode:v2.0.0.1 以降。すべての機能を使用するには、マイナーエンジンバージョンをアップグレードしてください。手順については、「マイナーエンジンバージョンのアップグレード」をご参照ください。
仕組み
スケジュールされたジョブは、次の 2 つの部分で構成されます。
-
コマンド:実行する SQL ステートメントまたはファンクション (
VACUUMなど) -
スケジュール:コマンドを実行するタイミング (標準の cron 構文で表現)
スケジュールは、スペースで区切られた 5 つのフィールドを使用します。
┌───────────── 分 (0 - 59)
│ ┌────────────── 時 (0 - 23)
│ │ ┌─────────────── 日 (1 - 31)
│ │ │ ┌──────────────── 月 (1 - 12)
│ │ │ │ ┌───────────────── 曜日 (0 - 6、0 は日曜日)
│ │ │ │ │
* * * * *
フィールド演算子:
| 演算子 | 意味 | 例 |
|---|---|---|
* |
任意の値 | * * * * * — 毎分 |
| 数値 | 完全一致 | 30 3 * * * — 毎日午前 3:30 |
, |
複数の値 | 1,15 * * * * — 1 分と 15 分 |
- |
範囲 | 1-5 — 月曜日から金曜日 |
/ |
ステップ値 | 0/2 — 0時から2時間ごと |
一般的なスケジュールの例:
| スケジュール | cron 式 |
|---|---|
| 毎週土曜日の午前 3:30 GMT | 30 3 * * 6 |
| 毎月 1 日と 30 日の午前 1:45 GMT | 45 1 1,30 * * |
| 毎週平日 (月曜日〜金曜日) の午前 3:00 GMT | 00 3 * * 1-5 |
| 午前 8:00 から午後 8:00 GMT まで 2 時間ごと | 0 8-20/2 * * * |
Crontab.guru を使用すると、cron 式をインタラクティブに作成およびプレビューできます。
拡張機能のインストールまたはアンインストール
pg_cron は、すべての AnalyticDB for PostgreSQL インスタンスにデフォルトでインストールされています。手動でインストールする必要はありません。
この拡張機能にはカーネル依存関係があるため、アンインストールできません。
ジョブのスケジュール
基本的なスケジュール
SELECT cron.schedule('<schedule>', '<command>');
| パラメータ | 必須 | 説明 |
|---|---|---|
<schedule> |
はい | ジョブを実行するタイミングを指定する cron 式 |
<command> |
はい | 実行する SQL ステートメントまたはファンクション呼び出し |
例:
-- 毎週土曜日の午前 3:30 GMT に 1 週間以上前のイベントを削除
SELECT cron.schedule('30 3 * * 6', $$DELETE FROM events WHERE event_time < now() - interval '1 week'$$);
-- 毎日午前 10:00 GMT に test() ファンクションを呼び出し
SELECT cron.schedule('0 10 * * *', 'select test()');
-- 毎分 SQL ステートメントを実行
SELECT cron.schedule('* * * * *', 'select 1');
-- 毎月 1 日と 30 日、および毎週土曜日と日曜日の午前 2:30 GMT に VACUUM FULL を実行
SELECT cron.schedule('30 2 1,30 * 6,0', 'VACUUM FULL');
名前付きジョブのスケジュール
名前を割り当てると、後でジョブを識別および管理しやすくなります。
SELECT cron.schedule('<job_name>', '<schedule>', '<command>');
| パラメータ | 必須 | 説明 |
|---|---|---|
<job_name> |
はい | ジョブのラベル |
<schedule> |
はい | cron 式 |
<command> |
はい | SQL ステートメントまたはファンクション呼び出し |
例:
SELECT cron.schedule('Delete Expired Data', '30 3 * * 6', $$DELETE FROM events WHERE event_time < now() - interval '1 week'$$);
SELECT cron.schedule('Select Per Minute', '* * * * *', 'select 1');
SELECT cron.schedule('Do Vacuum', '0 23 * * *', 'VACUUM FULL');
pg_cron では、重複するジョブ名が許可されます。cron.unschedule('<job_name>') を呼び出した際に、複数のジョブがその名前を共有している場合は、最小のジョブ ID を持つジョブのみが削除されます。曖昧さを避けるため、ジョブ ID を使用してください。
特定のデータベースでのジョブのスケジュール
1.4 より前の pg_cron バージョンでは、ジョブは拡張機能がインストールされているデータベースでのみ実行できました。他のデータベースでジョブを実行するには、cron.job テーブルを直接操作する必要があり、不便かつ安全ではありませんでした。pg_cron バージョン 1.4 以降では、cron.schedule() で対象データベースとアカウントを直接指定できます。
SELECT cron.schedule('<job_name>', '<schedule>', '<command>', '<database>', '<username>', '<active>');
| パラメータ | 必須 | デフォルト | 説明 |
|---|---|---|---|
<job_name> |
はい | — | ジョブのラベル |
<schedule> |
はい | — | cron 式 |
<command> |
はい | — | SQL ステートメントまたはファンクション呼び出し |
<database> |
いいえ | postgres |
ジョブを実行するデータベース |
<username> |
いいえ | 現在のアカウント | ジョブを実行するデータベースアカウント |
<active> |
いいえ | true |
ジョブを有効にするかどうか |
例:
-- dw データベースで毎日午後 11:00 GMT に VACUUM FULL を実行
SELECT cron.schedule('Do Vacuum', '0 23 * * *', 'VACUUM FULL', 'dw');
-- gp1234 として dw データベースで毎分 SQL ステートメントを実行
SELECT cron.schedule('Select Per Minute', '* * * * *', 'select 1', 'dw', 'gp1234');
-- user1 として dw データベースで毎日午前 10:00 GMT に test() を呼び出し
SELECT cron.schedule('DO Function', '0 10 * * *', 'select test()', 'dw', 'user1', true);
スケジュールされたジョブの更新
cron.alter_job を使用すると、既存のジョブを変更できます。
SELECT cron.alter_job(<job_id>, '<schedule>', '<command>', '<database>', '<username>', '<active>');
| パラメータ | 必須 | 説明 |
|---|---|---|
<job_id> |
はい | cron.job テーブルのジョブ ID |
<schedule> |
いいえ | 新しい cron 式。変更しない場合は null を渡します。 |
<command> |
いいえ | 新しい SQL ステートメント。変更しない場合は null を渡します。 |
<database> |
いいえ | 新しい対象データベース。変更しない場合は null を渡します。 |
<username> |
いいえ | 新しいデータベースアカウント。変更しない場合は null を渡します。 |
<active> |
いいえ | 有効にする場合は true、無効にする場合は false。変更しない場合は null を渡します。 |
例:
-- ジョブ 3 のスケジュールを毎日午前 11:00 GMT に変更
SELECT cron.alter_job(3, '0 11 * * *', null);
-- ジョブ 1 のコマンドを VACUUM に変更
SELECT cron.alter_job(1, null, 'VACUUM');
-- ジョブ 2 のデータベースアカウントを gp1234 に変更
SELECT cron.alter_job(2, null, null, null, 'gp1234');
スケジュールされたジョブの削除
ジョブ名による削除
SELECT cron.unschedule('<job_name>');
複数のジョブが同じ名前を共有している場合、最小のジョブ ID を持つジョブのみが削除されます。正確に指定するため、ジョブ ID を使用してください。
例:
SELECT cron.unschedule('Do Vacuum');
ジョブ ID による削除
SELECT cron.unschedule(<job_id>);
例:
SELECT cron.unschedule(21);
ジョブ ID は cron.job テーブルで確認できます。
スケジュールされたジョブの表示
スケジュールされたすべてのジョブの一覧表示
SELECT * FROM cron.job;
ジョブ実行履歴の表示
cron.job_run_details テーブルには、各ジョブ実行の詳細が記録されます。
-- 失敗したすべてのジョブを表示
SELECT * FROM cron.job_run_details WHERE status = 'failed';
-- ジョブ 1 の実行履歴を表示
SELECT * FROM cron.job_run_details WHERE jobid = '1';
スケジュールされたジョブが多数ある場合、cron.job_run_details は時間の経過とともに大きくなる可能性があります。定期的なクリーンアップジョブをスケジュールして、テーブルサイズを管理しやすい状態に保ってください。実行ログを完全に無効にするには、チケットを起票してテクニカルサポートに cron.log_run を false に設定するよう依頼してください。
次のステップ
-
GitHub の pg_cron リポジトリ — アップストリームのドキュメントとリリースノート
-
RDS for PostgreSQL のスケジュールされたジョブ (pg_cron) — お使いのインスタンスが RDS for PostgreSQL の場合