[AD]内存管理

一,Oracle 的内存分配和使用
1,Oracle规划内存使用时,我们必须清楚,如果Oracle耗用的内存过高,甚至超过了物理内存,那么系统的性能就会受到严重的影响,当系统执行任务时,如果没有足够的内存,那么系统就会进行分页或交换,以完成当前活动事务。当系统执行分页时,会将当前没有使用的信息从内存中转业到磁盘上,这样就可以为当前需要内存的程序分配内存。如果频繁发生分页,系统性能就会严重降低,从而导致很多程序的执行时间变长。
2,当系统执行交换时,会将某些进程所分配的不活跃内存页(根据LRU算法)从内存转移到硬盘上,这样另一个活动进程就可以得到所需要的内存。交换基于系统循环时间。如果交换太过频繁,系统甚至会出现当机。
二,案例一
用户报告,服务器启动一段时间以后,无法建立数据库连接。重新启动接分钟以后,再次无法连接。
1,登录数据库,检查系统进程
登录系统,检查系统进程,发现后台进程正常,有一定量的用户连接。
[root@rhel ~]# ps -ef | gre ora
2,检查告警日志
发现如下大量提示信息
skgspawn failed:category = 27142,depinfo = 12,op=fork,loc= skgpspaw3
该提示说明系统无法fork新的数据库进程,数据库无法spawn a new session。而且这里skgspawn failed:category = 2714,实际上应该是Oracle的错误号,可以通过Oracle的手册查询这个错误的具体内 容。
[oracle@rhel ~]$ oerr ora 27142
27142, 0000, "could not create new process"
// *Cause:  OS system call
// *Action: check errno and if possible increase the number of processes
[oracle@rhel ~]$
3,尝试连接数据库
当再次尝试连接数据库时,收到如下信息,无法连接数据库:
ORA-12540:TNS超出内部限制
内部限制超过,通常说明某些系统资源不足。
4,检查系统日志
检查系统日志信息,发现大量的失败的su操作,有swap区不足的报告:wapplatform su:[ID 810491 auth.crit]'su oracle'failed for root on /dev/pts/6
5,检查系统内存及交换区使用
通过TOP工具检查系统内存及swap使用情况:发现物理内存仅为1GB,Free部分为34M,交换区使用了752M,仅Swap Free部分仅余10M。由此可见,系统内存严重不足,Swap区不足。
6,检查数据库的SGA设置
发现SGA设置为600M,这个设置过高。对于RAM小于1GB的系统,Dedicated模式下,通常建议Oracle的SGA一般不应超过1/2物理内存,SGA之外还应考虑到PGA和操作系统的内存的分配。
7,调整内容
第一步:减少SGA,为系统保留足够的内存。
第二步:为系统增加Swap区。
8,如果物理内存(RAM)很大,不一定非要把Swap设置为2*Swap,通常可以设置Swap=RAM或者小于物理内存(如内存超过了32GB则完全可以设置Swap为16GB)。如果物理内存(RAM)过小,在系统繁忙期间,产生大量交换无法换到磁盘,就会出现问题。如果系统物理内存较小,通常设置SGA<1/2RAM,要考虑为Server process的PGA消耗及OS保留足够的内存 空间。
三,案例二
SGA设置过高导致的系统故障,大型生产系统,问题出现时系统累计大量用户进程,用户请求得不到即使相应,新的进程不断尝试建立连接,连接数很快被用完。最后系统处于挂起状态,无法进行服务响应。
1,登录系统,查看报警日志
日志中出现如下错误;
WARNING:aiowait timed out 2 times
注意到每次WARNING的时间间隔为10分钟。
我们知道在SUN的某些版本上IO存在问题,而异步IO缺省是打开的:
SQL> show parameter disk_a
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
disk_asynch_io                       boolean     TRUE
SQL>
针对此问题,暂时停用了数据库的异步IO写入。
2,检查共享内存设置
alert文件中还记录了一下告警信息;
WARNING:EINVAL.creating segment of size 0x000000019040000
fix shm parameters in /etc/system or equivalent
该信息说明系统内核参数设置不合理或者和SGA不匹配,检查system配置文件:
cat /etc/system
set shmsys:shminfo_shammax=4096000000
发现最大共享内存段设置为了4GB
3,检查SGA设置
SQL>show sga
发现SGA设置接近7GB(超过了4GB,oracle将分配多个共享内存段),这也就是步骤中的警告提示出现的

原因。
4,交换分区问题
用top命令检查系统运行状况:
发现在Top输出中,使用了12GB的swap,而物理内存几乎耗尽。初步判断:由于SGA设置过大(接近7GB)导致运行时产生大量交换,大量swap交换进而引发磁盘I/O问题,这也就是步骤1中看到异步I/O的错误原因。大量的交换导致数据库性能急剧下降,进而导致用户请求得不到快速响应,堵塞、累积直至数据库失去响应。
5,解决方案
此问题主要是由于SGA设置不当引起,马上缩小了SGA设置。
6,发现
后来发现,这个问题在oracle 9.2.0.3的solaris平台上广泛存在,oracle为记录bug(Bug NO:20886687 )并作了改进。在oracle 9.2.0.3版本中,缺省情况下oracle在异步I/O出现问题时,会连续WARNING100次,每次间隔10分钟,也就是1000分钟之后会给出的ORA-27083错误。
[oracle@rhel ~]$ oerr ora 27083
27083, 00000, "waiting for async I/Os failed"
// *Cause:  The aio_waitn() library call returned an error.
// *Action: Check errno.
[oracle@rhel ~]$
这一设置让很多的用户很不满,因为连续100次的I/O超时可能已经给系统带来了严重的影响,所以在 oracle9.2.0.4版本中,oracle引入了一个新的隐含参数用以控制在报告中ORA-27083错误前的WARNING的 次数。这个参数就是_aiowait_timeouts,这参数的缺省值为100;
SQL> @GetParDescrb.sql
Enter value for par: aiowait
old   3:  WHERE x.indx = y.indx AND x.ksppinm LIKE '%&par%'
new   3:  WHERE x.indx = y.indx AND x.ksppinm LIKE '%aiowait%'
NAME                           VALUE                DESCRIB
------------------------------ --------------------

------------------------------------------------------------
_aiowait_timeouts              100                  Number of aiowait timeouts before error

is reported

SQL>
四,案例三
寻找一个消耗CPU的sql
SQL> SELECT /*+ORDERED*/
  2  sql_text
  3  FROM v$sqltext a
  4  WHERE (a.hash_value,a.address) IN (
  5  SELECT DECODE(sql_hash_value,
  6  0,prev_hash_value,
  7  sql_hash_value
  8  ),
  9  DECODE(sql_hash_value,
 10  0,prev_sql_addr,
 11  sql_address
 12  )
 13  FROM v$session b
 14  WHERE b.paddr=(SELECT addr
 15  FROM v$process c
 16  WHERE c.spid='&pid'))
 17  ORDER BY piece ASC
 18  /
Enter value for pid: 3397
old  16: WHERE c.spid='&pid'))
new  16: WHERE c.spid='3397'))

SQL_TEXT
----------------------------------------------------------------
select * from tianmao.season1

SQL>

首先需要输入一个PID,这个PID即processID,也就是Top或ps中看到的PID。通过PID和v$process.spid相 关联,可以获得Process相关信息,进而通过v$process.addr和v$process.spid相关联,可以获得Process 的相关信息。再结合v$sqltext,就可以获得当前session正在执行的SQL语句。通过这个v$process视图, 我们得以把操作系统和数据库关联起来。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/29611940/viewspace-1145294/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/29611940/viewspace-1145294/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值