数据库服务器
系统:Solaris 5.9  两台做cluster,共享磁盘阵列柜
数据库:Oracle 9.2.0.5 做的是RAC
现象:最近2个月发现不时的客户端应用程序无法登录,像死机一样一直等待(2个月前一直正常,这套系统已经投入使用5年)。
应用服务器
    Windows 2003,安装了oracle客户端工具,版本9.2.0.1。这套系统是三层结构体系,客户端应用程序通过应用服务器来对数据库进行访问。这是应用服务器tnsnames.ora的部分内容,应用程序就是通过NODEORA这个服务名来连接数据库的。
NODEORA =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = fmislssun1)(PORT = 1521))
      (ADDRESS = (PROTOCOL = TCP)(HOST = fmislssun2)(PORT = 1521))
      (LOAD_BALANCE = yes)
    )
    (CONNECT_DATA =
      (SERVICE_NAME = fmis.lsdyj)
      (FAILOVER_MODE =
        (TYPE = session)
        (METHOD = basic)
      )
    )
  )NODE1 =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = fmislssun1)(PORT = 1521))
    )
    (CONNECT_DATA =
      (SERVICE_NAME = fmis1)
    )
  )NODE2 =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = fmislssun2)(PORT = 1521))
    )
    (CONNECT_DATA =
      (SERVICE_NAME = fmis2)
    )
  )当客户端应用程序无法登录时,我登录到应用服务器,使用sqlplus system/manager@nodeora连接数据库,不能进入到sql>提示符下,没有提示任何错误,会一直等待,按Ctrl+c中止也没有用。这时候查看alert_sid.log和listener.log在这个时间段都没有任何错误信息。
为了马上解决问题,我只能startup force重新启动一台数据库,一般来说就能恢复,但偶尔,还必须重启另一台数据库。
(用户是上帝啊,NND,不然我的工作早丢了)为了复现这样的故障,我进行了大量测试,终于发现当客户端进行了大任务查询时(需要数分钟才能完成的综合查询),就会出现这种故障。当客户端这个大任务完成后竟然发现数据库自动恢复正常了。于是我想到可能是数据库工作不正常导致CPU资源占用太高的原因,于是故障时登录solaris,使用prstat命令查看进程信息,会发现其中一台数据库服务器的cpu占用率25%,另一台完全是空载。对于大型的查询,这样的负载为过么?
   PID USERNAME  SIZE   RSS STATE  PRI NICE      TIME  CPU PROCESS/NLWP
 20735 oracle   4126M 4087M cpu0     0    0   2:37:37  25% oracle/2
 20729 oracle   3995M 3950M sleep   59    0   0:00:50 0.6% oracle/2
   761 root       60M   24M sleep   29   10  74:45:18 0.1% java/12
 10936 root     5896K 4952K cpu2    59    0   0:00:00 0.0% prstat/1
…………我也仔细检查了oracle各项参数和状态,或许是我水平太差,看不出哪里与这种故障有关
没法了,用explorer工具导出了solaris系统状态并发给solaris工程师,看看是不是系统出现毛病,solaris工程师的回答是:系统完全正常……有一次发生故障时,我发现在应用层服务器上使用sqlplus system/manager@node1和sqlplus system/manager@node2来连接数据库的时候完全正常!!!但使用nodeora服务名连接数据库依然是漫无天日的等待。
为了进一步缩小故障范围,我在两台solaris的tnsnames.ora添加了如下代码:
FMIS =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = fmislssun1)(PORT = 1521))
      (ADDRESS = (PROTOCOL = TCP)(HOST = fmislssun2)(PORT = 1521))
      (LOAD_BALANCE = yes)
    )
    (CONNECT_DATA =
      (SERVICE_NAME = FMIS.LSDYJ)
    )
  )
FMIS1 =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = fmislssun1)(PORT = 1521))
    )
    (CONNECT_DATA =
      (SERVER=DEDICATED)
      (SERVICE_NAME = FMIS.LSDYJ)
      (INSTANCE_NAME = FMIS1)
    )
  )
FMIS2 =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = fmislssun2)(PORT = 1521))
    )
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = FMIS.LSDYJ)
      (INSTANCE_NAME = FMIS2)
    )
  )
