数据库服务器
系统: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才出现的提示?那么这个错误会不会是一种误导?
那么还能有什么原因?
各位帅哥们,帮忙分析一下啊!不胜感激
系统: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才出现的提示?那么这个错误会不会是一种误导?
那么还能有什么原因?
各位帅哥们,帮忙分析一下啊!不胜感激
解决方案 »
- 拆分字段
- SQL语句求优化
- Oracle里not in 有关null处理的奇怪问题,欢迎大家来讨论。
- 企业版Oracle 10g安装以后,还需要配置那些参数,才能更好的运行
- 请教绝对高手,TO_DATE的问题,急!
- OTL编译错误,求救
- 建表、过程、触发器的问题
- 请问:oracle中用PLSQL对应字段问题
- 夜里11:30,小软件公司的两个合伙人的谈话,用心的,现实思考中国软件
- oracle 客户端没有sqlldr 怎么添加
- 接触rman,基础问题请教各位:使用rman工作,必须另外建立一个数据库吗?
- java连接oracle报异常,Io 异常: Got minus one from a read call
1、问题出现时,分别登录node1和node2都是正常的,只有通过nodeora连接数据库时有问题
2、问题出现时,重启一台数据库基本上可以解决问题
3、出现问题的时候在执行大事务查询
4、出现问题时,nodeora其实还是有响应的,只是在等了两分钟后才给出(说明某项资源不够用)所以我觉得问题可能在内存分配上,能不能看一下相关的几块内存在这个时候都是什么情况的?
请教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
出故障时,我运行了一个数据库检测脚本,部分内容如下:
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.大家看看有问题么?
况且我这是两台服务器,实际数据在共享阵列柜上,就算启动不了,还有另一个实例活着,可以立即备份数据。
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
crs_stat和srvctl一样,是crs里的命令,是我们对RAC环境进行管理的基本工具。
(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)
)
)
)
你的方案我照做了,不过,没有效果。
在应用服务器的Oracle客户端上,是有启用load_balance的,但没有启用failover。
failover似乎是一个实例失败之后的由另一个实例来接管失败的会话,但oracle仅仅失去响应而不报错的现象似乎并不认为实例失败(貌似只认为是负载过重而排队等待)。
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,但出故障的时候,为什么没有一个客户连接会连接到空闲的实例上(正常的时候)?不管怎样,共享服务器上的问题已经找到原因了,如果还有问题,大不了再增加共享服务器的数量,或者直接使用专用服务器!感谢达人们的帮忙!先给分!以后有关这问题的新发现,我再贴上来