首先从操作系统的监控看看性能如何:iostat vmstat top
看下cpu的使用率,io等待如何,发现系统的idle不到10%,这说明系统十分的繁忙。查了一下系统的会话
SELECT SID, SERIAL#, USERNAME, EVENT, SECONDS_IN_WAIT FROM V$SESSION WHERE LOGON_TIME < SYSDATE - 5 AND USERNAME != 'SYS'
系统中存在很多登陆时间超过5条的会话,这对于当前系统而言,可能性不大,且观察SECONDS_IN_WAIT列的等待时间,显然这些会话的状态并不正常。虽然SQL*Net message from client是空闲状态,但是如果出现了网络闪断,会话也可能处于这种状态,且会一直占用大量的CPU资源,而当前就是这种症状。
在操作系统中找到这些长时间等待的进程,确认这些进程不属于Oracle的后台进行,将这些进程用kill -9命令结束掉
SQL> SELECT SPID FROM V$PROCESS
2 WHERE ADDR IN (SELECT PADDR FROM V$SESSION WHERE SID IN (81, 97, 103, 134, 140, 158, 237, 246, 253, 267, 287, 320, 338, 479));
显然,杀掉了长时间运行的会话后,系统的idle从原来的不到10%,上升到20%以上,说明系统的压力有了缓解,等待一段时间后,idle的值进一步上升。
这时在检查刚才运行超过50秒的SQL,这次发现SQL运行时间不到0.1秒,看来刚才的SQL本身没有什么问题,只不过刚才整个系统都处于极度繁忙的状态,SQL运行所需要的资源、LATCH、锁等都被占用,因此出现了长时间的等待。这从片面也说明一个问题,系统的网络肯定是发生过闪断,导致了大量的会话处于等待的状态,消耗的大量的系统资源,直至系统资源被耗尽。
解决这个问题后,系统的压力开始慢慢降低,但是观察发现,虽然现在数据库中的会话并不多,但是数据库并没有处于比较空闲的状态。这说明系统还存在其他的问题。
检查数据库的alert文件时,发现一个问题。
首先,日志切换过于频繁:
可以看到,在系统忙时,每2、3分钟就需要切换一次redo文件,检查数据库中redo的配置:
SQL> SELECT * FROM V$LOG;
每个日志文件才分配了50M,难怪系统频繁的切换日志。怀疑安装数据库的时候采用了缺省的配置。 既然日志文件大小缺省配置,不会系统中的内存参数也是缺省配置大小吧,检查数据库中SGA配置: SQL> show sga
SGA分配8G,PGA分配1G,操作系统有32G内存,这个分配显然不合理。
进一步检查系统的内存分配情况:
SQL> show parameter cache
用户仅指定了6G的内存给SGA,Oracle在自动分配的时候还将大部分给了共享池,只给了DB_CACHE不到3G的空间,难怪系统性能很差。
调整了SGA以及redo文件的大小,并重启数据库后,性能问题解决。