再登录到solaris,使用sqlplus system/manager@fmis1和sqlplus system/manager@fmis2连接数据库也完全正常,但试图sqlplus system/manager@fmis时依然无法连接,这时我按Ctrl+c后等了2分钟,终于看到oracle报错(破天荒头一回啊,老天开眼了,再不开眼我的工作就除脱了):
ORA-03106: fatal two-task communication protocol error可是对于ora-03106,说的是通信的问题,我在数据库服务器上测试也会有些故障,不可能是网络通信或者客户端连接程序版本的问题,但那又是什么原因引起的?
并且ora-03106并不是正常情况出现的,只有我在数据库服务器上测试时,强行按Ctrl+c才出现的提示?那么这个错误会不会是一种误导?
那么还能有什么原因?
各位帅哥们,帮忙分析一下啊!不胜感激

解决方案 »

  1.   

    用crs_stat 检查一下crs的各项服务的状态如何。是大任务查询的时候连接不上,还是其他时候都连接不上,连接不上的时候,看看内存分配的状况,以及pga的使用。
      

  2.   

    看来我也想不到原因,不过我有几个疑点:
    1、问题出现时,分别登录node1和node2都是正常的,只有通过nodeora连接数据库时有问题
    2、问题出现时,重启一台数据库基本上可以解决问题
    3、出现问题的时候在执行大事务查询
    4、出现问题时,nodeora其实还是有响应的,只是在等了两分钟后才给出(说明某项资源不够用)所以我觉得问题可能在内存分配上,能不能看一下相关的几块内存在这个时候都是什么情况的?
      

  3.   

    感觉重新启动对ORACLE就是一种灾难,不知道启动后会出现什么问题
      

  4.   


    请教inthirties兄,crs_stat是oracle工具么?但系统里没有这个命令,是不是10g才有这个命令,我这里oracle版本是9205。pga分配的是256M,自动管理,一般分配的pga在50-80M之间,最高的时候也没有超过180M
    SQL> show parameter pgaNAME                                 TYPE        VALUE
    ------------------------------------ ----------- ------------
    pga_aggregate_target                 big integer 268435456
    SQL> show parameter workNAME                                 TYPE        VALUE
    ------------------------------------ ----------- ------------
    workarea_size_policy                 string      AUTO
      

  5.   

    每台数据库服务器内存都是8GB,共享池1536M,缓冲区高速缓存2000M,大池256M,java池16M,应用程序不是java的,delphi编写的。
    出故障时,我运行了一个数据库检测脚本,部分内容如下:
    SQL> show sga;Total System Global Area 4095188752 bytes
    Fixed Size                   737040 bytes
    Variable Size            1996488704 bytes
    Database Buffers         2097152000 bytes
    Redo Buffers                 811008 bytes
    SQL> select * from v$sgastat;POOL        NAME                            BYTES
    ----------- -------------------------- ----------
                fixed_sga                      737040
                buffer_cache               2097152000
                log_buffer                     787456
    shared pool errors                          54672
    shared pool KGK heap                         7000
    shared pool KQR L PO                     14441672
    shared pool KQR M PO                     32437208
    shared pool KQR S SO                         5632
    shared pool sessions                       905840
    shared pool sql area                    893157464
    shared pool 1M buffer                     2098176
    shared pool KGLS heap                    33640016
    shared pool PX subheap                       3576
    shared pool parameters                    4685552
    shared pool free memory                 123632928
    shared pool gcs shadows                  25520520
    shared pool PL/SQL DIANA                  2365304
    shared pool ges enqueues                 75948192
    shared pool FileOpenBlock                 2307528
    shared pool PL/SQL MPCODE                37340952
    shared pool gcs resources                38410032
    shared pool ges resources                55793816
    shared pool library cache               258177064
    shared pool miscellaneous                94491288
    shared pool KCL name table                1434984
    shared pool MTTR advisory                  490648
    shared pool PLS non-lib hp                   3464
    shared pool joxs heap init                   1872
    shared pool sim memory hea                1945392
    shared pool table definiti                  54352
    shared pool temporary tabl                   5944
    shared pool trigger defini                  19432
    shared pool trigger inform                   3184
    shared pool trigger source                   5792
    shared pool dictionary cache              3229952
    shared pool ges big msg buffers           1739688
    shared pool KSXR receive buffers          1034000
    shared pool ges reserved msg buffers      1257608
    shared pool KSXR pending messages que      853952
    shared pool event statistics per sess     3770760
    shared pool fixed allocation callback         616
    large pool  free memory                 239622720
    large pool  session heap                 28812736
    java pool   free memory                  1677721644 rows selected.SQL> 
    SQL> rem ++++++++++++++++++++++++++++++++++++++++++++++++++++++
    SQL> rem  resource limit
    SQL> select * from v$resource_limit;RESOURCE_NAME                  CURRENT_UTILIZATION MAX_UTILIZATION INITIAL_ALLOCATION   LIMIT_VALUE
    ------------------------------ ------------------- --------------- -------------------- --------------------
    processes                                       19              26        300                  300
    sessions                                        85             131        335                  335
    enqueue_locks                                   22             107       4182                 4182
    enqueue_resources                               22              22       1692            UNLIMITED
    ges_procs                                       18              24        301                  301
    ges_ress                                     85137          199498       7022            UNLIMITED
    ges_locks                                    88609          203294      10566            UNLIMITED
    ges_cache_ress                                 918           38777          0            UNLIMITED
    ges_reg_msgs                                   104            1733        830            UNLIMITED
    ges_big_msgs                                    38             247        830            UNLIMITED
    ges_rsv_msgs                                     0               0        600                  600
    gcs_resources                               112209          129883     263037               263037
    gcs_shadows                                  18857           19139     263037               263037
    dml_locks                                        0              94       1472            UNLIMITED
    temporary_table_locks                            0               5  UNLIMITED            UNLIMITED
    transactions                                     0               5        368            UNLIMITED
    branches                                         0               0        368            UNLIMITED
    cmtcallbk                                        0               1        368            UNLIMITED
    sort_segment_locks                               0               2  UNLIMITED            UNLIMITED
    max_rollback_segments                           11              11         74                   74
    max_shared_servers                               1               1         20                   20
    parallel_max_servers                             0               1          6                    622 rows selected.大家看看有问题么?
      

  6.   

    oracle宣称可以保证任何时候都不丢失数据,在重启数据库后会自动进行实例恢复。
    况且我这是两台服务器,实际数据在共享阵列柜上,就算启动不了,还有另一个实例活着,可以立即备份数据。
      

  7.   

    chogo兄,
    4、出现问题时,nodeora其实还是有响应的,只是在等了两分钟后才给出(说明某项资源不够用)实际上如果我不按Ctrl+c,他是不会有响应的,一直等待。今天,我又把数据库服务器上的tnsnames.ora更改了下,把(SERVER=DEDICATED) 改成(SERVER=SHARED),
    在故障时,登录数据库服务器用Sqlplus system/manager@fmis1和Sqlplus system/manager@fmis2连接数据库,发现fmis2成功连接,但fmis1无法连接,一直等待。恰好实例fmis1所在的服务器这时的cpu占有率达到25%!应用服务器的tnsnames.ora中没有指定使用Shared或者Dedicated方式来连接数据库,但事实上,大多是用shared的方式,这点可以通过lsnrctl services来确认,代码如下:
    LSNRCTL for Solaris: Version 9.2.0.5.0 - Production on 29-DEC-2009 16:55:11Copyright (c) 1991, 2002, Oracle Corporation.  All rights reserved.Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=fmislssun1)(PORT=1521)))
    Services Summary...
    Service "FMIS.LSDYJ" has 2 instance(s).
      Instance "FMIS1", status READY, has 3 handler(s) for this service...
        Handler(s):
          "DEDICATED" established:0 refused:0 state:ready
             REMOTE SERVER
             (ADDRESS=(PROTOCOL=TCP)(HOST=fmislssun1)(PORT=1521))
          "DEDICATED" established:0 refused:0 state:ready
             LOCAL SERVER
          "D000" established:1272 refused:0 current:68 max:972 state:ready
             DISPATCHER <machine: fmislssun1, pid: 20737>
             (ADDRESS=(PROTOCOL=tcp)(HOST=fmislssun1)(PORT=37892))
      Instance "FMIS2", status READY, has 2 handler(s) for this service...
        Handler(s):
          "DEDICATED" established:0 refused:0 state:ready
             REMOTE SERVER
             (ADDRESS=(PROTOCOL=TCP)(HOST=fmislssun2)(PORT=1521))
          "D000" established:51 refused:0 current:9 max:972 state:ready
             DISPATCHER <machine: fmislssun2, pid: 14277>
             (ADDRESS=(PROTOCOL=tcp)(HOST=fmislssun2)(PORT=55146))
    Service "FMIS1" has 1 instance(s).
      Instance "FMIS1", status UNKNOWN, has 1 handler(s) for this service...
        Handler(s):
          "DEDICATED" established:8 refused:0
             LOCAL SERVER
    Service "PLSExtProc" has 1 instance(s).
      Instance "PLSExtProc", status UNKNOWN, has 1 handler(s) for this service...
        Handler(s):
          "DEDICATED" established:0 refused:0
             LOCAL SERVER
    The command completed successfully
    由此我在想,问题似乎出在两方面:
    一、rac没有正常工作,因为就算一个实例的共享服务器失去响应,还有另外的实例和专用服务器工作正常,但用户的连接去没有传递到另外的实例上去。
    二、执行大型查询任务时,接受该任务的共享服务器失去响应。大家看呢,如果是这两方面的原因,该如何解决?如果不是,还有其它什么原因?共享服务器相关实例参数如下:
    shared_server_sessions               integer     330
    shared_servers                       integer     1
    max_shared_servers                   integer     20
    dispatchers                          string      (PROTOCOL=TCP)
    max_dispatchers                      integer     5
    circuits                             integer     335
    processes                            integer     300
    sessions                             integer     335
      

  8.   


    crs_stat和srvctl一样,是crs里的命令,是我们对RAC环境进行管理的基本工具。
      

  9.   

    FMIS = 
      (DESCRIPTION = 
        (ADDRESS_LIST = 
          (ADDRESS = (PROTOCOL = TCP)(HOST = fmislssun1)(PORT = 1521)) 
          (ADDRESS = (PROTOCOL = TCP)(HOST = fmislssun2)(PORT = 1521)) 
          (LOAD_BALANCE = yes) 
        ) 
        (CONNECT_DATA = 
          (SERVICE_NAME = FMIS.LSDYJ) 
        ) 
      ) 似乎没有 failover 配置,试试这个FMIS =
      (DESCRIPTION =
        (ADDRESS_LIST =
          (ADDRESS = (PROTOCOL = TCP)(HOST = fmislssun1)(PORT = 1521))
          (ADDRESS = (PROTOCOL = TCP)(HOST = fmislssun2)(PORT = 1521))
          (SOURCE_ROUTE = off)
          (failover = on)
          (load_balance = on)
        )
        (CONNECT_DATA =
          (SERVICE_NAME = FMIS.LSDYJ)
          (failover_mode =
            (type = select)
            (method = basic)
            (backup = FMIS1)
            (backup = FMIS2)
          )
        )
      )
      

  10.   

    但如何进入crs,solaris里没有crs开头的命令,我切换到su - oracle用户也没有crsctl命令,群集是sun cluster3.1的
      

  11.   

    TO ruihuahan兄:
        你的方案我照做了,不过,没有效果。
        在应用服务器的Oracle客户端上,是有启用load_balance的,但没有启用failover。
    failover似乎是一个实例失败之后的由另一个实例来接管失败的会话,但oracle仅仅失去响应而不报错的现象似乎并不认为实例失败(貌似只认为是负载过重而排队等待)。
      

  12.   

    我好像已经找到问题根源了。今天下班我再次手动复现故障,然后查询了与共享服务器有关的视图,其中gv$queue视图结果如下:
    SQL> select * from gv$queue;INST_ID PADDR            TYPE       QUEUED WAIT TOTALQ
    ------- ---------------- ---------- ------ ---- ------
          2 00               COMMON          0    0 30083
          2 000000040F4852D8 DISPATCHER      0    0 30505
          1 00               COMMON         15    0 10788
          1 000000040F4852D8 DISPATCHER      0    0 10924
    发现queued列有一个值为15,按照Oracle的解释,理想情况不应该存在排队!
    common队列存在排队,说明没有足够的共享服务器进程被用于清空队列,而恰好oracle的参数shared_servers值为 1。
        于是我把shared_servers的值改为3,重启数据库后再运行大型查询,这是队列仍然为空,故障没有出现!    问题好像解决了,不过我又想到新的问题:
    1. 实例参数max_shared_servers的值为20,那么在共享服务器进程不够用的时候,oracle为什么不启动新的进程而在原有的唯一的共享服务器进程上排队?
    2. 我启动了三个共享服务器进程才让排除没有发生,但如果这时同时有3个或者更多的人在运行这样的大查询,那么三个服务器可能也不够,那时故障将再次发生!
    3. 我重新修改了所有应用服务器上的tnsnames.ora,保证所有连接都启用了load_balance和failover,但出故障的时候,为什么没有一个客户连接会连接到空闲的实例上(正常的时候)?不管怎样,共享服务器上的问题已经找到原因了,如果还有问题,大不了再增加共享服务器的数量,或者直接使用专用服务器!感谢达人们的帮忙!先给分!以后有关这问题的新发现,我再贴上来