哥们儿,你们有没有遇到过这种情况,系统跑着跑着,突然就感觉有点不对劲了?慢吞吞的,或者平时应该按时跑的报表、数据同步,结果一看,要么没动静,要么就卡在那儿了。我前段时间就遇到了这么个情况,当时真是急得我团团转,抓耳挠腮的。
那会儿,我主要负责的几个业务系统,上面跑着不少定时任务,什么每天凌晨同步数据,每个小时生成报表,都是排得好好的。结果有一天早上,突然接到好几个业务那边的电话,说报表没出来,数据不对劲。我一听,脑袋都大了,心想这是哪儿出了岔子?
我当时第一反应就是去服务器上看看,CPU、内存、磁盘IO,这些常规的监控指标都瞅了一遍,看着也都没啥异常。可就是感觉不对,系统慢悠悠的。我心里就犯嘀咕,是不是有啥东西在后台偷偷摸摸地跑,把系统资源给占了?或者本来该跑的东西,没跑起来,堵住了?
我就开始瞎折腾,各种命令敲了一遍,想看看有没有什么异常进程。后来我才琢磨明白,我们系统里那些定时任务,它不是随便跑的,都是通过数据库的那个“任务队列”来管理的。这玩意儿,它有个上限,就是能同时跑多少个任务。这个数,就叫job_queue_processes。我一寻思,这会不会是根源?
揪出幕后真凶:从查询参数开始
我立马就想去看看这个job_queue_processes当前是个什么状态。我当时就是这么做的:
-
先摸清老底:查当前的设置是多少。
我直接就进数据库,敲了个命令,想看看这个参数到底设了多少。就像这样:
SHOW PARAMETER job_queue_processes;一敲,结果出来一个数,比方说它显示是10。我心里就有个底了,知道最多只能有10个任务一起跑。
-
接着看谁在跑:找出正在执行的任务。
光知道最大值没用,我还得知道现在到底有几个任务在跑,是哪些任务。我就去查了一个叫
dba_scheduler_running_jobs的表。这个表,顾名思义,就是专门记录那些正在跑的定时任务的。我当时捞数据就是这么捞的:SELECT job_name, session_id, elapsed_time, cpu_used FROM dba_scheduler_running_jobs;这一看,哟呵,果然看到几个平时不怎么见到的任务,已经跑了好久了,有的甚至都超出了平时的运行时间。还有一些,我发现它一直占用着一个会话(session),但又没啥动静,感觉就像是死掉了,但又没自己退出去。
-
再看看队列里还有瞧瞧排队等候的任务。
光看正在跑的不够,我还得知道那些没跑起来的是不是都在排队等着。我就去查了
dba_scheduler_jobs这个表,这个表能看到所有任务的状态。我就筛选了一下,专门看那些状态是“已启用”但还没开始跑的。我当时就是这样摸索的:SELECT job_name, state, last_start_date, next_run_date FROM dba_scheduler_jobs WHERE state = 'SCHEDULED' OR state = 'RETRYABLE';这样一来,我心里就有个谱了,哪些任务是正常的,哪些任务因为前面堵住了,所以没法按时启动。
-
定位具体会话:看看是哪个用户或程序占着茅坑不拉屎。
通过
dba_scheduler_running_jobs我拿到了session_id,我就顺藤摸瓜,直接去v$session里查这个会话的详细信息。这样我就能知道这个会话是哪个用户启动的,它到底在干当时我是这么查的:SELECT sid, serial#, username, program, status, sql_id FROM v$session WHERE sid = <拿到的session_id>;这样一查,我就看到了具体是哪个程序、哪个用户,正在跑哪个SQL,是活跃的还是等待的。我就能知道,是哪个任务卡住了,为什么卡住。有些卡住的任务,我发现它一直在执行一个很复杂的查询,或者在等待某个资源。
小编温馨提醒:本站只提供游戏介绍,下载游戏请前往89游戏主站,89游戏提供真人恋爱/绅士游戏/3A单机游戏大全,点我立即前往》》》绅士游戏下载专区
搞明白后,心里亮堂多了
经过这么一番折腾,我心里就豁然开朗了。原来就是有几个“老油条”任务,平时跑得好好的,结果那天不知道为啥就犯了“懒癌”,一直占着队列里的坑不走,导致后面一堆任务都堵住了,没法正常执行。系统自然就慢了,报表也出不来。
找到问题了,解决起来就好办了。对于那些卡住的任务,我就赶紧手动处理掉。有些就是简单地杀掉会话,让它重新跑;有些是发现SQL有问题,赶紧联系开发去优化。把这些“堵点”一清理,后面那些排队的任务就哗哗地跑起来了,系统也慢慢恢复正常了。
从那以后,我就长了个心眼儿。平时没事儿就会去瞟一眼job_queue_processes的状态,看看有没有“僵尸”任务霸占着资源不放。我甚至还写了个简单的脚本,把这些查询语句都整合起来,设置成定时运行,一旦发现异常情况,它就能第一时间告诉我。这样一来,我对系统的运行状况就掌握得更清楚了,再也不用像以前那样,系统一出问题就两眼一抹黑,抓瞎了。
只要有新的定时任务上线,我都会特别关注一下它的运行情况,看看它会不会影响到job_queue_processes的整体负载。通过这种方式,我现在能比较从容地应对各种突发状况,心里踏实多了。原来以为很复杂的东西,一步步搞明白后,也就那么回事儿。

