PG_CRON是PostgreSQL 9.5及以上版本中基于CRON的一個簡單的作業調度程序,它作為擴展程序在數據庫中運行。PG_CRON的使用方式與常規CRON保持相同的語法,但它允許直接從數據庫安排PostgreSQL命令。

注意事項

  • 舊版本PG_CRON插件可能存在內存泄露風險,因此在使用PG_CRON插件之前,請將內核小版本升級至V1.1.19及以上版本。如果不使用PG_CRON插件,則無該風險。
  • 出于安全性考慮,您只能夠通過系統函數來操作定時任務(系統提供了增加和刪除定時任務的功能),普通用戶對于cron.job(PG_CRON定時任務表)只有查看的權限。請您根據自己的需要選擇函數的使用方法。
  • 數據庫中的定時任務都儲存于默認postgres數據庫中,但是您可以在其它多個數據庫上執行定時任務查詢。
  • 定時任務執行的時間是GMT時間,請注意換算時間。
  • PG_CRON插件默認關閉,由于安全原因,暫時不支持用戶手動創建。如有需要,請前往配額中心,在配額名稱PolarDB PG pg_cron插件使用操作列,單擊申請,申請創建。

關閉插件

您可以在數據庫中執行以下腳本關閉PG_CRON。

-- 關閉 pg_cron
DROP EXTENSION pg_cron;

使用插件

每一個定時任務都分為定時計劃和定時任務兩個部分。定時計劃規定了使用插件的計劃,例如每隔一分鐘執行一次該任務;定時任務是具體的任務內容,例如select * from some_table。插件提供了一個可選參數database,未指定該參數則默認配置postgres數據庫。

以下函數是您可以執行的全部函數,其它操作視為非法操作。

-- 執行一個任務
SELECT cron.schedule('schedule', 'task')

-- 選定數據庫執行任務 
-- 第三個參數不指定即為配置文件中數據庫,默認postgres
SELECT cron.schedule('schedule', 'task', 'my_db')

-- 刪除一個任務
SELECT cron.unschedule(schedule_id)

-- 查看當前任務列表
SELECT * FROM cron.job;

示例

  • 增加任務項
    -- 周六3:30am (GMT) 刪除過期數據 
    SELECT cron.schedule('30 3 * * 6', $$DELETE FROM events WHERE event_time < now() - interval '1 week'$$);
     schedule
    ----------
           42
    
    -- 每天的 10:00am (GMT) 執行磁盤清理
    SELECT cron.schedule('0 10 * * *', 'VACUUM');
     schedule
    ----------
           43
     
    -- 每分鐘執行 指定腳本
    SELECT cron.schedule('* * * * *', 'select 1;');
     schedule
    ----------
           44
    
    -- 每個小時的 23分 執行 指定腳本
    SELECT cron.schedule('23 * * * *', 'select 1;');
     schedule
    ----------
           45
           
    -- 每個月的 4號 執行 指定腳本
    SELECT cron.schedule('* * 4 * *', 'select 1;');
     schedule
    ----------
           46

    其中,PG_CRON計劃使用標準的CRON語法,*表示每個該時間運行,指定數字則表示僅在這個時間運行,如下所示。

     ┌───────────── 分鐘 (0 - 59)
     │ ┌────────────── 小時 (0 - 23)
     │ │ ┌─────────────── 日期 (1 - 31)
     │ │ │ ┌──────────────── 月份 (1 - 12)
     │ │ │ │ ┌───────────────── 一周中的某一天 (0 - 6) (0 到 6 表示周末到下周六,
     │ │ │ │ │                   7 仍然是周末)
     * * * * *
  • 刪除任務項
    -- 停止、刪除一個任務
    SELECT cron.unschedule(42);
     unschedule
    ------------
              t
  • 查看當前任務
    SELECT * FROM cron.job;
    
     jobid | schedule   |  command  | nodename  | nodeport | database | username | active 
    -------+------------+-----------+-----------+----------+----------+----------+--------
        43 | 0 10 * * * |   VACUUM; | localhost |     5433 | postgres | test     | t