今天检查数据库中的备份输出脚本时,发现RMAN备份出现了错误。


这一篇跟踪错误信息,寻找定位问题的方向。




根据前面的问题描述,发现问题越来越复杂,从一个简单的RMAN备份报错,牵扯到系统中有3个长时间运行的JOB,以及RAC环境当前节点存在了大量的RACGMAIN CHECK进程的存在。


虽然问题很复杂,就不要急于盲目操作,先简单分析一下当前的状况。


发现问题是由于RMAN备份脚本报错造成的,但是根据错误信息和随后的测试发现,问题是可以重现的,并不是简单的RMAN问题,导致问题的原因应该是共享资源被占用,RMAN在长时间无法得多资源后被关闭。


在数据库中检查共享资源时,发现V$LOCK视图中有3个可疑会话持有锁信息,进一步查询发现是3个JOB对应的会话,这3个JOB都运行了很长时间,既没有结束,也没有报错。


而在检查操作系统的进程时,发现当前系统存在大量的racgmain check进程,数量居然有四百多个,这是很不正常的,检查其他正常的RAC环境并未发现这个进程的存在。


这3个问题可能是相互关联的,也可能是独立的3个问题,如果3个问题彼此没有联系,那么就要分别去分析并解决这3个问题,如果3个问题是关联的,那么需要寻找一个突破口来快速的定位问题的原因。


根据上一篇文章描述的现象进行推断,这3个问题多半是相关联的,因为RMAN报错并不是普通的RMAN配置问题,根据alert文件中给出的信息,问题是由于共享资源被占有所造成的,而随后查询V$LOCK时,就看到3个长时间没有完成的JOB,这并不是偶然的,虽然还没有看到这3个JOB在做什么,但是怀疑RMAN等待的资源正是被JOB所占用。这说明第一个问题和第二个问题是有联系的,而alert文件给出的共享资源信息本身就和RAC环境关系密切,LMD进程——GLOBAL ENQUEUE SERVICE DAEMON是RAC环境相关的进程,这说明3个问题并非是3个独立的问题,而是彼此相关的问题。


既然3个问题是有关的,那么从那个问题入手呢,原则上讲从哪个分析都可以,因为最终导致问题的原因是同一个。但是实际分析的问题的时候还是有选择的,而不是盲目选择一个问题就开始分析,那样的话很可能事倍功半。一般来说,选择问题的突破点有两个考虑,一个是寻找跟接近导致问题原因的现象来进行分析。如果现象A导致了现象B,那么就选择分析现象A,因为现象B分析的价值已经不大了,现在A更加进行导致问题的原因。另一点考虑就是入手的难易程度,优先分析那些很容易上手的现象,这样解决问题会更加迅速,而且即使发现走错了路,也可以很快的发现。


针对当前的3个问题,RMAN连接报错初步怀疑和JOB运行有关,也就是说RMAN的问题很可能就是JOB运行问题所引起的,那么这里就应该有限分析JOB问题。而JOB问题和RACGMAIN CHECK进程之间暂时无法确定依赖关系,因此不好确定分析的优先级。下面再来对应两个问题分析的难易程度,JOB运行的信息全部保存在数据库中,有很多的视图可供参考,分析起来轻车熟路;而racgmain check进程则完全的不透明,即使有个别的trace文件,其内容也有如天书一般,分析起来肯定会吃力得很。显然应该优先分析数据库中未完成的JOB。


顺便说一句,上面给出的方法适用于大多数的情况,但是有的时候则不尽然。还是以上面3个问题而言,根据目前所获取的信息来看,如果需要查询metalink来获取帮助的话,则应该有限考虑RMAN问题,因为RMAN问题中包含大量的明确的信息,既有RMAN报错信息,也有导致报错信息的命令,因此可以很容易的找到最相关的问题描述。对于racgmain check进程问题而言,racgmain check本身就是一个很好的查询关键词,很容易在metalink中找到相关的信息。而对于JOB问题而言,并不是搜索不到信息,而是当前获取的信息不足以通过搜索来找到有意义的信息,需要进一步发掘JOB未发成的其他原因,找到适合搜索的关键点信息。虽然RMAN问题和RACGMAIN CHECK进程问题适合进行搜索,但是不幸的是,搜索解决和当前情况比较类似的不多,而且很难确定当前的问题和metalink中描述的是同一个问题,因此还是应该继续分析Oracle中的JOB信息。


SQL> SELECT SID, JOB FROM DBA_JOBS_RUNNING;


      SID        JOB


---------- ----------


      118          4


      102         74


      289         27


SQL>COLWHAT FORMAT A60


SQL> SELECT JOB, LOG_USER, WHAT


 2  FROM DBA_JOBS


 3  WHERE JOB IN (4, 27, 74);


      JOB LOG_USER             WHAT


---------- -------------------- --------------------------------------------------------


        4 NDMAIN               DBMS_STATS.GATHER_SCHEMA_STATS(USER, CASCADE => TRUE);


       27ZHEJIANG             dbms_stats.gather_schema_stats(user, cascade => true);


       74 GPO                  P_Project_Stat;


根据JOB信息,前面两个JOB运行都是和统计信息有关,第3个JOB运行的过程是用户自定义的过程。


SQL> SELECT SID, TYPE, ID1, ID2, LMODE, REQUEST, CTIME, BLOCK


 2  FROM V$LOCK


 3  WHERE SID IN (102, 118, 289)


 4  ORDER BY CTIME DESC;


      SID TY        ID1        ID2      LMODE    REQUEST      CTIME      BLOCK


---------- -- ---------- ---------- ---------- ---------- ---------- ----------


      118 JQ          0          4          6          0     151090          2


      118 TO     196404          1          3          0     151087          2


      118 TX     262181      87690          6          0     151087          2


      118 TM     196404          0          3          0     151087          2


      289 JQ          0         27          6          0     147490          2


      102 JQ          0         74          6          0     147487          2


      289 TO  -40016215          1          3          0     147484          2


      289 TX     458770      86777          6          0     147484          2


      102 TM      70434          0          3          0     147466          2


已选择9行。


可以看到会话118持有锁的时间最长,对比DBA_JOBS_RUNNING信息:


SQL> SELECT SID, JOB, LAST_DATE, THIS_DATE


 2  FROM DBA_JOBS_RUNNING;


      SID        JOB LAST_DATE           THIS_DATE


---------- ---------- ------------------- -------------------


      118          4 2009-05-10 00:00:05 2009-05-24 00:00:02


      102         74 2009-05-23 01:00:00 2009-05-24 01:00:04


      289         27 2009-05-17 01:00:03 2009-05-24 01:00:04


仔细观察后才发现,这个JOB运行的时间是在RMAN进程运行之后。根据上一篇文章的描述,RMAN语句的运行时间是23日的23点左右,而JOB运行时间是24日的0点到1点,显然RMAN语句报错并不是JOB未完成的原因,倒是有可能导致二者原因的问题都是同一个,再检查racgmain check进程问题:


bash-3.00$ ps -ef|grep racgmain


 oracle 24085     1   0   May 23 ?           0:00 /opt/oracle/product/10.2/crs/bin/racgmain check


 oracle 20734     1   0   May 23 ?           0:00 /opt/oracle/product/10.2/crs/bin/racgmain check


 oracle 19021     1   0   May 23 ?           0:00 /opt/oracle/product/10.2/database/bin/racgmain check


 oracle 19035     1   0   May 23 ?           0:00 /opt/oracle/product/10.2/database/bin/racgmain check


 oracle 20207     1   0   May 23 ?           0:00 /opt/oracle/product/10.2/database/bin/racgmain check


 oracle 25186     1   0   May 23 ?           0:00 /opt/oracle/product/10.2/crs/bin/racgmain check


 oracle 20385     1   0   May 23 ?           0:00 /opt/oracle/product/10.2/database/bin/racgmain check


 oracle 18960     1   0   May 23 ?           0:00 /opt/oracle/product/10.2/database/bin/racgmain check


 oracle 22094     1   0   May 23 ?           0:00 /opt/oracle/product/10.2/crs/bin/racgmain check


 oracle 23123     1   0   May 23 ?           0:00 /opt/oracle/product/10.2/database/bin/racgmain check


.


.


.


 oracle 23166     1   0   May 23 ?           0:00 /opt/oracle/product/10.2/database/bin/racgmain check


 oracle 23508     1   0   May 23 ?           0:00 /opt/oracle/product/10.2/database/bin/racgmain check


 oracle 18643     1   0   May 23 ?           0:00 /opt/oracle/product/10.2/database/bin/racgmain check


 oracle 18420     1   0   May 23 ?           0:00 /opt/oracle/product/10.2/database/bin/racgmain check


可以发现所有的racgmain check进程都是5月23日启动的,那么导致RMAN和JOB问题的真正原因很可能是racgmain check进程问题。


检查rac其他实例上,没有发现这个进程:


bash-3.00$ ps -ef|grep racgmain


 oracle 12451 12157   0 17:36:19 pts/1       0:00 grep racgmain


看来问题就是发生在当前节点上。


虽然导致问题的原因多半和racgmain进程有关,但是racgmain进程很难进行诊断,所以还是先检查一些导致JOB未完成的真正原因,这对于解决问题也是有帮助的:


SQL> SELECT EVENT,


 2  P1TEXT,


 3  P1,


 4  P2TEXT,


 5  P2,


 6  WAIT_CLASS,


 7  SECONDS_IN_WAIT WAIT


 8  FROM V$SESSION_WAIT


 9  WHERE SID IN (102, 118, 289)


10  ORDER BY WAIT DESC;


EVENT                P1TEXT                  P1 P2TEXT               P2 WAIT_CLASS    WAIT


-------------------- --------------- ---------- ------------ ---------- ----------- ------


gc cr request        file#                   14 block#            36545 Cluster     153419


enq: TO - contention name|mode       1414463491 object #     4254951081 Other       149816


library cache lock   handle address  2.0935E+10 lock address 2.3357E+10 Concurrency 149798


可以看到,最先被锁住的JOB会话在等待gc cr request,而这个会话等待事件的类型正是CLUSTER,这说明第一个会话在尝试取得远端内存中的数据块时被锁住,而这个现象和大量的racgmain check进行显然有关系。


检查V$SESSION_LONGOPS视图,可以看到两个收集统计信息的会话停止的位置。


SQL> SELECT SID, MESSAGE    


 2  FROM V$SESSION_LONGOPS


 3  WHERE TOTALWORK != SOFAR


 4  AND SID IN (102, 118, 289);


      SID MESSAGE


---------- ---------------------------------------------------------------------------


      289 Gather Table's Index Statistics: Table ASS_NEWS : 1 out of 2 Indexes done


      289 Gather Schema Statistics: Schema : 8 out of 444 Objects done


      118 Gather Schema Statistics: Schema : 2 out of 138 Objects done


检查会话锁的对象信息:


SQL> SELECT * FROM DBA_DML_LOCKS WHERE SESSION_ID IN (102, 118, 289);


SESSION_ID OWNER NAME                 MODE_HELD     MODE_REQUESTE LAST_CONVERT BLOCKING_OTHERS


---------- ----- -------------------- ------------- ------------- ------------ ---------------


      102 GPO   GPO_PROJECT_PRODUCT  Row-X (SX)    None                158825 Global


      118 SYS   ORA_TEMP_1_DS_143368 Row-X (SX)    None                162446 Global


其中ORA_TEMP_1_DS_143368是SYS生成的临时表:


SQL>COLOBJECT_NAME FORMAT A30


SQL> SELECT OWNER, OBJECT_NAME, OBJECT_TYPE, OBJECT_ID


 2  FROM DBA_OBJECTS


 3  WHERE OBJECT_NAME = 'ORA_TEMP_1_DS_143368';


OWNER OBJECT_NAME                    OBJECT_TYPE          OBJECT_ID


----- ------------------------------ ------------------- ----------


SYS   ORA_TEMP_1_DS_143368           TABLE                   196404


SQL> SELECT TABLE_NAME, TABLESPACE_NAME, TEMPORARY


 2  FROM DBA_TABLES


 3  WHERE WNER = 'SYS'


 4  AND TABLE_NAME = 'ORA_TEMP_1_DS_143368';


TABLE_NAME                     TABLESPACE_NAME                T


------------------------------ ------------------------------ -


ORA_TEMP_1_DS_143368                                          Y


正是这个临时表的操作,导致了会话的TO等待事件,而且这个临时表是Oracle收集统计信息时使用的,它的结构与当前正在访问的用户对象结构一致:


SQL> SELECT OWNER, SEGMENT_NAME


 2  FROM DBA_EXTENTS


 3  WHERE FILE_ID = 14


 4  AND BLOCK_ID <= 36545


 5  AND BLOCK_ID + BLOCKS >= 36545;


OWNER      SEGMENT_NAME


---------- ------------------------------


NDMAIN     CAT_AREA_MEDICARE


SQL> DESC NDMAIN.CAT_AREA_MEDICARE


名称                                   是否为空?类型


--------------------------------------- -------- ------------------------


ID                                      NOT NULL CHAR(24)


PRODUCT_ID                              NOT NULL CHAR(24)


PLAT_ID                                 NOT NULL CHAR(24)


INSURED_DRUG_NUBMER                     NOT NULL VARCHAR2(8)


INSURED_DRUG_TYPE                       NOT NULL CHAR(1)


LAST_UPDATE_USER                                 CHAR(24)


LAST_UPDATE_DATE                                 DATE


LAST_UPDATE_PLAT                                 CHAR(24)


LAST_UPDATE_ORG                                  CHAR(24)


SQL> DESC ORA_TEMP_1_DS_143368


名称                                   是否为空?类型


--------------------------------------- -------- -----------------------


ID                                      NOT NULL CHAR(24)


PRODUCT_ID                              NOT NULL CHAR(24)


PLAT_ID                                 NOT NULL CHAR(24)


INSURED_DRUG_NUBMER                     NOT NULL VARCHAR2(8)


INSURED_DRUG_TYPE                       NOT NULL CHAR(1)


LAST_UPDATE_USER                                 CHAR(24)


LAST_UPDATE_DATE                                 DATE


LAST_UPDATE_PLAT                                 CHAR(24)


LAST_UPDATE_ORG                                  CHAR(24)


虽然清楚了Oracle在做什么,但是还是不知道这个会话为什么会hang住,检查当前事务:


SQL> SELECT SID, TYPE, ID1, ID2, CTIME, START_DATE, XIDSQN


 2  FROM V$TRANSACTION A, V$LOCK B


 3  WHERE A.ADDR = B.ADDR;


      SID TYPE              ID1        ID2      CTIME START_DATE              XIDSQN


---------- ---------- ---------- ---------- ---------- ------------------- ----------


      144 TX             655449     137382     188527 2009-05-23 17:00:40     137382


      118 TX             262181      87690     163364 2009-05-24 00:00:04      87690


      289 TX             458770      86777     159761 2009-05-24 01:00:07      86777


      277 TX             524320      89189     174678 2009-05-23 20:51:30      89189


除了刚才看到的JOB会话,当前事务还包括另外两个会话,而且这两个会话的启动时间更早:


SQL> SELECT SID, PROGRAM, ACTION, EVENT, SECONDS_IN_WAIT


 2  FROM V$SESSION


 3  WHERE SID IN (144, 277);


      SID PROGRAM              ACTION                  EVENT                SECONDS_IN_WAIT


---------- -------------------- ----------------------- -------------------- ---------------


      144 oracle@ahrac1 (m000) Auto-Flush Slave Action gc current request            188734


      277 oracle@ahrac1 (m001) ASH Emergency-Flush     row cache lock                174885


显然这是Oracle后台工具进行的操作,不过这两个会话的等待时间同样存在问题,而且根据V$TRANSACTION会话显示的时间,会话144的启动时间显然要远远早于RMAN启动的时间。而且会话144在gc current request,这个事件仍然和RAC环境有关。



oracle视频教程请关注:http://u.youku.com/user_video/id_UMzAzMjkxMjE2.html