Job队列的管理
				
		
		
				
				 
		
				
						    之前学习过一次Job的管理了,但是这次在学习DBA的时候看到,就从理论的高度再重新全面得学习一回。Job的管理比较简单,主要就是对DBMS_JOB这个包的应用和一些参数的设置,而且DBMS_JOB包也比较简单,不需要太复杂的记忆,基本上看一遍就能记住。在建立JOB的时候,最需要注意的还是时间的偏移问题,需要解决好。
				
		
		
				
				 
		
				
				 
		
				
						一、Job执行基础知识
				
		
		
				
				 
		
				
						
								    1、作业队列进程(Jnnn)
						
				
		
		
				
						
						
				 
		
				
						    Oracle使用Job队列进程(Jnnn)来执行作业队列中的Job。对于每一个实例,这些Job队列进程都是由Job队列协调程序(CJQ0)后台进程动态派生的。
				
		
		
				
						    CJQ0定期从DBA_JOBS视图中选出准备运行的Job,并按时间排序,然后派生出Jnnn进程运行选中的Job,每个Jnnn执行一个Job。
				
		
		
				
						
						
				 
		
				
						
								    2、JOB_QUEUE_PROCESSES参数
						
				
		
		
				
						
						
				 
		
				
						    JOB_QUEUE_PROCESSES参数用于控制一个实例上能够并发运行Jnnn进程的最大数目,例如:
				
		
		
				
						    JOB_QUEUE_PROCESSES = 60 指同一时间最多并发处理60个Job
				
		
		
				
						
						
				 
		
				
						    另:如果JOB_QUEUE_PROCESSES = 0则表示数据库启动时不启动任何Job队列协调程序进程,也不执行任何Job
				
		
		
				
						
						
				 
		
				
						
								    3、JOB_QUEUE_PROCESSES的修改
						
				
		
		
				
						
						
				 
		
				
						    Jnnn由Job队列协调进程创建,每次按需要创建Job队列所需的最多的Jnnn进程。当Jnnn执行完某个Job时,它将轮询另一个要执行的Job,如果没有要执行的Job,则该进程进入空闲状态,并在指定时间后再次轮询,在轮询到预定次数后,如果还没有找到要执行的作业,则该进程终止。
				
		
		
				
						
						
				 
		
				
						    ALTER SYSTEM SET JOB_QUEUE_PROCESSES; 可用该语句动态修改最大并发Jnnn进程数目
				
		
		
				
						
						
				 
		
				
						    注1:如果ALTER SYSTEM修改后的JOB_QUEUE_PROCESSES小于当前执行的Jnnn数,则允许超出的执行完当前任务。
				
		
		
				
						    注2:如果实例运行在受限模式,则Jnnn进程不执行Job
				
		
		
				
						
						
				 
		
				
						
						
				 
		
				
						
								二、管理Job队列
						
				
		
		
				
						
						
				 
		
				
						
								    1、DBMS_JOB包
						
				
		
		
				
						
						
				 
		
				
						    Oracle中使用DBMS_JOB包来执行JOB的管理操作,具体包括以下过程:
				
		
		
				
						
						
				 
		
				
						    SUBMIT    :将Job提交到Job队列
				
		
		
				
						    REMOVE    :从Job队列中删除指定Job
				
		
		
				
						    CHANGE    :修改Job( WHAT + NEXT_DATE + INTERVAL )
				
		
		
				
						    WHAT      :修改Job的说明(SQL语句)
				
		
		
				
						    NEXT_DATE :修改Job的下一次执行时间
				
		
		
				
						    INTERVAL  :修改Job的执行间隔
				
		
		
				
						   BROKEN    :设置Job损坏标记(不再执行)
				
		
		
				
						
								
										    RUN       :强制执行Job
						
				
		
		
				
						
						
				 
		
				
						
								    2、DBMS_JOB.SUBMIT
						
				
		
		
				
						
						
				 
		
				
						    使用DBMS_JOB.SUBMIT来提交JOB,主要有以下参数:
				
		
		
				
						
						
				 
		
				
						
								
										    JOB       :这是一个输出参数,是系统分配给JOB的标识符。
						
				
		
		
				
						
								
										    WHAT      :希望执行的PL/SQL代码
						
				
		
		
				
						
								
										    NEXT_DATE :Job下一次运行的日期,默认为SYSDATE
						
				
		
		
				
						
								
										    INTERVAL  :计算下一次执行的日期,默认值为NULL
						
				
		
		
				
						
								
										    NO_PARSE  :TRUE-分析与首次执行Job相关联的过程;FALSE-分析与Job相关的过程(???)
						
				
		
		
				
						
						
				 
		
				
						    具体的说明如下:
				
		
		
				
						
						
				 
		
				
						
								      a) 作业环境
						
				
		
		
				
						
						
				 
		
				
						        当Job被提交时,Oracle还会记录以下信息:
				
		
		
				
						        * 当前user
				
		
		
				
						        * 提交或更改Job的user
				
		
		
				
						        * 当前schema(可能用了alter session set current_schema语句)
				
		
		
				
						        * MAC权限
				
		
		
				
						        * NLS_LANGUAGE
				
		
		
				
						        * NLS_TERRITORY
				
		
		
				
						        * NLS_CURRENCY
				
		
		
				
						        * NLS_ISO_CURRENCY
				
		
		
				
						        * NLS_NUMERIC_CHARACTERS
				
		
		
				
						        * NLS_DATE_FORMAT
				
		
		
				
						        * NLS_DATE_LANGUAGE
				
		
		
				
						        * NLS_SORT
				
		
		
				
						
						
				 
		
				
						
								      b) Job的导入和导出
						
				
		
		
				
						
						
				 
		
				
						        可以在数据库之间导入和导出Job,如果导入时的标识符相同,则不能导入,作为新Job提交
				
		
		
				
						
						
				 
		
				
						
								      c) Job所有者
						
				
		
		
				
						
						
				 
		
				
						        提交者即为Job的所有者,只有Job的所有者可以对Job进行修改、强制执行、删除
				
		
		
				
						
						
				 
		
				
						
								      d) Job号码
						
				
		
		
				
						
						
				 
		
				
						        用于区分的唯一标识符,由SYS.JOBSEQ序列自动产生,永远不能修改,除非删除重建
				
		
		
				
						
						
				 
		
				
						
								      e) Job定义
						
				
		
		
				
						
						
				 
		
				
						        一般在SUBMIT中的WHAT参数都是对某个过程的调用,使用单引号标注。
				
		
		
				
						
						
				 
		
				
						
								        注:不能从一个Job中run另一个Job(remove等其他操作是可以的)
						
				
		
		
				
						
						
				 
		
				
						      f) Job执行间隔
				
		
		
				
						
						
				 
		
				
						        在Job当前执行完成后,会马上计算INTERVAL的指,来指定下一次的运行时间,下面的INTERVAL指都是正确的:
				
		
		
				
						
								        'SYSDATE + 7' --本次执行后的7天
						
				
		
		
				
						
								        'SYSDATE + 1/48' --本次执行后的半小时
						
				
		
		
				
						
								        'NEXT_DAY(TRUNC(SYSDATE),''MONDAY'') + 15/24' --每个星期一下午3点
						
				
		
		
				
						
								        'NEXT_DAY(ADD_MONTHS(TRUNC(SYSDATE,''Q''),3),''THURSDAY'')' --每个季度星期四
						
				
		
		
				
						
						
				 
		
				
						        注:要注意其中的''分隔
				
		
		
				
						
						
				 
		
				
						
								      g) 数据库链接和Job
						
				
		
		
				
						
						
				 
		
				
						        如果在Job中使用到了数据库的链接,那么必须包括用户名和密码,如果是匿名链接,则提交不成功
				
		
		
				
						
						
				 
		
				
						
								    3、Job的执行
						
				
		
		
				
						
						
				 
		
				
						    Jnnn执行Job时,拥有Job所有者的默认权限,所有者必须为Job中引用的所有对象授予所需的对象权限
				
		
		
				
						    当用DBMS_JOB.RUN强制执行Job时:用户只有所有者的默认权限,所有用过角色授予Job所有者的权限都不可用
				
		
		
				
						
						
				 
		
				
						      a) Job队列锁
				
		
		
				
						
						
				 
		
				
						        Oracle使用Job队列锁确保每次Job只在一个会话中执行。
				
		
		
				
						
						
				 
		
				
						        通过查找V$JOB视图的'JQ'类型锁,可以查看明细信息:
				
		
		
				
						
								        SELECT SID,TYPE,ID1,ID2 FROM V$LOCK WHERE TYPE = 'JQ'; --ID2表示Job标识符
						
				
		
		
				
						
						
				 
		
				
						
								      b) Job执行错误
						
				
		
		
				
						
						
				 
		
				
						        Job执行失败时,报ORA-12012错,主要是这样几个原因:
				
		
		
				
						        ① 网络失败或实例失败
				
		
		
				
						        ② 当执行Job时发生异常情况
				
		
		
				
						
						
				 
		
				
						
								        若Job返回错误,则Oracle会在1分钟后重试,然后在2分钟后重试,再在4分钟后重试,每次间隔都是前一次的2倍。
						
				
		
		
				
						
								        直到失败16次,则将该Job标记为“损坏”,并且不再尝试执行该Job。
						
				
		
		
				
						
						
				 
		
				
						
								    4、删除Job
						
				
		
		
				
						
						
				 
		
				
						
								    DBMS_JOB.REMOVE(14144); --直接输入Job号即可
						
				
		
		
				
						
						
				 
		
				
						    限制:
				
		
		
				
						        ① 可以删除目前正在执行的Job,但Job会执行完成当前任务后再被删除
				
		
		
				
						        ② 只能删除自己的所有Job,若要删除其他user的Job,会报错Job不在列表中
				
		
		
				
						
						
				 
		
				
						    5、更改Job
				
		
		
				
				 
		
				
						    使用CHANGE、WHAT、NEXT_DATE、INTERVAL来修改,只要注明Job号即可。
				
		
		
				
						
						
				 
		
				
						    限制:还是只能修改自己所有的Job
				
		
		
				
						
						
				 
		
				
						
								    6、损坏的Job
						
				
		
		
				
				 
		
				
						    Job被标记为损坏只有两种途径:
				
		
		
				
						    ① 尝试执行16次失败
				
		
		
				
						    ② 用DBMS_JOB.BROKEN标记为损坏
				
		
		
				
						
						
				 
		
				
						    运行被标注为损坏的Job也只有两种途径:
				
		
		
				
						    ① 用DBMS_JOB.RUN强制执行
				
		
		
				
						    ② 用DBMS_JOB.BROKEN标记用未损坏
				
		
		
				
						
						
				 
		
				
						    示例:
				
		
		
				
						
								    DBMS_JOB.BROKEN(14144, TRUE); --标记为损坏
						
				
		
		
				
						
								    DBMS_JOB.BROKEN(14144, FALSE, NEXT_DAY(SYSDATE, 'MONDAY')); --标记为未损坏并设置执行间隔
						
				
		
		
				
				 
		
				
						
								   7、强制执行Job
						
				
		
		
				
				 
		
				
						    直接用 DBMS_JOB.RUN(14144); 来强制执行Job
				
		
		
				
						
						
				 
		
				
						
								    注意:一但使用RUN后将不能回滚该Job,而且INTERVAL将会重新计算下一次执行时间
						
				
		
		
				
						
						
				 
		
				
						
								   8、终止Job
						
				
		
		
				
						
						
				 
		
				
						    使用 DBMS_JOB.BROKEN 或 KILL SESSION 两种方法来终止Job
				
		
		
				
						
						
				 
		
				
						
						
				 
		
				
						
								三、查看Job信息
						
				
		
		
				
						
						
				 
		
				
						    DBA_JOBS:所有Job的信息
				
		
		
				
						   ALL_JOBS:当前用户可以访问的所有Job信息
				
		
		
				
						    DBA_JOBS_RUNNING:当前运行的Job信息