About
home
Tmax OpenSQL
home
💻

40. pg_cron

작성자
CJH
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) │ │ │ │ │ │ │ │ │ │ * * * * *
Shell
복사

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
Shell
복사
Install on Debian, Ubuntu using apt.postgresql.org
# Install the pg_cron extension sudo apt-get -y install postgresql-14-cron
Shell
복사

Setting

pg_cron 백그라운드 워커를 시작하려면 PostgreSQL 이 시작될 때 shared_preload_libraries 파라미터에 pg_cron 을 추가해야 합니다.
pg_cron 은 서버가 Standby 모드인 경우 작업을 실행하지 않지만 서버가 Promote 된다면 자동으로 시작됩니다.
pg_cron 적용은 아래와 같습니다.
# add to postgresql.conf shared_preload_libraries = 'pg_cron'
Shell
복사
기본적으로 pg_cron 백그라운드 워커는 ‘postgres’ 데이터베이스에 메타데이터 테이블을 생성할 것으로 예상됩니다. 하지만, postgresql.conf 에서 cron.database_name 파라미터를 설정하여 구성할 수 도 있습니다.
# add to postgresql.conf # pg_cron 백그라운드 워커를 실행시킬 데이터베이스를 지정할 수 있다. cron.database_name = 'postgres'
Shell
복사
pg_cron 은 클러스터에서 하나의 데이터베이스에만 설치할 수 있습니다. 여러 데이터베이스에서 작업을 실행해야 하는 경우 cron.schedule_in_database() 를 사용합니다.
postgresql.conf 에서 cron.timezone 을 설정하여 시간을 조정할 수 있습니다.
# add to postgresql.conf cron.timezone = 'PRC'
Shell
복사
PostgreSQL 을 재기동한 후, CREATE EXTENSION pg_cron 을 수행하고 pg_cron function 과 메타데이터 테이블 등을 생성할 수 있습니다.
-- run as superuser CREATE EXTENSION pg_cron; -- USGAE 를 일반 유저에게 부여할 수도 있음 GRANT USAGE ON SCHEMA cron TO hans;
Shell
복사

pg_cron 시작을 확인할 수 있는 방법

중요 : 기본적으로 pg_cron 은 libpq를 사용하여 pg_hba.conf 에서 허용해야 하는 로컬 데이터베이스에 대한 새 연결을 엽니다. cron 작업을 실행하는 사용자를 위해 localhost 에서 들어오는 연결에 대한 인증을 활성화해야 할 수도 있고, 연결을 열 때 libpq 가 사용할 .pgpass 파일에 암호를 추가할 수도 있습니다.
또한, 유닉스 도메인 소켓 디렉토리를 호스트 이름으로 사용하고 일반적으로 안전한 pg_hba.conf 에서 로컬 연결에 대한 신뢰 인증을 활성화할 수 있습니다.
# connect via a unix domain socket cron.host = '/tmp'
Shell
복사
또는 백그라운드 워커를 사용하도록 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
Shell
복사
보안을 위해 현재 사용자와 동일한 권한으로 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 │ ├───────┼───────┼─────────┼──────────┼──────────┼───────────────────┼───────────┼──────────────────┼───────────────────────────────┼───────────────────────────────┤ │ 1043282610 │ postgres │ marco │ select process() │ succeeded │ SELECT 12023-02-07 09:30:00.098164+01 │ 2023-02-07 09:30:00.130729+01 │ │ 1043272609 │ postgres │ marco │ select process() │ succeeded │ SELECT 12023-02-07 09:29:00.015168+01 │ 2023-02-07 09:29:00.832308+01 │ │ 1043212603 │ postgres │ marco │ select process() │ succeeded │ SELECT 12023-02-07 09:28:00.011965+01 │ 2023-02-07 09:28:01.420901+01 │ │ 1043202602 │ postgres │ marco │ select process() │ failed │ server restarted │ 2023-02-07 09:27:00.011833+01 │ 2023-02-07 09:27:00.72121+01 │ │ 943202602 │ 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)
Shell
복사
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)
SQL
복사

pg_cron Functions

cron.schedule()
해당 함수는 cron 작업을 예약합니다. 작업은 처음에 기본 postgres 데이터베이스에서 예약됩니다. 이 함수는 job id를 나타내는 bigint 값을 반환합니다.
cron.schedule (job_name, schedule, command ); cron.schedule (schedule, command );
SQL
복사
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 )
SQL
복사
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);
SQL
복사
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)
SQL
복사

pg_cron Simple Test

임의 테이블 하나를 만들고 pg_cron 을 이용한 정기적인 Vacuum 작업을 수행합니다.
1.
임의 테이블 생성
postgres=# create table test(n int); CREATE TABLE
SQL
복사
2.
스케줄 생성
# test vacuum 이름을 가지고 1분 마다 test 테이블을 vacuum 하는 스케줄 생성 postgres=# SELECT cron.schedule('test vacuum', '* * * * *', 'vacuum analyze test;'); schedule ---------- 5 (1 row)
SQL
복사
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)
SQL
복사
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)
SQL
복사
지금까지 ‘PostgreSQL의 pg_cron’에 관해 알아보았습니다
‘PostgreSQL의 pg_Agent’를 바로 이어서 확인해보세요!

자유롭게 댓글을 남겨주세요