懵懂oracle之存储过程3--JOB详解
1 初始化 1.1 初始化权限 使用dbms_job包如果遇到权限问题,那么需要使用管理员账号给此用户赋予权限: 1 grant execute on dbms_job to 用户; 1.2 初始化参数 重点关注job_queue_processes参数,它告诉了数据库最多可创建多少个job进程来运行job,可通过下面语句查询改参数值情况: select name,value,display_value from v$parameter where name in ('spfile',job_queue_processes');当job_queue_processes参数对应的value为0时,则代表所有创建的job都不会运行,因此我们需将此参数值根据各自需要修改至n(1~1000):
2 dbms_job包分析(可在数据库中查看此包获取相关信息,暂未分析包内user_export存过的用法) 2.1 内部存过参数汇总
2.2 内部存过详解 新建存过sp_test_hll_170726以作后面测试使用1)submit:用于新建一个定时任务
2)isubmit:用于新建一个定时任务同时指定JOB编号
3)remove:用于从JOB任务队列中移除一个JOB(不会中断仍在运行的JOB)
4)what:用于修改what参数值
8)change:用于修改what、next_date、interval、instance、force参数值
10)run:用于立即执行此定时任务(被broken挂起的存过也会取消挂起并运行)
3 JOB任务队列查询处理汇总 3.1 表汇总(SYS.JOB$、DBA_JOBS、ALL_JOBS、USER_JOBS、DBA_JOBS_RUNNING) 在通过上面介绍的dbms_job包对JOB进行的处理,实际上处理的是数据库的任务队列表SYS.JOB$,我们可以通过下面语句查看该表情况: select t.job,t.lowner,t.powner,t.cowner,t.last_date,t.this_date,t.next_date,t.total,t.interval#,t.failures,t.flag,t.what,128); line-height:1.5!important">2 t.nlsenv,t.env,t.charenv,t.field1,t.scheduler_flags,t.xid 3 /*,t.cur_ses_label,t.clearance_hi,t.clearance_lo 不能查询这三个字段,会报异常ORA-00932: 数据类型不一致: 应为 NUMBER,但却获得 LABEL 它们的数据类型为MLSLABEL,在TRUSTED ORACLE中用来保存可变长度二进制标签。 6 from sys.job$ t; 但是它的数据长得不好看,Oracle提供了我们两个视图(DBA_JOBS、USER_JOBS)可以查看: DBA_JOBS,所有用户拥有的JOB USER_JOBS,当前用户拥有的JOB同时通过下面语句我们可以知道,还有一个同义词ALL_JOBS: ALL_JOBS,USER_JOBS的同义词我们通过下面语句都能查询我们建立好的JOB的信息: select * from dba_jobs; from all_jobs; from user_jobs;DBA_JOBS/ALL_JOBS/USER_JOBS各字段的含义如下: 1 字段(列) 数据类型 描述 2 JOB NUMBER 任务的唯一标示号 3 【Identifier of job. Neither import/export nor repeated executions change it.】 4 LOG_USER VARCHAR2(30) 提交任务时登录的用户 5 【USER who was logged when the job was submitted】 6 PRIV_USER 30) 任务默认权限对应的用户 7 【USER whose privileges apply to this job】 8 SCHEMA_USER 30) 对任务作语法分析的用户模式(查询bar表代表查询schema_user.bar表) 9 【from bar means from schema_user.bar】 10 LAST_DATE DATE 最后一次成功运行任务的时间 11 【Date that this job last successfully executed】 12 LAST_SEC 32) 长度为8的HH24:MI:SS格式的LAST_DATE 13 【Same as LAST_DATE. This is when the last successful execution started.】 14 THIS_DATE DATE 正在运行任务的开始时间,如果没有运行任务则为null 15 【Date that this job started executing (usually if not executing)】 16 THIS_SEC 32) 长度为8的HH24:MI:SS格式的THIS_DATE 17 【Same as THIS_DATE. This 18 NEXT_DATE DATE 下一次定时运行任务的时间 19 【Date that this job will next be executed】 20 NEXT_SEC 32) 长度为8的HH24:MI:SS格式的NEXT_DATE 21 【Same as NEXT_DATE. The job becomes due for execution at this time.】 22 TOTAL_TIME NUMBER 数据库用于执行此任务的总秒数统计 23 【Total wallclock time spent by the system on this job,128); line-height:1.5!important">in seconds】 24 BROKEN 1) 中断标识,Y表示任务中断,不再尝试执行此任务 25 【If Y,no attempt is being made to run this job. See dbms_jobq.broken(job).】 26 INTERVAL 200) 用于计算下此运行时间的时间表达式 27 【A date function,evaluated at the start of execution,becomes next NEXT_DATE】 28 FAILURES NUMBER 自最后一次成功之后任务运行失败的总次数 29 【How many times has this job started and failed since its last success?】 30 WHAT 4000) 任务执行的匿名PL/SQL块 31 【Body of the anonymous PL/SQL block that this job executes】 32 NLS_ENV 4000) 任务运行的NLS会话设置 33 【alter session parameters describing the NLS environment of the job】 34 MISC_ENV RAW(32) 任务运行的其他一些会话参数 35 【a versioned raw maintained by the kernel,255); line-height:1.5!important">for other session parameters】 36 INSTANCE NUMBER 任务执行时限制关联的数据库实例 37 【Instance number restricted to run the job】 同时,Oracle还提供了DBA_JOBS_RUNNING视图供我们查询正在运行的任务: DBA_JOBS_RUNNING,数据库中所有正在运行的JOB,关联v$lock和job$表通过下面语句可简单查询该表情况: from dba_jobs_running;DBA_JOBS_RUNNING各字段含义如下: 2 SID NUMBER 正在运行任务的会话ID of process which is executing the job. See v$lock. 】 4 JOB NUMBER 正在运行任务的唯一标示号 5 【Identifier of job. This job is currently executing.】 6 FAILURES 7 【How many times has this job started 8 LAST_DATE DATE 最后一次成功运行任务的时间 9 【Date that this job last successfully executed】 10 LAST_SEC 11 【Same 12 THIS_DATE DATE 正在运行任务的开始时间,如果没有运行任务则为null 13 【Date that this job started executing (usually 14 THIS_SEC 15 【Same 16 INSTANCE 17 【Instance to run the job 3.2 JOB的失败重试 当JOB实现失败时,数据库会自动安排重新执行,此时JOB执行时间按下面情况来定: 2) 第i次失败,等待2i分钟后开始第i+1次数据库自动安排的重新执行,当2i>1440分钟时,时间固定为1440分钟; 3) 重试次数达16次时,JOB不再自动执行(用户还是可手动执行再失败的),标记中断标识, 3.3 停止正在运行的JOB 由于remove、broken都只是影响任务后续的执行情况,并不会对正在运行的任务造成影响,而有些情况下,由于存储过程的问题或者数据之间的影响等各种原因导致JOB执行异常,我们需要终止正在运行的异常JOB;也可能是JOB执行时间过长,人为需要停止正在运行的JOB。在这个时候我们需要按下面步骤进行处理: ** 第一步:查询JOB情况得到需要停止的JOB的编号 **from user_jobs; from dba_jobs_running; 4 ** 第二步:将需要停止的JOB标记中断,以避免停止后又运行 ** 7 dbms_job.broken(job编号,true); 8 10 / 11 ** 第三步:查询JOB运行情况,并选择适当语句杀会话,甚至杀进程(谨慎操作) **select b.job,128); line-height:1.5!important"> JOB编号 14 a.what,128); line-height:1.5!important"> 任务内容 15 b.failures,128); line-height:1.5!important"> 失败次数 16 b.this_date,128); line-height:1.5!important"> 开始时间 17 floor(sysdate - b.this_date) || 天' || 18 to_char(trunc(sysdate,0); line-height:1.5!important">') + (sysdate - b.this_date),0); line-height:1.5!important">hh24:mi:ss') this_total,128); line-height:1.5!important"> 当前耗时 19 (select f.sql_fulltext 20 from v$locked_object e,v$sql f 21 where e.session_id = c.sid 22 and f.hash_value = c.sql_hash_value 23 and rownum = 1) sql_fulltext,128); line-height:1.5!important"> 如果锁对象,则获取当前sql 24 c.inst_id,128); line-height:1.5!important"> 数据库实例ID 25 g.host_name ==>|| utl_inaddr.get_host_address(g.host_name) "机器==>IP",128); line-height:1.5!important"> 机器及IP 26 c.status,128); line-height:1.5!important">会话状态 27 alter system kill session ''' || b.sid || c.serial# 28 ''' immediate;' 普通环境杀会话,128); line-height:1.5!important"> session级杀会话 29 30 c.inst_id ' RAC环境杀会话,128); line-height:1.5!important"> RAC环境session级杀会话 31 /* kill session语句并不实际杀死会话,只相当于让会话自我清除,在某些情况下,例如等待远程数据库应答或 回滚当前事务时,都会等待这些操作完成,这时就将会话状态标记为"marked for kill",数据库会尽快将它杀掉, 如果加上immediate,那么则会要求将控制权立即返回给当前会话 35 36 alter system disconnect session 37 post_transaction或immediate;' 数据库杀进程,128); line-height:1.5!important">38 39 c.inst_id ' 数据库RAC环境杀进程,128); line-height:1.5!important">40 disconnect是在数据库中从操作系统层面清除服务器进程, 42 post_transaction表示清除前需等待正在进行的事务完成, 而immediate则表示立即清除并回滚正在进行的事务, 44 两者必须有其一,都有时,post_transaction优先级高,忽视immediate子句。 45 用disconnect我们就不用切换到操作系统层面用下面语句去清除进程了 46 47 orakill || g.instance_name ' || d.spid "Windows杀进程",128); line-height:1.5!important">48 kill || d.spid "UnixORLinux杀进程1",128); line-height:1.5!important">49 kill -9 || d.spid "UnixORLinux杀进程2" 用1杀不掉就加-9 50 51 不管是在数据库用disconnect还是上面到操作系统上面敲kill命令,都是杀的进程, 杀掉操作系统进程是一件危险的事情,千万不得误杀,请务必谨慎操作,严格确认。 54 from user_jobs a,128); line-height:1.5!important">55 dba_jobs_running b,128); line-height:1.5!important">56 gv$session c,128); line-height:1.5!important">57 gv$process d,128); line-height:1.5!important">58 gv$instance g 59 where a.job = b.job 60 and b.sid 61 and c.paddr = d.addr 62 and g.inst_id = c.inst_id; 63 ** 第四步:恢复JOB,使其继续执行 ** 如果JOB未修复好,可不执行此步操作 67 dbms_job.broken(job编号,false); 68 dbms_job.broken(job编号,false,可加个参数修改接来下运行的时间原默认为sysdate); 69 70 71 /(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |