pg_cron 은 PostgreSQL v10 이상 데이터베이스 내부에서 Extension 으로 실행되는 간단한 cron 기반 작업 스케줄러 입니다.
일반 cron과 동일한 구문을 사용하지만 데이터베이스에서 직접 PostgreSQL 명령을 예약할 수 있습니다.
pg_cron은 여러 작업을 병렬로 실행할 수 있지만 한 번에 최대 하나의 작업 인스턴스를 실행합니다. 첫 번째 실행이 완료되기 전에 두 번째 실행이 시작되어야 하는 경우 두 번째 실행은 큐에 추가되어 첫 번째 실행이 완료되는 즉시 시작됩니다.
스케줄링은 표준 cron 구문을 사용합니다. * 는 “모든 기간마다 실행” 을 의미하고 특정 숫자는 “해당시간에만” 을 의미합니다.
┌───────────── min (0 – 59)
│ ┌────────────── hour (0 – 23)
│ │ ┌─────────────── day of month (1 – 31)
│ │ │ ┌──────────────── month (1 – 12)
│ │ │ │ ┌───────────────── day of week (0 – 6) (0 to 6 are Sunday to
│ │ │ │ │ Saturday, or use names; 7 is also Sunday)
│ │ │ │ │
│ │ │ │ │
Install
pg_cron 과 PostgreSQL version 이 동일한 것으로 설치할 것
Install on Red Hat, CentOS, Fedora, Amazon Linux using PGDG
#Install the pg_cron extension
sudo yum install -y pg_cron_14
Install on Debian, Ubuntu using apt.postgresql.org
#Install the pg_cron extension
sudo apt-get -y install postgresql-14-cron
Setting
pg_cron 백그라운드 워커를 시작하려면 PostgreSQL 이 시작될 때 shared_preload_libraries 파라미터에 pg_cron 을 추가해야 합니다.
pg_cron 은 서버가 Standby 모드인 경우 작업을 실행하지 않지만 서버가 Promote 된다면 자동으로 시작됩니다.
pg_cron 적용은 아래와 같습니다.
#add to postgresql.conf
shared_preload_libraries = ‘pg_cron’
기본적으로 pg_cron 백그라운드 워커는 ‘postgres’ 데이터베이스에 메타데이터 테이블을 생성할 것으로 예상됩니다. 하지만, postgresql.conf 에서 cron.database_name 파라미터를 설정하여 구성할 수 도 있습니다.
#add to postgresql.conf
#pg_cron 백그라운드 워커를 실행시킬 데이터베이스를 지정할 수 있다.
cron.database_name = ‘postgres’
pg_cron 은 클러스터에서 하나의 데이터베이스에만 설치할 수 있습니다. 여러 데이터베이스에서 작업을 실행해야 하는 경우 cron.schedule_in_database() 를 사용합니다.
postgresql.conf 에서 cron.timezone 을 설정하여 시간을 조정할 수 있습니다.
#add to postgresql.conf
cron.timezone = ‘PRC’
PostgreSQL 을 재기동한 후, CREATE EXTENSION pg_cron 을 수행하고 pg_cron function 과 메타데이터 테이블 등을 생성할 수 있습니다.
— run as superuser
CREATE EXTENSION pg_cron;— USGAE 를 일반 유저에게 부여할 수도 있음
GRANT USAGE ON SCHEMA cron TO hans;
pg_cron 시작을 확인할 수 있는 방법
중요 : 기본적으로 pg_cron 은 libpq를 사용하여 pg_hba.conf 에서 허용해야 하는 로컬 데이터베이스에 대한 새 연결을 엽니다. cron 작업을 실행하는 사용자를 위해 localhost 에서 들어오는 연결에 대한 인증을 활성화해야 할 수도 있고, 연결을 열 때 libpq 가 사용할 .pgpass 파일에 암호를 추가할 수도 있습니다.
또한, 유닉스 도메인 소켓 디렉토리를 호스트 이름으로 사용하고 일반적으로 안전한 pg_hba.conf 에서 로컬 연결에 대한 신뢰 인증을 활성화할 수 있습니다.
#connect via a unix domain socket
cron.host = ‘/tmp’
또는 백그라운드 워커를 사용하도록 pg_cron 을 구성할 수 있습니다.
이 경우 동시 작업 수는 max_worker_processes 설정에 의해 제한되므로 해당 값을 높여야 할 수도 있습니다.
#Schedule jobs via background workers instead of localhost connections
cron.use_background_workers = on
#Increase the number of available background workers from the default of 8
max_worker_processes = 20
보안을 위해 현재 사용자와 동일한 권한으로 cron.schedule 함수가 호출된 데이터베이스에서 작업이 실행됩니다.
또한, 사용자는 cron.job 테이블에서 자신의 작업만 볼 수 있습니다.
Job 실행을 보는 방법
cron.job_run_details 에서 실행 중인 작업 및 최근에 완료된 작업 실행의 상태를 볼 수 있습니다.
select * from cron.job_run_details order by start_time desc limit 5;
┌───────┬───────┬─────────┬──────────┬──────────┬───────────────────┬───────────┬──────────────────┬───────────────────────────────┬───────────────────────────────┐
│ jobid │ runid │ job_pid │ database │ username │ command │ status │ return_message │ start_time │ end_time │
├───────┼───────┼─────────┼──────────┼──────────┼───────────────────┼───────────┼──────────────────┼───────────────────────────────┼───────────────────────────────┤
│ 10 │ 4328 │ 2610 │ postgres │ marco │ select process() │ succeeded │ SELECT 1 │ 2023-02-07 09:30:00.098164+01 │ 2023-02-07 09:30:00.130729+01 │
│ 10 │ 4327 │ 2609 │ postgres │ marco │ select process() │ succeeded │ SELECT 1 │ 2023-02-07 09:29:00.015168+01 │ 2023-02-07 09:29:00.832308+01 │
│ 10 │ 4321 │ 2603 │ postgres │ marco │ select process() │ succeeded │ SELECT 1 │ 2023-02-07 09:28:00.011965+01 │ 2023-02-07 09:28:01.420901+01 │
│ 10 │ 4320 │ 2602 │ postgres │ marco │ select process() │ failed │ server restarted │ 2023-02-07 09:27:00.011833+01 │ 2023-02-07 09:27:00.72121+01 │
│ 9 │ 4320 │ 2602 │ postgres │ marco │ select do_stuff() │ failed │ job canceled │ 2023-02-07 09:26:00.011833+01 │ 2023-02-07 09:26:00.22121+01 │
└───────┴───────┴─────────┴──────────┴──────────┴───────────────────┴───────────┴──────────────────┴───────────────────────────────┴───────────────────────────────┘
(10 rows)
cron.job_run_details 의 레코드는 자동으로 정리되지 않지만 크론 작업을 예약할 수 있는 모든 사용자는 자신의 cron.job_run_details 레코드를 삭제할 수 있는 권한도 있습니다.
pg_cron Parameters
다음은 pg_cron extention 동작을 제어하는 파라미터의 목록입니다.
Parameters | Description |
---|---|
cron.database_name | pg_cron 메타데이터가 보관되는 데이터베이스입니다. |
cron.host | PostgreSQL에 연결할 호스트 이름입니다. 이 값은 수정할 수 없습니다. |
cron.log_run | 실행 중인 모든 작업을 job_run_details 테이블에 기록합니다. 유효한 값은 on 또는 off입니다. |
cron.log_statement | 모든 cron 문을 실행하기 전에 기록합니다. 유효한 값은 on 또는 off입니다. |
cron.max_running_jobs | 동시에 실행할 수 있는 최대 작업 수입니다. |
cron.use_background_workers | 클라이언트 세션 대신 백그라운드 작업자를 사용합니다. 이 값은 수정할 수 없습니다. |
- pg_cron Parameter 조회 시
postgres=# SELECT name, setting, short_desc FROM pg_settings WHERE name LIKE ‘cron.%’ ORDER BY name;
name | setting | short_desc
—————————–+———–+—————————————————-
cron.database_name | postgres | Database in which pg_cron metadata is kept.
cron.enable_superuser_jobs | on | Allow jobs to be scheduled as superuser
cron.host | localhost | Hostname to connect to postgres.
cron.log_min_messages | warning | log_min_messages for the launcher bgworker.
cron.log_run | on | Log all jobs runs into the job_run_details table
cron.log_statement | on | Log all cron statements prior to execution.
cron.max_running_jobs | 32 | Maximum number of jobs that can run concurrently.
cron.use_background_workers | off | Use background workers instead of client sessions.
(8 rows)
pg_cron Functions
- cron.schedule()
- 해당 함수는 cron 작업을 예약합니다. 작업은 처음에 기본 postgres 데이터베이스에서 예약됩니다. 이 함수는 job id를 나타내는 bigint 값을 반환합니다.
cron.schedule (job_name,
schedule,
command
);cron.schedule (schedule,
command
);
Parameters | Description |
---|---|
job_name | cron 작업의 이름입니다. |
schedule | cron 작업의 일정을 나타내는 텍스트입니다. 형식은 표준 cron 형식입니다. |
command | 실행할 명령의 텍스트입니다. |
- cron.schedule_in_database()
- 해당 함수는 cron 작업을 데이터베이스 별로 예약합니다. 이 함수는 job id를 나타내는 bigint 값을 반환합니다.
cron.schedule_in_database (
job_name text,
schedule text,
command text,
database text,
username text DEFAULT NULL::text,
active boolean DEFAULT true
)
Parameters | Description |
---|---|
job_name | cron 작업의 이름입니다. |
schedule | cron 작업의 일정을 나타내는 텍스트입니다. 형식은 표준 cron 형식입니다. |
command | 실행할 명령의 텍스트입니다. |
database | 작업을 예약할 데이터베이스 이름입니다. |
username | 작업을 수행시킬 유저 이름입니다. |
active | 작업을 on / off 할 수 있는 값입니다. |
- cron.unschedule()
- 이 함수는 cron 작업을 삭제합니다. job_name 또는 job_id를 전달할 수 있습니다. 정책은 사용자가 작업 일정을 제거할 수 있는 소유자인지를 확인합니다. 이 함수는 성공 또는 실패를 나타내는 boolean 값을 반환합니다.
cron.unschedule (job_id);
cron.unschedule (job_name);
Parameters | Description |
---|---|
job_id | cron 작업이 예약된 경우 cron.schedule 함수에서 반환된 작업 식별자입니다. |
job_name | cron.schedule 함수로 예약된 cron 작업의 이름입니다. |
pg_cron TABLE
해당 테이블은 cron 작업을 예약하고 작업 완료 방법을 기록하는데 사용됩니다.
Parameters | Description |
---|---|
cron.job | 예약된 각 작업에 대한 메타데이터를 포함합니다. 이 테이블과의 대부분의 상호 작용은 cron.schedule 및 cron.unschedule 함수를 사용하여 수행해야 합니다. 이 테이블에 직접 업데이트 또는 삽입 권한을 부여하지 않는 것이 좋습니다. 이렇게 하면 사용자가 username(으)로 실행되도록 rds-superuser 열을 업데이트할 수 있습니다. |
cron.job_run_details | 이전에 예약된 작업 실행에 대한 기록 정보를 포함합니다. 이는 실행한 작업에서 상태, 반환 메시지, 시작 및 종료 시간을 조사하는 데 유용합니다. |
아래와 같이 테이블 조회가 가능합니다
|cron.job 테이블의 active 컬럼은 default 값이 t 로 되어 있으나 해당 값을 f 로 update 해주면 해당 작업은 수행되지 않음
postgres=# select * from cron.job;
jobid | schedule | command | nodename | nodeport | database | username | active | jobname
——-+———-+———+———-+———-+———-+———-+——–+———
(0 rows)postgres=# select * from cron.job_run_details;
jobid | runid | job_pid | database | username | command | status | return_message | start_time | end_time
——-+——-+———+———-+———-+———+——–+—————-+————+———-
(0 rows)
pg_cron Simple Test
- 임의 테이블 하나를 만들고 pg_cron 을 이용한 정기적인 Vacuum 작업을 수행합니다.
1.임의 테이블 생성
postgres=# create table test(n int);
CREATE TABLE
2.스케줄 생성
test vacuum 이름을 가지고 1분 마다 test 테이블을 vacuum 하는 스케줄 생성
postgres=# SELECT cron.schedule(‘test vacuum’, ‘* * * * *’, ‘vacuum analyze test;’);
schedule
5
(1 row)
3. 스케줄 조회
postgres=# select * from cron.job;
jobid | schedule | command | nodename | nodeport | database | username | active | jobname
——-+———–+———————-+———–+———-+———-+———-+——–+————-
5 | * * * * * | vacuum analyze test; | localhost | 5432 | postgres | postgres | t | test vacuum
(1 row)
4.스케줄 이력 조회
postgres=# select * from cron.job_run_details;
jobid | runid | job_pid | database | username | command | status | return_message | start_time | end_time——-+——-+———+———-+———-+——————————-+———–+—————-+——————————-+———————-
5 | 7 | 8445 | postgres | postgres | vacuum analyze test; | succeeded | VACUUM | 2022-05-12 14:34:00.009511+09 | 2022-05-12 14:34:00.0
21028+09
5 | 8 | 8525 | postgres | postgres | vacuum analyze test; | succeeded | VACUUM | 2022-05-12 14:35:00.00951+09 | 2022-05-12 14:35:00.0
20938+09
(2 rows)
지금까지 ‘PostgreSQL의 pg_cron’에 관해 알아보았습니다
‘PostgreSQL의 pg_Agent’를 바로 이어서 확인해보세요!