在使用数据库时,我们经常会需要在上面跑一些定时作业,例如转历史库,批处理,定时维护数据等。Oracle可以通过其自带的job机制来进行,作为Oracle的替代方案之一的PostgreSQL没有自带job机制,但是可以通过pgAgent来补全功能。
在pgAdmin v1.9版本之前,pgAgent是其安装包的一部分,pgAdmin v1.9之后 pgAgent独立成一个单独的软件包。
1. 环境
操作系统 RHEL 6.3
数据库版本 PostgreSQL 10.3
2. 软件下载获取
在PG自己的yum源上可以下载到适配各个数据库版本的pgAgent及其依赖包。可以选择配置yum源安装或者在没有网络的内网环境下通过下载安装。如果下载安装则要补全依赖包。我这里是内网RHEL 6.3 软件工作站模式。需要下载:
wxBase-2.8.12-1.el6.x86_64.rpm pgagent_10-3.4.0-10.rhel6.x86_64.rpm
3. 部署pgAgent
# rpm -ivh wxBase-2.8.12-1.el6.x86_64.rpm warning: wxBase-2.8.12-1.el6.x86_64.rpm: Header V4 DSA/SHA1 Signature, key ID 442df0f8: NOKEY Preparing... ########################################### [100%] 1:wxBase ########################################### [100%] # rpm -ivh pgagent_10-3.4.0-10.rhel6.x86_64.rpm warning: pgagent_10-3.4.0-10.rhel6.x86_64.rpm: Header V4 DSA/SHA1 Signature, key ID 442df0f8: NOKEY Preparing... ########################################### [100%] 1:pgagent_10 ########################################### [100%]
默认pgAgent会被安装在/usr/share/pgagent_10 目录下,可执行文件位于/usr/bin/pgagent_10
软件包安装完成后在需要进行作业调度的数据库执行以下脚本完成作业调度相关数据库对象的创建工作(并非全局有效)
$ psql -U postgres -d postgres -f /usr/share/pgagent_10-3.4.0/pgagent.sql
脚本执行完后会在数据库内生成一个新的catalog,通过这个schema进行数据库作业的调度。
最后还需要启动pgAgent才算是全部完成。
$ pgagent_10 -s /PostgreSQL/10/data/pgagent.log hostaddr=127.0.0.1 port=5432 dbname=postgres user=postgres password=123456
4.作业部署
完成pgAgent的安装部署工作后,在pgAdmin上出现相应的菜单
通过pgAgent可以使用图形化页面维护作业,不知道填什么的时候注意看提示基本就知道了。
- 定义作业名称
- 定义作业步骤
在General页定义通用信息
在code页定义需要执行的代码
- 定义调度信息
在general页定义基本信息
在Repeat页定义周期,周期使用cron风格。
以上所有操作也可以通过SQL进行,上面所有操作对应的代码如下:
DO $$ DECLARE jid integer; scid integer; BEGIN -- Creating a new job INSERT INTO pgagent.pga_job( jobjclid, jobname, jobdesc, jobhostagent, jobenabled ) VALUES ( 1::integer, 'job_test2'::text, ''::text, ''::text, true ) RETURNING jobid INTO jid; -- Steps -- Inserting a step (jobid: NULL) INSERT INTO pgagent.pga_jobstep ( jstjobid, jstname, jstenabled, jstkind, jstconnstr, jstdbname, jstonerror, jstcode, jstdesc ) VALUES ( jid, 'step1'::text, true, 's'::character(1), ''::text, 'postgres'::name, 'f'::character(1), 'insert into t1 values (999);'::text, ''::text ) ; -- Schedules -- Inserting a schedule INSERT INTO pgagent.pga_schedule( jscjobid, jscname, jscdesc, jscenabled, jscstart, jscend, jscminutes, jschours, jscweekdays, jscmonthdays, jscmonths ) VALUES ( jid, 'job_sch_test2'::text, ''::text, true, '2018-05-24 15:12:33+08'::timestamp with time zone, '2018-05-25 15:12:39+08'::timestamp with time zone, -- Minutes ARRAY[false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, true, true, true]::boolean[], -- Hours ARRAY[false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, false, false, false, false, false, false, false, false]::boolean[], -- Week days ARRAY[false, false, false, false, false, false, false]::boolean[], -- Month days ARRAY[false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false]::boolean[], -- Months ARRAY[false, false, false, false, false, false, false, false, false, false, false, false]::boolean[] ) RETURNING jscid INTO scid; END $$;
再回到图形界面,除了预先定义好的作业外,通过作业上的run now选项可以立刻执行一次。
上面的设置里我选择在每天的15点56-59分,一共执行4次作业,每次向t1表写入一条数据。完成后
5. pgAgent的数据字典表
pgAgent的相关表都位于Catalogs/pgAgent下。
pga_exception : 记录作业执行异常信息
pga_job: 作业定义的基本信息,作业起止时间,最后运行时间等
pga_jobagent:pgAgent的配置信息,服务器上pgAgent的地址和启动时间
pga_jobclass: pgAgent的配置信息,定义作业类型
pga_joblog:每个作业的运行日志,包含启动时间、执行时长。
pga_jobstep:每个job步骤的定义在这个表里。
pga_jobsteplog:每个job步骤的执行日志,包含步骤的开始时间,执行时长。
pga_schedule:job调度的定义在这个表里。