随着业务的增长,平安的数据库中的数据量不断增大,数据库对象间的关系日趋复杂,数据库中的JOB执行的时间也不断增长,规则也更加复杂。各系统中原有的随意设置JOB,对JOB异常不监控,处理不及时状况已经不能满足现有业务的要求。目前系统中JOB异常影响到生产系统可用性的问题日益严重,针对这些问题罗总提出希望做到JOB的运行监控可以由基础架构的TIER1人员来做,另外也希望开发、运营、DBA三方一起制定出JOB的开发规范、管理规范和监控规范,通过规范管理和加强监控减少JOB对生产的影响。
由于LBS的JOB数量最多,关系最复杂,所以选取LBS作为试点系统,目前LBS已经对JOB开发和监控建立了规范,并且已经在生产环境运行。
本文档的JOB规范是根据LBS试点形成的开发规范、监控规范和运营规范。规范中的开发过程管理操作细则由CMM参与设计制作,运营过程管理操作细则由SQA参与设计制作。
1、 确定JOB用户,将同一数据库中同一个系统的所有的JOB都放到同一用户下执行。
2、 对JOB运行时间进行估计,根据业务逻辑指定JOB先后顺序,分批串/并行。需要重新整理job,将有先后执行顺序、相互可能会有锁等影响的job合并成一个job;将没有关联关系、同时执行没有影响的job单独出来,可以和其他job并发执行。
3、 将最早开始运行时间,最晚开始运行时间,最大运行时间,运行频度(天、周、月)等写入配置表。
4、 JOB代码通过读取配置表判断是否可以运行JOB,凡是在配置表时间段之外启动的JOB都不能执行。如果特殊情况需要在配置表时间段之外执行JOB,采用手工执行方式。
5、 超时JOB将被KILL。运营开发需要根据DB的具体情况确认是否要在工作时间开始前对DB中还在运行的JOB进行Kill,对于需要Kill的DB,由DBA根据需求在后台增加Cron进行Kill。
6、 运营和开发需要对维护期间(冷备,主机数据库维护、版本下发期间DB受限等)停库影响JOB执行的情况进行评估,确定在这些时段受到影响的JOB的执行策略和后续处理措施,原则上配置表中JOB配置最好避开常规的冷备时间段内。
1、 JOB的所有异常都要有记录,要进行处理;
2、 必须在JOB执行日志表中记录下该JOB执行的开始时间,结束时间,成功标志,失败原因;
3、 必须对JOB执行超时情况(结束时间超过配置表的配置)的异常进行记录;
4、 JOB必须分过程记录异常,保证异常能跟踪到JOB调用的哪个过程(procedure)出错;
5、 DBA或运营人员手工KILL JOB也需要作为异常,记录在错误信息表中;
6、 JOB的异常要划分级别,目前警告级别定为warning/minor/major/critical.运营可以根据JOB的具体情况给每个JOB规定不同的级别。
7、 所有的异常都要抛出给OpenView,由Tier-1根据运营提供的处理手册来判断是否要上报到问题管理系统。
8、 JOB问题要通过指定问题管理通道上报,运营、开发要定期对JOB问题进行分析,并根据分析结果对JOB的运行时间等参数进行调整。
9、 异常的抛出流程为:JOB异常->DB TABLE LOG->OPENVIVW->OVSD->TIER1->问题管理系统->运营->开发。
1、 批处理是指批次对数据进行操作的过程。
2、 批处理可以手工调用,也可以通过JOB调用,一般情况下,批处理被设定为JOB,在特定的时间执行(例如:LBS的批处理大部分都在凌晨执行)。
3、 批处理开发规范应该明确规定:每个批处理过程执行结束后,在日志表中记录下该批处理执行的开始时间,结束时间,成功标志,失败原因,处理结果(如:记录数,金额等)
4、 JOB异常和批处理异常的关系
由于JOB是调用批处理过程进行业务处理,JOB本身并不处理任何业务。所以,JOB正常运行并不表示业务处理已经正确完成。故而,是否抛异常不仅要看JOB是否正常完成,还要看该JOB调用的批处理是否正确完成。
JOB是否正常完成、JOB中调用的批处理是否正确完成、是否要抛异常三者之间关系如下:
JOB本身是否正常完成 |
JOB调用的批处理过程是否正确完成 |
是否抛出异常 |
Y |
Y |
N |
Y |
N |
Y |
Y(但超时) |
Y/N |
Y |
N |
Y/N |
Y |
5、 JOB调用的批处理程序对于大批量的数据修改(执行时间超过1小时或操作数据数量超过2000条)操作,要实施分段提交和断点续做,以保证job的批处理占用较少的回滚段等资源,最终提高job执行成功的几率。
JOB的开发规范总体来讲有两个方面,一是用后台的配置表来控制JOB的执行,二是要将JOB运行的状况记录到表中,并将异常发送到OpenView,再由基础架构管理部Tier1组(基础架构管理部Tier1组是一个24小时值班的系统监控组)录入到问题管理系统中。然后由运营按照正常问题处理流程进行处理跟进。具体流程参看下页的流程图。
各系统要指定一个用户为系统的JOB专用用户(例如,LIFEJOB为LBS的JOB专用用户,LBS中所有业务相关JOB都放在这个用户下),JOB专用的表,JOB要调用的PACKAGE(JOB_PACKAGE)都放在这个用户下,如果其他的包或过程需要被JOB_PACKAGE调用,则需要授执行权给此用户。
JOB 用户的命名规则为 <系统名>+JOB, 对于一个库中有多个系统的情况,如果功能彼此独立,可以按照系统名+JOB的规则给每个系统建立一个JOB用户;如果是一个大系统下的多个子系统,请开发酌情申请建立一<大系统名>+JOB 的JOB用户。
1、 每新增一个JOB都必须插入记录到JOB执行配置表,凡没有在JOB配置表中登记的JOB,均视为无效JOB。
2、 对每个JOB过程必须加以注释说明(执行时间/执行频次/主要功能/创建人/创建时间/修改人/修改时间),此注释说明必须和数据库中的执行时间和执行频次一致,如有调整必须修改此注释,并重新提交下发!
3、 对每个JOB调用的批处理过程,必须说明其功能/维护模块
4、 对每个JOB,启动后如果确定要执行其中的批处理过程,必须往JOB_RUNNING_LOG插入记录,并且在批处理过程执行完成后更新JOB_RUNNING_LOG中的结束时间。
5、 对每个JOB必须加上错误控制,错误必须明确是JOB中的哪个过程引起的异常。
将所有发生的错误记录到JOB_ERROR_LOG表中.
6、 对于新增JOB过程或JOB过程调整,必须同现有的JOB负责人进行沟通协调,以防止冲突
7、 JOB要调用的package(JOB_PACKAGE)过程由专人负责编写,JOB下发说明由负责编写package的同事编写后放到CC上,由各个项目组打标签下发,JOB下发说明文件的命名格式为:JOB下发说明+需求名.TXT
8、 提供各个JOB批处理过程中所有用到的表,形成文档
系统下发的JOB中不能直接调用各个功能过程,必须是调用JOB专用PACKAGE中的过程,否则不得下发。
各开发部门设立一名JOB负责人(原则上由各开发部门核心组负责数据库设计的同事承担),统筹管理该部门各系统的JOB开发。
开发JOB负责人工作职责如下:
1、负责本部门JOB规范的推广实施,
2、负责和JOB管理相关的JOB Package和表结构的开发、维护、管理工作。
3、对本部门各开发组提交的JOB变更(新增、修改、删除、配置表数据调整等)和JOB程序进行审核,确保其符合JOB规范
4、根据JOB运行的历史数据和业务逻辑,业务需求,提供JOB配置表的数据,对JOB的运行时间、运行顺序统筹安排。确定超时JOB的处理方案(如是否需要在上班前杀掉仍在运行的JOB)。
5、配合运营定期分析JOB异常,并负责转报给开发的JOB问题的处理跟进。
6、负责推动JOB调用的相关程序(如批处理过程)的优化。
图2 JOB开发管理流程图
1、 系统分析人员分析需求后,如果确认需要新增JOB和调整JOB则填写“JOB变更申请表”,并按照正常开发过程对JOB调用的过程进行开发。
2、开发完之后将JOB调用的过程和功能过程的效率以及同现有的JOB过程的功能及数据之间的冲突关系评估结果提交开发JOB负责人和受影响关联项目组进行审核,复审时开发JOB负责人需提供修改后的JOB_PACKAGE。(如部门内系统过多,开发JOB负责人不能一一了解,可让各系统JOB开发人员进行修改,但开发JOB负责人要对JOB_PACKAGE的质量负责)
3、审核结果需记录到JOB复审记录中
4、审核通过后提交EOA流程确认,具体说明如下:
1) 编写JOB程序人员需在EOA中申请复审,同时在签报中须附上《JOB变更申请表》,《JOB复审记录》、代码、配置表和脚本
2) 部门JOB负责人在EOA中确认资料内容的完备性和正确性,确定JOB运行的时间,同时提供JOB_PACKAGE
3) 如部门系统过多,可增加系统JOB负责人审核环节。并由系统JOB负责人提供JOB_PACKAGE(可选)
4) 部门长/开发JOB负责人直属领导确认
5) 运营组长确认/运营分管领导确认
表1JOB复审流程(EOA)
处理环节序号 |
审批类型 |
审批角色 |
说明 |
附件 |
0 |
申请提交 |
编写JOB业务程序人员 |
填写签报正文,启动该流程
|
签报中须附上JOB变更申请表、JOB复审报告、代码、配置表和脚本 |
1 |
内部批示 |
开发JOB负责人 |
确认资料内容的完备性和正确性,确定JOB运行的时间,提供最终JOB_PACKAGE并更新到CC中 |
附上最终的JOB_PACKAGE |
2 |
内部批示 |
系统JOB负责人 |
本环节为可选环节,如开发部门内系统过多,开发JOB负责人不能一一了解,在处理环节一可转发给系统JOB负责人进行审核处理。由系统JOB负责人提供最终JOB_PACKAGE |
附上最终的JOB_PACKAGE |
3 |
内部批示 |
部门长/开发JOB负责人直属领导 |
审核申请的合理性 |
|
4 |
内部批示 |
运营负责人/运营分管领导 |
确认申请的合理性 |
|
说明: 审核流程详见EOA中“集团信息管理中心 – IT各部门工作流程”中各开发部门下面的“数据库JOB复审” |
5、EOA审批通过后,如EOA审批中有新的问题产生,需由流程申请人员把问题更新到《JOB复审报告》中,并提交给部门开发JOB负责人。
6、开发JOB负责人将确认的JOB_PACKAGE和JOB复审记录更新到Clearcase中,并通知项目组及关联组
1) 在CC中“公共服务\src”下建立存放JOB_PACKAGE的文件目录
2) 在JOB_PACKAGE存放的目录下建立“JOB审核及申请”目录,在该目录下按照JOB系统名建立子目录,在该目录下存放JOB审核和变更申请的文档,文件命名方式遵循开发中心规范“配置管理指南”要求
7、项目组对JOB_PACKAGE打标签并进行下发
各运营部门运营组设立一名JOB负责人(由运营应用服务组成员担任),运营JOB负责人工作职责如下:
- 在JOB新程序测试和上线期间向监控组提出监控申请
- 提供本组的TIer1 JOB异常处理操作手册,并定期维护手册,确保手册的及时更新,并对Tier1进行必要的培训,使其能满足运营JOB异常处理要求
- 设置MOSS的JOB异常邮件发送策略,确保JOB异常邮件能及时发送给正确的收件人
- 负责审批运营组内的JOB变更请求(新建、修改、删除、配置表数据调整等),对本运营组提交的JOB程序进行审核,确保其符合JOB规范
- 负责运营自己写的JOB相关的JOB Package和表结构的开发、维护、管理工作
- 定期主动分析JOB异常,并跟进JOB问题的处理进度(运营、开发)
- Job异常事件的处理遵循运营事件管理流程中的规定
- JOB异常事件上报通道统一规定为:在ItsmPortal系统中“IT系统监控-应用系统监控“下,服务目录的建立遵循”IT应用系统问题“下所有的服务目录设计
ü 通道命名规则为:
IT系统监控-----应用系统监控-------应用系统名称(即服务目录第一层)
- 各应用服务组应该在Tier1指引中明确上报通道和上报主题,在上报界面选择
a. 上报主题-------JOB运行异常
b.上报方式-------人工上报
c.上报来源-----Openview
-
- 运营事件响应人员处理TIRE1上报的job运行异常的事件,并遵循事件管理流程中的定义
ü 应用系统监控通道收到的事件,在处理界面选择事件类型为“JOB类监控”.
ü 判断是否可以解决该事件,可以则自己处理,不能解决则升级至PIR事件处理;同时确定该事件是否需要更改程序,如果需要则上报PIR需求
ü 解决时判断是否需要补执行,需要补执行的则由事件响应人员使用实名用户执行。补执行时,要预估补执行的过程运行的资源占用情况,对其他操作的影响,需要选择合适的运行时间,避免JOB过程补执行对生产系统的影响。
可以根据job重要性的不同,定义不同的告警级别,Tier1工作人员会根据不同的告警级别采用不同的处理方案,告警级别及Tier1处理方案如下:
- 低(warning) :不需要处理,直接终止;原则上此级别不使用
- 一般(minor) :上报问题管理系统;原则上所有JOB最低设置级别是minor
- 中(major):上报问题管理系统,8:00--23:00电话通知运营负责人员,若公司电话无人接听,拨打运营负责人员的手机
- 高(critical) :上报问题管理系统,立即电话通知运营负责人员,若公司电话无人接听,拨打运营负责人员的手机
告警级别原则上不能修改,如果特殊情况需要修改(如因为job相关的业务重要性发生变化时,可以根据业务的重要性升高或降低告警级别),需要走JOB下发流程(按照4.2中要求进行申请和审核),由开发提交版本给运营进行修改。
程序测试与版本发布由运营测试组和运营应用部署组负责,流程与工作要求与其他程序的测试和版本发布相同。
新版本流程上线之前,JOB规范的执行由各开发部门核心组JOB负责人和运营JOB负责人一起把关,在EOA审批流中运营JOB负责人参与复审。
新增JOB需提交统一申请表(参看job变更申请表.doc),待审批后进行开发
1业务类监控JOB的新建/修改/删除,运营提出需求,由对应开发部门开发新建。
2 数据库性能监控类JOB的新建/修改/删除,由运营提出需求并开发,通过DBA审核后发布到生产环境。
建议邮件与DBA组组长沟通确认可行后,运营开发人员遵照JOB开发规范进行开发,完成后了附上相应文档与脚本,进行如下EOA签报。
详细申请操作请参见4.2.2要点说明
1. 编写JOB程序人员需在EOA中申请复审,同时在签报中须附上《JOB变更申请表》,《JOB复审记录》、代码、配置表和脚本
2. 各组JOB负责人在EOA中确认资料内容的完备性和正确性,确定JOB运行的时间,同时提供JOB_PACKAGE
3. 部门长/编写JOB人员的直属领导确认
4. DBA组组长确认
5. DBA组组长转DBA各负责人确认(邮件)
表1 JOB复审流程
处理环节序号 |
审批类型 |
审批角色 |
说明 |
附件/签报正文 |
0 |
申请提交 |
编写JOB程序人员 |
填写签报正文,启动该流程 |
签报中须附上《JOB变更申请表》、《JOB复审报告》、代码、配置表和脚本 |
1 |
内部批示 |
运营JOB负责人 |
确认资料内容的完备性和正确性,确定JOB运行的时间,修改JOB_PACKAGE并更新到CC中 |
附上修改后的JOB_PACKAGE |
2 |
内部批示 |
运营JOB负责人直属领导 |
审核申请的合理性 |
附上修改后的JOB_PACKAGE |
3 |
内部批示 |
DBA组组长(萧青) |
确认申请的合理性 |
DBA总负责人邮件转其它各负责人确认 |
3.临时抓取数据修改数据-----主要用于非工作时间定时进行批处理的情况。
原则上不允许建立临时性JOB,特殊情况下可申请建立。运营的临时JOB必须要建立新的JOB_PACKAGE(job_package_op) / JOB_SCHEDULE_TABLE (job_schedule_table_op) 与业务的job进行区分。
详细申请操作参见4.2.2要点说明
表2临时JOB复审流程
处理环节序号 |
审批类型 |
审批角色 |
说明 |
附件/签报正文 |
0 |
申请提交 |
编写JOB业务程序人员 |
填写签报正文,启动该流程 |
签报中须附上《JOB变更申请表》、《JOB复审报告》、代码、配置表和脚本 |
1 |
内部批示 |
本组JOB负责人 |
确认资料内容的完备性和正确性,确定JOB运行的时间,修改JOB_PACKAGE并更新到CC中 |
附上修改后的JOB_PACKAGE |
2 |
内部批示 |
部门长/编写JOB人员的直属领导 |
审核申请的合理性 |
附上修改后的JOB_PACKAGE |
1、对DBA组创建的JOB实施JOB规范。
2、在JOB新程序测试和上线期间向监控组提出监控申请。
3、提供本组的TIer1 JOB异常处理操作手册,并定期维护手册,确保手册的及时更新,并对Tier1进行必要的培训,使其能满足运营JOB异常处理要求。
4、设置MOSS的JOB异常邮件发送策略,确保JOB异常邮件能及时发送给正确的收件人。
5、根据JOB规范检查开发、运营提交的JOB程序是否符合JOB规范
6、定期主动分析JOB异常,并跟进JOB问题的处理进度(运营、开发)
7、负责审批组内的JOB变更请求(新建、修改、删除、配置表数据调整)
8、各系统JOB用户的权限进行管理,根据用户申请对JOB用户授权或者收回权限。
9、定期审计生产数据库中的JOB用户和JOB,对不符合JOB规范的情况要求开发、运营进行修改。
1、 pait.lbs_group.lbs.application.lbsjob告警:其他G4CS2031.txt 报警信件实例。
2、 监控处理指引-ET-OVO-30025.doc Tier-1处理指引实例。
3、 000_crt_dbajob_usr.sql 创建JOB用户的示例脚本。
4、 001_dbajob_crt_table.sql 创建JOB规范相关表的示例脚本
5、 002_dbajob_crt_pkg.sql,job_package_spec.sql,job_package_body.sql创建job_package的示例脚本
6、 003_dbajob_run_os.sql 创建run_os函数的脚本(Oracle数据库中利用java调用OpC的过程)
7、 004_dbajob_crt_trigger.sql 创建job_error_log表上的trigger的脚本(调用函数发出OpC命令的trigger)
8、 010_dbajob_init_table.sql 初始化JOB参数表的示例脚本。
9、 011_dbajob.create_job.sql 创建新JOB的示例脚本。
10、 JOB复审报告.doc
11、 JOB变更申请表.doc
暂无。
创建新的job用户的代码如下,<示例脚本见000_crt_dbajob_usr.sql>
如果是新申请JOB用户,申请人直接申请JOB用户即可,DBA实施的时候会按照下列模板创建
如果是采用现有用户实施JOB规范,请检查实施规范的用户是否有下列权限,如果没有,请向DBA组提交服务请求申请。
CREATE USER dbajob
IDENTIFIED BY chang_on_create
DEFAULT TABLESPACE dbadata
TEMPORARY TABLESPACE temp
QUOTA UNLIMITED ON dbadata
QUOTA UNLIMITED ON temp;
GRANT CREATE SESSION,CREATE TABLE, CREATE TRIGGER,CREATE PROCEDURE TO dbajob;
--下面四个授权语句要用sys执行
GRANT EXECUTE ON SYS.DBMS_JOB TO dbajob;
GRANT SELECT ON SYS.v_$session TO dbajob;
GRANT SELECT ON SYS.dba_jobs_running TO dbajob;
GRANT SELECT ON SYS.dba_jobs TO dbajob;
--注意:下列代码中的用户名要大写
EXEC Dbms_Java.Grant_Permission('DBAJOB', 'java.io.FilePermission', '/opt/OV/bin/OpC/opcmsg', 'read ,execute');
EXEC dbms_java.grant_permission('DBAJOB','java.lang.RuntimePermission','*','writeFileDescriptor' );
<示例代码见001_dbajob_crt_table.sql>
JOB执行配置表,该表定义JOB的启动执行计划。
CREATE TABLE job_schedule_table
(
job_name VARCHAR2(30) CONSTRAINT nn_ljst_job_name NOT NULL,
description VARCHAR2(500) CONSTRAINT nn_ljst_description NOT NULL,
OPERATOR VARCHAR2(100) CONSTRAINT nn_ljst_job_operator NOT NULL,
developer VARCHAR2(100) CONSTRAINT nn_ljst_job_developer NOT NULL,
early_start_up VARCHAR2(12) CONSTRAINT nn_ljst_job_mistart_time NOT NULL,
lately_start_up VARCHAR2(12) CONSTRAINT nn_ljst_job_mastart_time NOT NULL,
max_running_during NUMBER CONSTRAINT nn_ljst_job_mruning_time NOT NULL,
enable_date DATE CONSTRAINT nn_ljst_job_frun_time NOT NULL,
disable_date DATE,
frequency VARCHAR2(1) CONSTRAINT nn_ljst_job_fre NOT NULL,
alert_level VARCHAR2(10) DEFAULT 'minor' CONSTRAINT nn_ljst_al NOT NULL,
default_alert_level VARCHAR2(10) CONSTRAINT nn_jstm_d_alert_level NOT NULL
)
;
COMMENT ON TABLE job_schedule_table IS 'JOB执行配置表';
COMMENT ON COLUMN job_schedule_table.default_alert_level IS 'JOB的默认报警级别';
COMMENT ON COLUMN job_schedule_table.job_name IS 'JOB名称';
COMMENT ON COLUMN job_schedule_table.description IS 'JOB的描述';
COMMENT ON COLUMN job_schedule_table.OPERATOR IS '运营维护人员';
COMMENT ON COLUMN job_schedule_table.developer IS '开发维护人员';
COMMENT ON COLUMN job_schedule_table.early_start_up IS '最早启动时间(只记录时分秒,如043000,表示4点30分)';
COMMENT ON COLUMN job_schedule_table.lately_start_up IS '最迟启动时间(只记录时分秒,如043000,表示4点30分)';
COMMENT ON COLUMN job_schedule_table.max_running_during IS '最大执行时间长度(以分钟为单位)';
COMMENT ON COLUMN job_schedule_table.enable_date IS 'JOB生效时间';
COMMENT ON COLUMN job_schedule_table.disable_date IS 'JOB失效终止时间';
COMMENT ON COLUMN job_schedule_table.frequency IS '启动频率(D-每天执行,W-每周执行,M-每月执行)';
COMMENT ON COLUMN job_schedule_table.alert_level IS 'JOB的异常报警级别';
COMMENT ON COLUMN job_schedule_table.default_alert_level IS 'JOB的缺省异常报警级别';
ALTER TABLE job_schedule_table ADD (
CONSTRAINT ck_ljst_alert_level
CHECK (alert_level IN ('warning','minor','major','critical')));
ALTER TABLE job_schedule_table ADD (
CONSTRAINT ck_ljst_frequency CHECK (frequency IN ('D','W','M')));
ALTER TABLE job_schedule_table ADD (
CONSTRAINT pk_job_secheule_table PRIMARY KEY (job_name));
字段名 |
类型 |
功能 |
JOB_NAME |
VARCHAR2(30) |
JOB名称 |
DESCRIPTION |
VARCHAR2(500) |
JOB的描述 |
OPERATOR |
VARCHAR2(100) |
运营维护人员 |
DEVELOPER |
VARCHAR2(100) |
开发维护人员 |
EARLY_START_UP |
VARCHAR2(12) |
最早启动时间(只记录时分秒,如043000,表示4点30分) |
LATELY_START_UP |
VARCHAR2(12) |
最迟启动时间(只记录时分秒,如043000,表示4点30分) |
MAX_RUNNING_DURING |
NUMBER |
最大执行时间长度(以分钟为单位) |
ENABLE_DATE |
DATE |
JOB生效时间 |
DISABLE_DATE |
DATE |
JOB失效终止时间 |
FREQUENCY |
VARCHAR2(1) |
启动频率(D-每天执行,W-每周执行,M-每月执行) |
ALERT_LEVEL |
VARCHAR2(10) |
JOB的异常报警级别(Default为minor) |
DEFAULT_ALERT_LEVEL |
VARCHAR2(10) |
JOB的缺省异常报警级别(ALERT_LEVEL可能被修改,可以用这个字段恢复JOB报警级别的缺省值) |
<代码见001_dbajob_crt_table.sql>
<例子数据见table_data_demo.xls>
JOB执行的日志表,在JOB执行的过程中,此表还用作控制JOB的执行次数(每天执行一次)
CREATE TABLE job_running_log
(
username VARCHAR2(30),
SID NUMBER,
serial# NUMBER,
logon_time DATE,
job_proc VARCHAR2(50),
job_function VARCHAR2(100),
start_time DATE,
end_time DATE,
job_status CHAR(1) DEFAULT 'N'
)
;
COMMENT ON TABLE job_running_log IS 'JOB执行LOG表';
COMMENT ON COLUMN job_running_log.username IS '用户名';
COMMENT ON COLUMN job_running_log.SID IS '进程';
COMMENT ON COLUMN job_running_log.serial# IS '序列';
COMMENT ON COLUMN job_running_log.logon_time IS '登陆时间';
COMMENT ON COLUMN job_running_log.job_proc IS '执行的JOB';
COMMENT ON COLUMN job_running_log.job_function IS 'JOB功能描述';
COMMENT ON COLUMN job_running_log.start_time IS '执行开始时间';
COMMENT ON COLUMN job_running_log.end_time IS '执行结束时间';
COMMENT ON COLUMN job_running_log.job_status IS 'JOB执行结果';
ALTER TABLE job_running_log ADD (
CONSTRAINT ck_lbsjoblog_status CHECK (job_status IN ('N','Y')));
字段名 |
类型 |
功能 |
USERNAME |
VARCHAR2(30) |
执行JOB的用户名称(select user from dual) |
SID |
NUMBER |
执行JOB的用户的SID(v$session.sid) |
Serial# |
NUMBER |
执行JOB的用户的serial#(v$session.serial#) |
LOGON_TIME |
DATE |
执行JOB的用户的登录时间(v$session. LOGON_TIME) |
JOB_PROC |
VARCHAR2(50) |
JOB调用的过程 |
JOB_FUNCTION |
VARCHAR2(100) |
JOB的功能描述 |
START_TIME |
DATE |
JOB执行开始时间 |
END_TIME |
DATE |
JOB执行结束时间 |
JOB_STATUS |
CHAR(1) |
JOB的状态,Y(成功)/N(失败)(Default 为N) |
<代码见001_dbajob_crt_table.sql>
<例子数据见table_data_demo.xls>
JOB异常日志表,记录JOB的异常信息。
CREATE TABLE job_error_log
(
error_no VARCHAR2(10) CONSTRAINT nn_lbs_job_error_log_errno NOT NULL,
error_message VARCHAR2(500),
job_name VARCHAR2(30) CONSTRAINT nn_lbs_job_error_log_jobname NOT NULL,
job_user VARCHAR2(30) CONSTRAINT nn_lbs_job_error_log_jobuser NOT NULL,
job_date DATE CONSTRAINT nn_lbs_job_error_log_jobdate NOT NULL,
error_comment VARCHAR2(300),
SID NUMBER,
serial# NUMBER
);
COMMENT ON TABLE job_error_log IS 'LBS JOB错误日志表';
COMMENT ON COLUMN job_error_log.SID IS '运行该JOB的SID';
COMMENT ON COLUMN job_error_log.serial# IS 'SID对应的SERIAL#';
COMMENT ON COLUMN job_error_log.error_no IS '系统错误代码';
COMMENT ON COLUMN job_error_log.error_message IS '系统错误信息';
COMMENT ON COLUMN job_error_log.job_name IS '出错job';
COMMENT ON COLUMN job_error_log.job_user IS '操作用户';
COMMENT ON COLUMN job_error_log.job_date IS '操作时间';
COMMENT ON COLUMN job_error_log.error_comment IS '出错过程';
字段名 |
类型 |
功能 |
ERROR_NO |
VARCHAR2(10) |
系统错误代码 |
ERROR_MESSAGE |
VARCHAR2(500) |
系统错误信息 |
JOB_NAME |
VARCHAR2(30) |
出错job |
JOB_USER |
VARCHAR2(30) |
操作用户 |
JOB_DATE |
DATE |
操作时间 |
ERROR_COMMENT |
VARCHAR2(300) |
出错过程 |
SID |
NUMBER |
运行该JOB的SID (v$session.sid) |
SERIAL# |
NUMBER |
SID对应的SERIAL# (v$session.serial#) |
<代码见001_dbajob_crt_table.sql>
<例子数据见table_data_demo.xls>
CREATE TABLE job_sid_serviceid_relation
(
SID VARCHAR2(30),
serviceid VARCHAR2(100)
)
;
COMMENT ON TABLE job_sid_serviceid_relation IS 'JOB所在数据库SID与OPENVIEW的SERVICEID对应关系表';
COMMENT ON COLUMN job_sid_serviceid_relation.SID IS '数据库的SID';
COMMENT ON COLUMN job_sid_serviceid_relation.serviceid IS 'openview的SERVICEID';
字段名 |
类型 |
功能 |
SID |
VARCHAR2(30) |
数据库的SID |
SERVICEID |
VARCHAR2(100) |
ov的SERVICEID |
<代码见001_dbajob_crt_table.sql>
每个JOB要处理的业务被封装为一个过程放到JOB_PACKAGE中,过程的命名规则为job_x(x为序号),过程的执行的时间和执行的频次都必须在PACKAGE的注释中说明
<示例代码见job_package_spec.sql, job_package_body.sql>
下面列出JOB_Package中的主要过程。
判断当前时间该JOB是否可以执行
/*********************************************************************
执行内容: 返回当前时间该JOB是否可以执行,
该过程为公共过程非JOB批处理过程
参数说明: p_job_name ---JOB的名称
返回值说明:'Y'--该JOB启动时间在配置表中规定的执行时间范围内,
可以执行JOB中的处理过程
'N'--该JOB启动时间在配置表中规定的执行时间范围外,
不可以执行JOB中的处理过程
REVISIONS: 1.0
Ver Date Author Description
--------- ---------- --------------- ------------------------------------
1.0 2006-7-30 基础架构部 甘露 1. Created
*********************************************************************/
function start_on_schedule(p_job_name varchar2) return varchar2 is
v_sid number;
V_serial# number;
v_today date;
v_count number;
v_lasttime date;
begin
select sysdate into v_today from dual where rownum = 1;
--获取当前的SID和SERIAL#
select sid, serial#
into v_sid, v_serial#
from v$session
where sid = (select max(sid)
from v$session
where AUDSID = userenv('sessionid'));
--获取该JOB最后一次启动时间
select nvl(max(start_time), v_today - 1)
into v_lasttime
from JOB_RUNNING_LOG
where upper(job_proc) = upper(p_job_name);
--查看该JOB目前启动时间是否在规定的时间范围内启动
select count(*)
into v_count
from job_schedule_table
where upper(job_name) = upper(p_job_name)
and v_today >= enable_date
and v_today < nvl(disable_date, sysdate + 1)
and to_char(v_today, 'hh24miss') >= early_start_up
and to_char(v_today, 'hh24miss') <= lately_start_up
--and v_lasttime < trunc(v_today) --如果存在一天运行多次的job,请将这一行注释掉。
;
if v_count = 0 then
--如果该JOB在当天的首次启动没有在规定的时间范围内启动,需要上报异常
select count(*)
into v_count
from job_schedule_table
where upper(job_name) = upper(p_job_name)
and v_today >= enable_date
and v_today < nvl(disable_date, sysdate + 1)
and (to_char(v_today, 'hh24miss') < early_start_up or
to_char(v_today, 'hh24miss') > lately_start_up)
and v_lasttime < trunc(v_today);
if v_count > 0 then
insert into job_error_log
(sid,
serial#,
error_no, --系统错误代码
error_message, --系统错误信息
job_name, --出错的job
job_user, --出错的用户
job_date, --出错的时间
error_comment --出错详细信息
)
values
(v_sid,
v_serial#,
'-0000',
'该JOB异常启动:JOB启动出现在非正确时间区间',
p_job_name,
user,
sysdate,
p_job_name || '启动异常');
end if;
return 'N';
else
return 'Y';
end if;
EXCEPTION
when others then
insert into job_error_log
(sid,
serial#,
error_no, --系统错误代码
error_message, --系统错误信息
job_name, --出错的job
job_user, --出错的用户
job_date, --出错的时间
error_comment --出错详细信息
)
values
(v_sid,
v_serial#,
'-0000',
'启动异常-start_on_schedule执行异常',
p_job_name,
user,
sysdate,
p_job_name || '启动异常');
return 'N';
end;
JOB封装过程,将具体的过程封装进来。
/*********************************************************************
执行内容:<执行内容>
执行时间:<执行时间>
执行频次:<执行频次>
创建人: <创建人>
创建时间:<创建时间>
*********************************************************************/
procedure job_<序号> is
v_today date;
v_sid number;
v_serial# number;
v_sqlcode varchar2(6);
v_sqlerrm varchar2(200);
v_error_comment varchar2(300);
begin
---获取当前的时间
select sysdate
into v_today
from dual;
---获取本进程的SID和SERIAL#
select sid,
serial#
into v_sid,
v_serial#
from v$session
where sid=(select max(sid)
from v$session
where AUDSID=userenv('sessionid'));
if start_on_schedule('job_<序号>')='Y' then
insert into JOB_RUNNING_LOG
select user,s.sid,s.serial#,s.logon_time,'job_<序号>','财统数据分析-每月8日',
v_today,trunc(v_today)+8/24,'N'
from v$session s,dba_jobs_running djr,dba_jobs dj
where dj.what ='job_package.job_<序号>;'
and djr.job=dj.job
and s.sid=djr.sid;
----------------------------------------------------------------------------------------------
-- 备注:
-- 对于Oracle 8i/9i环境,上面SQL中对dba_jobs_running的查询会触发oracle bug 3402490、2624130。
-- 因此, 如果Job运行数据库版本低于 10.2.0.0,则必须要使用 /*+ Rule*/ hint,以避免触发此bug.
-- 请使用下面代码代替:
-- insert into JOB_RUNNING_LOG
-- select /*+ rule*/ user,s.sid,s.serial#,s.logon_time,'job_<序号>','财统数据分析-每月8日',
-- v_today,trunc(v_today)+8/24,'N'
-- from v$session s,dba_jobs_running djr,dba_jobs dj
-- where dj.what ='job_package.job_<序号>;'
-- and djr.job=dj.job
-- and s.sid=djr.sid;
--------------------------------------------------------------------------------------------------
commit;
---模块:
---功能:
---维护人:
v_error_comment:='<调用的程序名称>';
<调用的程序名称>;
commit;
update JOB_RUNNING_LOG set END_TIME = sysdate,job_status='Y' where job_proc='job_<序号>' and start_time=v_today;
commit;
end if;
exception
when others then
rollback;
v_sqlcode :=sqlcode;
v_sqlerrm :=substr(sqlerrm,1,200);
insert into job_error_log
(sid ,
serial# ,
error_no , --系统错误代码
error_message , --系统错误信息
job_name , --出错的job
job_user , --出错的用户
job_date , --出错的时间
error_comment --出错详细信息
)
values
(v_sid ,
v_serial# ,
v_sqlcode ,
v_sqlerrm ,
'job_<序号>' ,
user ,
sysdate ,
v_error_comment
);
commit;
end;
例子:再保月度作业每月三号执行
/*********************************************************************
执行内容:再保月度作业
执行时间:
执行频次:每月3日,20:00执行
创建人:惠林源
创建时间:2006-4-13
*********************************************************************/
procedure job_28 is
。。。。。。。
--模块:再保
---功能:再保月度作业
---维护人:林子军
v_error_comment:='lre_reins_month_proc_pkg.execute_proc;';
lre_reins_month_proc_pkg.execute_proc(v_error_comment);
commit;
update JOB_RUNNING_LOG set END_TIME = sysdate,job_status='Y' where job_proc='job_28' and start_time=v_today; --JOB成功执行完毕
commit;
。。。。。。
job每天都运行,通过在lre_reins_month_proc_pkg里面判断是否3日来决定是否执行。如下所示。
这样做可以在执行日期变更的时候只要修改具体的job调用的procedure,不用修改job_package.
if to_char(sysdate,'dd')='03' and v_deptno in ('104','118') then
exception
when others then
rollback;
v_sqlcode :=sqlcode;
v_sqlerrm :=substr(sqlerrm,1,200);
insert into job_error_log
(sid ,
serial# ,
error_no , --系统错误代码
error_message , --系统错误信息
job_name , --出错的job
job_user , --出错的用户
job_date , --出错的时间
error_comment --出错详细信息
)
values
(v_sid ,
v_serial# ,
v_sqlcode ,
v_sqlerrm ,
'job_<序号>' ,
user ,
sysdate ,
v_error_comment
);
commit;
end;
2、数据插入的时候触发如下Trigger
<代码见004_dbajob_crt_trigger.sql>
create or replace trigger tr_i_job_error_log
before insert on job_error_log
referencing new as new old as old
for each row
declare
v_trigger_user varchar2(30);
v_trigger_date date;
v_sid varchar2(30);
v_serviceid varchar2(400);
v_operator varchar2(100);
v_developer varchar2(100);
v_description varchar2(500);
v_alert_level varchar2(10);
v_run_result number;
v_sqlcode varchar2(6);
v_sqlerrm varchar2(200);
v_msg_text varchar2(4000);
v_error_comment varchar2(300);
begin
v_error_comment := 'before get_user';
select user into v_trigger_user from dual;
v_trigger_date := sysdate;
--消息格式为:系统名称+数据库名称+job名称+' '+出错过程名称+'出错,错误代码为:'+错误代码+',出错时间'+出错时间+','+错误描述+
--'运营负责人员:'+运营负责人员+',开发负责人员:'+开发负责人员+'job功能:'+job功能描述+',问题级别'+问题级别
v_error_comment := 'before job_sid_serviceid_relation';
select sid, serviceid
into v_sid, v_serviceid
from job_sid_serviceid_relation
where rownum = 1;
v_error_comment := 'before job_schedule_table';
select operator, developer, description, alert_level
into v_operator, v_developer, v_description, v_alert_level
from job_schedule_table
where upper(job_name) = upper(:new.job_name);
v_error_comment := 'before v_msg_text';
v_msg_text := v_sid || '数据库' || :new.job_name || ',' ||
replace(:new.error_comment, ';', '') ||
'过程出错,出错时间' ||
to_char(:new.job_date, 'yyyy/mm/dd/hh24:mi:ss') || ',' ||
'错误内容:' || :new.error_message || ',运营负责人员:' ||
v_operator || ',开发负责人员:' || v_developer ||
',job功能:' || v_description || ',问题级别:' ||
v_alert_level;
--下面两行一定要保留,第一行为替换半角的空格为全角,第二行为替换换行符号为下划线。
--由于opcmsg无法处理消息中的空格和换行,所以要进行转换
v_msg_text := replace(v_msg_text, ' ', to_multi_byte(' '));
v_msg_text := replace(v_msg_text, chr(10), '_____');
v_run_result := run_os('/opt/OV/bin/OpC/opcmsg severity=' ||
v_alert_level ||
' application=dbajob object=job service_id=' ||
v_serviceid || ' msg_grp=J2EE msg_text=' ||
v_msg_text);
/*
--出错处理
--如果需要错误处理,可以执行后面的脚本创建tr_error_log表,并将这一段的注释去掉。
--如果系统中已经有统一的trigger错误log表,可以用该表将下面的tr_error_log表替换。
exception
when others then
v_sqlcode := sqlcode;
v_sqlerrm := substr(sqlerrm, 1, 200);
insert into tr_error_log
(error_no, --系统错误代码
error_message, --系统错误信息
trigger_name, --出错的trigger
trigger_user, --出错的用户
trigger_date, --出错的时间
error_comment --出错详细信息
)
values
(v_sqlcode,
v_sqlerrm,
'TR_I_JOB_ERROR_LOG',
v_trigger_user,
v_trigger_date,
v_error_comment);
*/
/*
CREATE TABLE tr_error_log
(
error_no VARCHAR2(10) CONSTRAINT nn_tr_error_log_errno NOT NULL,
error_message VARCHAR2(200),
trigger_name VARCHAR2(30) CONSTRAINT nn_tr_error_log_trname NOT NULL,
trigger_user VARCHAR2(30) CONSTRAINT nn_tr_error_log_truser NOT NULL,
trigger_date DATE CONSTRAINT nn_tr_error_log_trdate NOT NULL,
error_comment VARCHAR2(300)
);
COMMENT ON TABLE tr_error_log IS '错误日志表';
COMMENT ON COLUMN tr_error_log.error_no IS '系统错误代码';
COMMENT ON COLUMN tr_error_log.error_message IS '系统错误信息';
COMMENT ON COLUMN tr_error_log.trigger_name IS '出错trigger';
COMMENT ON COLUMN tr_error_log.trigger_user IS '操作用户';
COMMENT ON COLUMN tr_error_log.trigger_date IS '操作时间';
COMMENT ON COLUMN tr_error_log.error_comment IS '出错详细信息';
CREATE INDEX ix_tr_error_log_trdate ON tr_error_log(trigger_date);
CREATE INDEX ix_tr_error_log_trname ON tr_error_log (trigger_name);
*/
end;
/
上面代码中,蓝色部分+红色代码为关键内容,这两部分代码实现消息的拼接和通过操作系统发送给OV的功能。
灰色部分为异常处理,如果需要异常处理,可以执行上面紫色部分的脚本创建tr_error_log表,并将灰色部分代码的注释去掉。如果系统中已经有统一的trigger错误log表,可以用该表将灰色部分代码中德的tr_error_log表替换,并将灰色部分代码的注释去掉。
<示例代码见003_dbajob_run_os.sql >,创建调用操作系统命令的JAVA过程及ORACLE函数
create or replace and compile java source named "RunOS" as
import java.io.*;//避免分号结尾
public class RunOS extends Object{
public static int RunThis(String args){
int rc=0;//
try{
Runtime.getRuntime().exec(args);//
}catch (Exception e){
e.printStackTrace();//
rc = -1;//
}finally{
return rc;//
}
}
}
/
create or replace
function run_os(p_cmd in varchar2) return number
as language java name 'RunOS.RunThis(java.lang.String) return integer';
/
当程序采用指定的参数调用了/opt/OV/bin/OpC/opcmsg之后,消息会送到OpenView中。
当JOB运行完毕后,job_package会update job_running_log表,这个时候下面的Trigger会被触发,判断JOB运行是否超时,如果超时则调用runos函数报警。
只要将红色部分修改为对应的系统名称,然后在JOB用户下执行即可。
如果对格式有要求,可以自行调整。
create or replace trigger tr_u_job_running_log
before update on job_running_log
referencing new as new old as old
for each row
declare
v_trigger_user varchar2(30);
v_trigger_date date;
v_seq_no number;
v_sid varchar2(30);
v_serviceid varchar2(400);
v_operator varchar2(100);
v_developer varchar2(100);
v_description varchar2(500);
v_alert_level varchar2(10);
v_max_running_during number;
v_runing_time number;
v_run_result number ;
v_msg_text varchar2(4000);
v_sqlcode varchar2(6);
v_sqlerrm varchar2(200);
v_error_comment varchar2(300);
v_count number:=0;
begin
--消息格式为:系统名称+数据库名称+job名称+' '+出错过程名称+'出错,错误代码为:'+错误代码+',出错时间'+出错时间+','+错误描述+
--'运营负责人员:'+运营负责人员+',开发负责人员:'+开发负责人员+'job功能:'+job功能描述+',问题级别'+问题级别
v_error_comment:='before job_sid_serviceid_relation';
select sid,
serviceid
into v_sid,
v_serviceid
from job_sid_serviceid_relation
where rownum=1;
v_error_comment:='before job_schedule_table';
select operator,
developer,
description,
alert_level,
max_running_during
into v_operator,
v_developer,
v_description,
v_alert_level,
v_max_running_during
from job_schedule_table
where upper(job_name)=upper(:new.job_proc);
if :new.job_status='Y' then
--查找JOB是否执行超时
select (:new.end_time-:new.start_time)*24*60
into v_runing_time
from dual;
if v_runing_time>v_max_running_during then
v_error_comment:='before v_msg_text';
v_msg_text:='XX系统'||v_sid||'数据库'||:new.job_proc||'出错,出错时间:'||to_char(:new.end_time,'yyyy/mm/dd/hh24:mi:ss')||','||'错误描述:'||'执行时间过长,超过规定时间!!!'||
'运营负责人员:'||v_operator||',开发负责人员:'||v_developer||',job功能:'||v_description||',问题级别:'||v_alert_level;
v_msg_text:=replace(v_msg_text,' ',to_multi_byte(' '));
v_msg_text:=replace(v_msg_text,chr(10),'_____');
v_run_result:=run_os('/opt/OV/bin/OpC/opcmsg severity='||v_alert_level||' application=lbsjob object=job service_id='||v_serviceid||' msg_grp=Monitor msg_text='||v_msg_text);
end if;
end if;
exception
when others then
null;---这里最好进行修改
end;
/
1、 消息进入OpenView之后,会写入OpenView后台数据库。同时进入OVSD(OVSD是基础架构部使用的一套和OV集成的系统,类似于现有的问题管理系统)中。
2、 MOSS系统会定时(3分钟)扫描OpenView数据库,发现新的报警信息后,根据规则发邮件给指定人员。
3、 基础架构部Tier1同事在看到该异常事件后会根据运营提供的Tier1处理指引进行处理(动作包括上报问题管理系统,立刻打电话通知、工作时间电话通知等),由于Tier1是24小时工作的,确保严重异常能够及时得到处理。
4、 运营同事在看到上报的问题后可按照正常问题处理流程进行处理。
5、 如果需要开发协助则转包问题给对应的开发部门。
由运营填写《OVO监控申请表_prd.doc》和制定《Tier1监控指引》(可以参看监控处理指引-ET-OVO-30025.doc),一起由新问题管理系统提交服务请求给监控组申请生产环境的OVO监控,申请成功后,监控组会反馈ServiceID,将serviceID insert到job_sid_serviceid_relation即可
<示例语句见010_dbajob_init_table.sql>
--初始化serviceid
INSERT INTO job_sid_serviceid_relation
VALUES ('ISW', 'pait.db.job.dba');
COMMIT ;
开发在实施JOB规范前,应对现有JOB进行调查,设计好JOB配置表的数据,insert到job_schedule_table即可
<示例语句见010_dbajob_init_table.sql>
--初始化job_schedule_table
INSERT INTO job_schedule_table
(job_name,
description,
OPERATOR,
developer,
early_start_up,
lately_start_up,
max_running_during,
enable_date,
disable_date,
frequency,
alert_level,
default_alert_level
)
VALUES ('job_0101',
'DB质量评测-取数-每天一次',
'甘露/627159',
'甘露/627159',
'030000',
'090000',
60,
SYSDATE,
NULL,
'D',
'minor',
'minor'
);
INSERT INTO job_schedule_table
(job_name,
description,
OPERATOR,
developer,
early_start_up,
lately_start_up,
max_running_during,
enable_date,
disable_date,
frequency,
alert_level,
default_alert_level
)
VALUES ('job_0102',
'DB质量评测-取数-每15分钟一次',
'甘露/627159',
'甘露/627159',
'000000',
'240000',
30,
SYSDATE,
NULL,
'D',
'minor',
'minor'
);
INSERT INTO job_schedule_table
(job_name,
description,
OPERATOR,
developer,
early_start_up,
lately_start_up,
max_running_during,
enable_date,
disable_date,
frequency,
alert_level,
default_alert_level
)
VALUES ('job_0103',
'DB质量评测-计算统计信息-每15分钟一次',
'甘露/627159',
'甘露/627159',
'000000',
'240000',
30,
SYSDATE,
NULL,
'D',
'minor',
'minor'
);
COMMIT ;
做完上述设置后,就要重建目前系统中的JOB
运行下列语句,对当前用户下的JOB参数做备份
Create table bak_user_jobs
As
Select * from user_jobs;
对需要重建的JOB,依次执行dbms_jobs.remove进行删除。
例如:
Exec Dbms_job.remove(24);
<代码示例见011_dbajob.create_job.sql>
DECLARE
X NUMBER;
BEGIN
SYS.DBMS_JOB.SUBMIT
( job => X
,what => 'job_package.job_0103'
,next_date => to_date('30/07/2006 17:58:00','dd/mm/yyyy hh24:mi:ss')
,interval => 'to_date(to_char(trunc(sysdate, ''HH''), ''yyyymmdd hh24:'') || trunc((trunc(sysdate, ''MI'') - trunc(sysdate, ''HH'')) * 24 * 60 / 15) * 15,''yyyymmdd hh24:mi'')+1/24/60*13+1/24/4 '
,no_parse => TRUE
);
SYS.DBMS_OUTPUT.PUT_LINE('Job Number is: ' || to_char(x));
END;
/
commit;
为了避免修改运营job配置表和package影响到生产的业务job,如果需要实施运营的job,则根据下列规范单独建立配置表和package,如果没有运营job则不需要建立。运营JOB的表名为job_schedule_table_op,表结构同job_schedule_table,package为job_package_op,job过程为opjob_xxx。
重复报错分为下列两种情况:
同一JOB在不同机构数据库中报同样的错误
同一JOB在短时间内多次报错。
针对上述第一种情况,LBS已经开发了汇总程序,其他各系统(PCIS,GBS)可以参考LBS的实施方案开发汇总程序,以减少重复上报的数量。
针对第二种情况,目前没有示例代码,也可以根据LBS的汇总代码,进行修改,开发汇总程序 这一部分不是JOB规范的强制实施要求,各系统可以根据自己的具体情况决定是否实施。
(1),如何调试JOB消息-> OV
a.准备工作:设置好job_schedule_table,根据监控组反馈的信息设置run_os的application, object, msg_group, service_id等参数;根据需要设置MOSS系统的参数和接收报警信息Email
b.模拟一个JOB运行错误,看是否能收到报警邮件,如果能收到,则说明系统运行正常。
c.如果没有收到报警邮件,则检查job_error_log,看是否有对应的错误记录,如果没有,则请检查程序,查找无记录插入到job_error_log的原因,并更正
d.如果job_error_log中有数据,但是没有收到报警邮件,请先检查job_error_log上面报警的Trigger是否正常,如果不正常,则查明原因,并更正。
e.如果job_error_log中有数据,而且trigger业正常,但是没有收到报警邮件,则先在JOB用户下执行下面的脚本,注意要讲service_id替换为实际的service_id
如果执行报错,则根据错误信息进行处理。
variable x number;
set serveroutput on
exec dbms_java.set_output(100000);
exec :x := run_os('/opt/OV/bin/OpC/opcmsg severity=minor application=jobtest object=job msg_grp=J2EE service_id=pait.db.job.gbs msg_text=测试消息,请不要处理');
f.如果执行不报错,而Openview也没有消息,则联系负责的DBA,要求DBA协助在后台OS层直接发出命令,看是否报错,如果报错,则根据错误信息调整即可,如果不报错,openview里面也没有错误消息,则联系监控组共同测试,查明原因并解决。
(2)Tier1操作指引的要求
由于Tier1并不负责某个具体模块,对各个系统的具体情况也不了解,故提供的Tier1指引应该假定使用者是有一定电脑操作经验,但是对平安系统没有经验的用户。在指引用,应详细描述操作的步骤,对于用到的问题管理系统或其他上报途径,要指明具体的上报通道,上报格式,系统名称等.应对每个步骤提供截图并配以文字说明
(3)申请OVO监控的方法。
测试环境和开发环境最好一起申请,填写《OVO监控申请表_test.doc》,通过新问题管理系统 “IT基础架构服务-监控组-OVO节点监控申请>”通道上报即可
生产环境的监控申请,请填写《OVO监控申请表_prd.doc》,并制定好Tier1监控指引,以并通过新问题管理系统 “IT基础架构服务-监控组-OVO节点监控申请>”通道上报即可
(4)对于执行频率非常的job应该如何实施job规范?
对于执行频率非常高的job,可以暂缓实施job规范,如果要实施,可以在job_schedule_table里面将开始和结束时间分别置为000000和240000,并对异常进行汇总,每15分钟或者30分钟抛出一次,避免短时间内产生大量报警。
(5)目前我们的规范只做了对于job级(即job调用过程异常退出)的监控,对job调用过程出现的一些异常没有做。是否下一步会做呢?
JOB调用过程出现的异常由各个开发部门自己来处理,主要考虑是过程中的出错主要是数据出错,需要对异常的数据进行监控及处理。而异常数据如何检核与业务逻辑关系比较大。
目前LBS开发对于这部分也设计了统一的过程数据异常跟踪表,并正在开发程序将异常上报到问题管理系统,由运营及开发进行处理。
JOB项目组暂无计划对过程中的异常数据监控做统一的推广。