本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
使用 PostgreSQL pg_cron 擴充功能排程維護
您可以使用 PostgreSQL pg_cron
擴充功能,來排程 PostgreSQL 資料庫內的維護命令。如需擴充功能的詳細資訊,請參閱 pg_cron 文件中的什麼是 pg_cron?
Aurora PostgreSQL 引擎 12.6 版以及更新版本支援 pg_cron
擴充功能。
若要深入了解如何使用 pg_cron
,請參閱在 RDS for PostgreSQL 或 Aurora PostgreSQL 相容版本資料庫上使用 pg_cron 排程任務
設定 pg_cron 擴充功能
設定 pg_cron
擴充功能,如下所示:
-
修改與 PostgreSQL 資料庫執行個體關聯的自訂參數群組,並將
pg_cron
新增至shared_preload_libraries
參數值。重新啟動 PostgreSQL 資料庫執行個體,使參數群組的變更生效。若要深入了解如何使用參數群組,請參閱 Amazon Aurora PostgreSQL 參數。
-
重新啟動 PostgreSQL 資料庫執行個體之後,請使用具有
rds_superuser
許可的帳戶執行下列命令。例如,如果您在為 Aurora PostgreSQL 資料庫叢集 建立 RDS 時使用了預設設定,請以使用者postgres
身分連接並建立擴充功能。CREATE EXTENSION pg_cron;
pg_cron
排程器設定於名為postgres
的預設 PostgreSQL 資料庫內。pg_cron
物件會在此postgres
資料庫中建立,而且所有排程動作都會在此資料庫中執行。 -
您可以使用預設設定,或將任務排程在 PostgreSQL 資料庫執行個體的其他資料庫中執行。若要將任務排程至 PostgreSQL 資料庫執行個體中的其他資料庫,請參閱 為預設資料庫以外的資料庫排程 cron 任務 中的範例。
授與資料車使用者使用 pg_cron 的許可
安裝 pg_cron
擴充功能需要 rds_superuser
權限。然而,使用 pg_cron
的許可能夠授予 (由 rds_superuser
群組/角色的成員) 其他資料庫使用者,讓他們可以安排自己的任務。建議您只有在能改善生產環境中的作業時,才視需要授予對 cron
結構描述的許可。
若要授予資料庫使用者對 cron
結構描述的許可,請執行以下命令:
postgres=>
GRANT USAGE ON SCHEMA cron TOdb-user
;
這樣會給予 db-user
存取 cron
結構描述的許可,以針對它們有權存取的物件排程 cron 作業。如果資料庫使用者沒有許可,則作業會在將錯誤訊息發佈至 postgresql.log
檔案後失敗,如下所示:
2020-12-08 16:41:00 UTC::@:[30647]:ERROR: permission denied for table table-name
2020-12-08 16:41:00 UTC::@:[27071]:LOG: background worker "pg_cron" (PID 30647) exited with exit code 1
換句話說,請確定被授與cron
結構描述權限的資料庫使用者也擁有他們計劃排程之物件 (表格、結構描述等) 的權限。
Cron 工作的詳細資訊及其成功或失敗也會擷取在資料cron.job_run_details
表中。如需詳細資訊,請參閱 用於排程工作和擷取狀態的資料表 。
排定 pg_cron 任務
以下各節示範如何使用 pg_cron
任務排程各種管理任務。
注意
建立 pg_cron
工作時,請檢查 max_worker_processes
設定大於數目 cron.max_running_jobs
。如果 pg_cron
任務耗盡背景工作者程序,則會失敗。pg_cron
任務的預設數字為 5
。如需詳細資訊,請參閱 用於管理 pg_cron 擴充功能的參數。
正在清理資料表
自動資料清理功能可處理大多數情況下的清理維護。但是,您可能想要在您選定的時間來排定清理特定的資料表。
以下為使用 cron.schedule
函數來設定一個任務,以在每天 22:00 (GMT) 於特定資料表上使用 VACUUM FREEZE
的範例。
SELECT cron.schedule('manual vacuum', '0 22 * * *', 'VACUUM FREEZE pgbench_accounts');
schedule ---------- 1 (1 row)
執行上述範例之後,您可以如下所示檢查 cron.job_run_details
資料表中的歷史記錄。
postgres=>
SELECT * FROM cron.job_run_details;
jobid | runid | job_pid | database | username | command | status | return_message | start_time | end_time -------+-------+---------+----------+----------+--------------------------------+-----------+----------------+-------------------------------+------------------------------- 1 | 1 | 3395 | postgres | adminuser| vacuum freeze pgbench_accounts | succeeded | VACUUM | 2020-12-04 21:10:00.050386+00 | 2020-12-04 21:10:00.072028+00 (1 row)
以下是cron.job_run_details
表的查詢,看到失敗的作業。
postgres=>
SELECT * FROM cron.job_run_details WHERE status = 'failed';
jobid | runid | job_pid | database | username | command | status | return_message | start_time | end_time ------+-------+---------+----------+----------+-------------------------------+--------+--------------------------------------------------+-------------------------------+------------------------------ 5 | 4 | 30339 | postgres | adminuser| vacuum freeze pgbench_account | failed | ERROR: relation "pgbench_account" does not exist | 2020-12-04 21:48:00.015145+00 | 2020-12-04 21:48:00.029567+00 (1 row)
如需詳細資訊,請參閱 用於排程工作和擷取狀態的資料表 。
正在清除 pg_cron 歷史記錄資料表
cron.job_run_details
資料表包含 cron 任務的歷史記錄,它可能會隨著時間的推移而變得非常大。建議您排程清除此資料表的任務。例如,保留一週的項目可能足以進行疑難排解。
下列範例會使用 cron.schedule 函數來排程每天在午夜執行的任務,以清除 cron.job_run_details
資料表。這項任務只保留過去七天。如下所示使用您的 rds_superuser
帳戶來排程任務。
SELECT cron.schedule('0 0 * * *', $$DELETE FROM cron.job_run_details WHERE end_time < now() - interval '7 days'$$);
如需詳細資訊,請參閱 用於排程工作和擷取狀態的資料表 。
僅將錯誤記錄到 postgresql.log 檔案
若要防止寫入至 cron.job_run_details
資料表,請修改與 PostgreSQL 資料庫執行個體關聯的參數群組,並將 cron.log_run
參數設定為關閉。pg_cron
延伸模組不再寫入至資料表,而且只會將錯誤擷取至 postgresql.log
檔案。如需詳細資訊,請參閱 修改 Aurora 數據庫參數組中的參數。
使用下列命令來檢查 cron.log_run
參數的值。
postgres=>
SHOW cron.log_run;
如需詳細資訊,請參閱 用於管理 pg_cron 擴充功能的參數。
為預設資料庫以外的資料庫排程 cron 任務
pg_cron
的中繼資料都保留在名為 postgres
的 PostgreSQL 預設資料庫中。由於使用背景工作者來執行維護 cron 任務,因此您可以在 PostgreSQL 資料庫執行個體內的任何資料庫中排程任務︰
-
在 cron 資料庫中,使用 cron.schedule 如常排程任務。
postgres=>
SELECT cron.schedule('database1 manual vacuum', '29 03 * * *', 'vacuum freeze test_table');
-
作為使用
rds_superuser
角色的使用者,請為您剛建立的任務更新資料庫欄,以便在 PostgreSQL 資料庫執行個體內的另一個資料庫中執行。postgres=>
UPDATE cron.job SET database = 'database1' WHERE jobid = 106;
-
透過查詢
cron.job
資料表進行驗證。postgres=>
SELECT * FROM cron.job;
jobid | schedule | command | nodename | nodeport | database | username | active | jobname ------+-------------+--------------------------------+-----------+----------+----------+-----------+--------+------------------------- 106 | 29 03 * * * | vacuum freeze test_table | localhost | 8192 | database1| adminuser | t | database1 manual vacuum 1 | 59 23 * * * | vacuum freeze pgbench_accounts | localhost | 8192 | postgres | adminuser | t | manual vacuum (2 rows)
注意
在某些情況下,您可能會新增一個打算在其他資料庫上執行的 cron 任務。在此情況下,任務可能會嘗試在預設資料庫 (postgres
) 中執行,然後再更新正確的資料庫資料欄。如果使用者名稱具有許可,則任務會在預設資料庫中成功執行。
pg_cron 擴充功能的參考
您可以使用下列參數、函數和資料表搭配 pg_cron
擴充功能。如需詳細資訊,請參閱 pg_cron 文件中的什麼是 pg_cron?
用於管理 pg_cron 擴充功能的參數
以下是用來控制 pg_cron
擴充功能行為的參數清單。
參數 | 描述 |
---|---|
cron.database_name |
在其中保留 |
cron.host |
要連線至 PostgreSQL 的主機名稱。您無法修改此值。 |
cron.log_run |
記錄 |
cron.log_statement |
在執行之前記錄所有 cron 陳述式。值為 |
cron.max_running_jobs |
可同時執行的任務數量上限。 |
cron.use_background_workers |
使用背景工作者而不是用戶端工作階段。您無法修改此值。 |
使用下列 SQL 命令來顯示這些參數及其值。
postgres=>
SELECT name, setting, short_desc FROM pg_settings WHERE name LIKE 'cron.%' ORDER BY name;
函數參考:cron.schedule
這個函數會排程一個 cron 任務。任務最初是在預設 postgres
資料庫中進行排程。該函數會返回表示任務識別符的 bigint
值。若要將任務排程在 PostgreSQL 資料庫執行個體中的其他資料庫中執行,請參閱 為預設資料庫以外的資料庫排程 cron 任務 中的範例。
該函數有兩種語法格式。
- 語法
-
cron.schedule (job_name, schedule, command ); cron.schedule (schedule, command );
- 參數
-
參數 描述 job_name
cron 任務的名稱。
schedule
指出 cron 任務排程的文字。格式為標準 cron 格式。
command
要執行的命令文字。 - 範例
-
postgres=>
SELECT cron.schedule ('test','0 10 * * *', 'VACUUM pgbench_history');
schedule ---------- 145 (1 row)
postgres=>
SELECT cron.schedule ('0 15 * * *', 'VACUUM pgbench_accounts');schedule ---------- 146 (1 row)
函數參考:cron.unschedule
這個函數會刪除 cron 任務。您可以指定 job_name
或 job_id
,兩者之一。政策可確保您是移除任務排程的擁有者。該函數會返回一個表示成功或失敗的布林值。
此函數的語法格示如下。
- 語法
-
cron.unschedule (job_id); cron.unschedule (job_name);
- 參數
-
參數 描述 job_id
排程 cron 任務時,從
cron.schedule
函數傳回的任務識別符。job_name
使用
cron.schedule
函數排程的 cron 任務的名稱。 - 範例
-
postgres=>
SELECT cron.unschedule(108);unschedule ------------ t (1 row)
postgres=>
SELECT cron.unschedule('test');
unschedule ------------ t (1 row)
用於排程工作和擷取狀態的資料表
下表用於排程 cron 任務以及記錄任務完成的方式。
表格 | 描述 |
---|---|
cron.job |
包含每個排程任務的中繼資料。大部分與此資料表的互動應透過使用 重要我們建議您不要將更新或插入權限直接提供給此資料表。這樣做將允許使用者更新 |
cron.job_run_details |
包含過去排程任務執行的歷史記錄資訊。這對於調查任務執行的狀態、傳回訊息以及開始和結束時間非常有用。 注意若要防止此資料表無限期增長,請定期清除。如需範例,請參閱 正在清除 pg_cron 歷史記錄資料表。 |