|
| 1 | +:sectnums: |
| 2 | +:sectnumlevels: 5 |
| 3 | +:imagesdir: ./_images |
| 4 | + |
| 5 | += pg_cron |
| 6 | + |
| 7 | +== Overview |
| 8 | +Running periodic tasks in PostgreSQL, such as executing VACUUM or deleting old data, is a common requirement. A simple way to achieve this is to configure cron or other external daemons to periodically connect to the database and run commands. However, as databases increasingly run as managed services or standalone containers, configuring and running a separate daemon often becomes impractical. Additionally, it's difficult to make your cron jobs aware of failover or schedule tasks across cluster nodes. |
| 9 | + |
| 10 | +pg_cron is an open-source scheduled task extension for PostgreSQL that allows setting up cron-style task scheduling directly within the database for automating data maintenance tasks (cleanup, aggregation), database health checks, executing stored procedures and custom functions, and other operations. It stores cron jobs in tables, and periodic tasks automatically fail over with the PostgreSQL server. For more details, see https://github.com/citusdata/pg_cron[pg_cron documentation]. |
| 11 | + |
| 12 | +== Installation and Configuration |
| 13 | + |
| 14 | +[TIP] |
| 15 | +IvorySQL 1.17 and above is already installed in the environment, with the installation path at /usr/local/ivorysql/ivorysql-1 |
| 16 | + |
| 17 | +=== Source Installation |
| 18 | + |
| 19 | +``` |
| 20 | +# Clone pg_cron source code |
| 21 | +git clone https://github.com/citusdata/pg_cron.git |
| 22 | +cd pg_cron |
| 23 | +# Set pg_config path to PATH environment variable, e.g.: |
| 24 | +export PATH=/usr/local/ivorysql/ivorysql-1/bin/:$PATH |
| 25 | +make |
| 26 | +make install |
| 27 | +``` |
| 28 | + |
| 29 | +=== Configuration File (ivorysql.conf) |
| 30 | + |
| 31 | +``` |
| 32 | +# Shared preload extensions |
| 33 | +shared_preload_libraries = 'pg_cron' |
| 34 | + |
| 35 | +# Specify task metadata storage database (default current database) |
| 36 | +cron.database_name = 'ivorysql' |
| 37 | + |
| 38 | +# Maximum number of concurrent tasks allowed |
| 39 | +cron.max_running_jobs = 5 |
| 40 | +``` |
| 41 | + |
| 42 | +=== Restart Service |
| 43 | + |
| 44 | +``` |
| 45 | +pg_ctl restart -D ./data -l logfile |
| 46 | +``` |
| 47 | + |
| 48 | +=== Create Extension and Confirm pg_cron Version |
| 49 | + |
| 50 | +Connect to the database with psql and execute the following commands: |
| 51 | +``` |
| 52 | +ivorysql=# CREATE extension pg_cron; |
| 53 | +CREATE EXTENSION |
| 54 | + |
| 55 | +ivorysql=# SELECT * FROM pg_available_extensions WHERE name = 'pg_cron'; |
| 56 | + name | default_version | installed_version | comment |
| 57 | +---------+-----------------+-------------------+--------------------------- |
| 58 | + pg_cron | 1.6 | |Job scheduler for PostgreSQL |
| 59 | +(1 row) |
| 60 | +``` |
| 61 | +
|
| 62 | +== Core Functionality Usage |
| 63 | +
|
| 64 | +=== Creating Scheduled Tasks |
| 65 | +
|
| 66 | +``` |
| 67 | +SELECT cron.schedule( |
| 68 | + 'nightly-data-cleanup', -- Task name (unique identifier) |
| 69 | + '0 3 * * *', -- Cron expression (daily at UTC 3:00) |
| 70 | + $$DELETE FROM logs |
| 71 | + WHERE created_at < now() - interval '30 days'$$ -- SQL to execute |
| 72 | +); |
| 73 | +``` |
| 74 | +
|
| 75 | +Cron expression quick reference: |
| 76 | +
|
| 77 | +|==== |
| 78 | +|Example|Meaning |
| 79 | +|'0 * * * *'|Execute every hour on the hour |
| 80 | +|'*/15 * * * *'|Execute every 15 minutes |
| 81 | +|'0 9 * * 1-5'|Execute at 9 AM on weekdays |
| 82 | +|'0 1 1 * *'|Execute at 1 AM on the 1st of every month |
| 83 | +|==== |
| 84 | +
|
| 85 | +pg_cron also allows using '$' to represent the last day of the month. |
| 86 | +
|
| 87 | +=== Task Management |
| 88 | +
|
| 89 | +``` |
| 90 | +# View all tasks |
| 91 | +SELECT * FROM cron.job; |
| 92 | +
|
| 93 | +image::p31.png[] |
| 94 | +
|
| 95 | +# View task execution history |
| 96 | +SELECT * FROM cron.job_run_details ORDER BY start_time DESC LIMIT 10; |
| 97 | +
|
| 98 | +image::p32.png[] |
| 99 | +
|
| 100 | +# Delete task |
| 101 | +SELECT cron.unschedule('nightly-data-cleanup'); |
| 102 | +
|
| 103 | +# Pause task (update status) |
| 104 | +UPDATE cron.job SET active = false WHERE jobname = 'delete-job-run-details'; |
| 105 | +``` |
0 commit comments