Innovating today, leading tomorrow

OpenSQL_Technical Guide
[OpenSQL] pg_cron

[OpenSQL] pg_cron

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 동작을 제어하는 파라미터의 목록입니다.

ParametersDescription
cron.database_namepg_cron 메타데이터가 보관되는 데이터베이스입니다.
cron.hostPostgreSQL에 연결할 호스트 이름입니다. 이 값은 수정할 수 없습니다.
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
);

ParametersDescription
job_namecron 작업의 이름입니다.
schedulecron 작업의 일정을 나타내는 텍스트입니다. 형식은 표준 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
)

ParametersDescription
job_namecron 작업의 이름입니다.
schedulecron 작업의 일정을 나타내는 텍스트입니다. 형식은 표준 cron 형식입니다.
command실행할 명령의 텍스트입니다.
database작업을 예약할 데이터베이스 이름입니다.
username작업을 수행시킬 유저 이름입니다.
active작업을 on / off 할 수 있는 값입니다.
  • cron.unschedule()
    • 이 함수는 cron 작업을 삭제합니다. job_name 또는 job_id를 전달할 수 있습니다. 정책은 사용자가 작업 일정을 제거할 수 있는 소유자인지를 확인합니다. 이 함수는 성공 또는 실패를 나타내는 boolean 값을 반환합니다.

cron.unschedule (job_id);

cron.unschedule (job_name);

ParametersDescription
job_idcron 작업이 예약된 경우 cron.schedule 함수에서 반환된 작업 식별자입니다.
job_namecron.schedule 함수로 예약된 cron 작업의 이름입니다.

pg_cron TABLE

해당 테이블은 cron 작업을 예약하고 작업 완료 방법을 기록하는데 사용됩니다.

ParametersDescription
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’를 바로 이어서 확인해보세요!

광고성 정보 수신

개인정보 수집, 활용 목적 및 기간

(주)티맥스티베로의 개인정보 수집 및 이용 목적은 다음과 같습니다.
내용을 자세히 읽어보신 후 동의 여부를 결정해 주시기 바랍니다.

  • 수집 목적: 티맥스티베로 뉴스레터 발송 및 고객 관리
  • 수집 항목: 성함, 회사명, 회사 이메일, 연락처, 부서명, 직급, 산업, 담당업무, 관계사 여부, 방문 경로
  • 보유 및 이용 기간: 동의 철회 시까지

※ 위 개인정보 수집 및 이용에 대한 동의를 거부할 권리가 있습니다.
※ 필수 수집 항목에 대한 동의를 거부하는 경우 뉴스레터 구독이 제한될 수 있습니다.

개인정보의 처리 위탁 정보
  • 업체명: 스티비 주식회사
  • 위탁 업무 목적 및 범위: 광고가 포함된 뉴스레터 발송 및 수신자 관리
 

개인정보 수집 및 이용

개인정보 수집, 활용 목적 및 기간

(주)티맥스티베로의 개인정보 수집 및 이용 목적은 다음과 같습니다. 내용을 자세히 읽어보신 후 동의 여부를 결정해 주시기 바랍니다.

  • 수집 목적: 티맥스티베로 뉴스레터 발송 및 고객 관리
  • 수집 항목: 성함, 회사명, 회사 이메일, 연락처, 부서명, 직급, 산업, 담당업무, 관계사 여부, 방문 경로
  • 보유 및 이용 기간: 동의 철회 시까지

※ 위 개인정보 수집 및 이용에 대한 동의를 거부할 권리가 있습니다.
※ 필수 수집 항목에 대한 동의를 거부하는 경우 뉴스레터 구독이 제한될 수 있습니다.

개인정보의 처리 위탁 정보

  • 업체명: 스티비 주식회사
  • 위탁 업무 목적 및 범위: 광고가 포함된 뉴스레터 발송 및 수신자 관리
  •