oracle 进程 sleeping正常吗
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了oracle 进程 sleeping正常吗相关的知识,希望对你有一定的参考价值。
首先登陆主机,执行top发现CPU资源几乎消耗殆尽,存在很多占用CPU很高的进程,而内存和I/O都不高,具体如下:last pid: 26136; load averages: 8.89, 8.91, 8.12
216 processes: 204 sleeping, 8 running, 4 on cpu
CPU states: 0.6% idle, 97.3% user, 1.8% kernel, 0.2% iowait, 0.0% swap
Memory: 8192M real, 1166M free, 14M swap in use, 8179M swap free
PID USERNAME THR PRI NICE SIZE RES STATE TIME CPU COMMAND
25725 oracle 1 50 0 4550M 4508M cpu2 12:23 11.23% oracle
25774 oracle 1 41 0 4550M 4508M run 14:25 10.66% oracle
26016 oracle 1 31 0 4550M 4508M run 5:41 10.37% oracle
26010 oracle 1 41 0 4550M 4508M run 4:40 9.81% oracle
26014 oracle 1 51 0 4550M 4506M cpu6 4:19 9.76% oracle
25873 oracle 1 41 0 4550M 4508M run 12:10 9.45% oracle
25723 oracle 1 50 0 4550M 4508M run 15:09 9.40% oracle
26121 oracle 1 41 0 4550M 4506M cpu0 1:13 9.28% oracle
25745 oracle 1 41 0 4551M 4512M run 9:33 9.28% oracle
26136 oracle 1 41 0 4550M 4506M run 0:06 5.61% oracle
409 root 15 59 0 7168K 7008K sleep 173.1H 0.52% picld
25653 oracle 1 59 0 4550M 4508M sleep 1:01 0.46% oracle
25565 oracle 1 59 0 4550M 4508M sleep 0:07 0.24% oracle
25703 oracle 1 59 0 4550M 4506M sleep 0:08 0.13% oracle
25701 oracle 1 59 0 4550M 4509M sleep 0:23 0.10% oracle
于是先查看数据库的告警日志ALERT文件,并没有发现有什么错误存在,日志显示数据库运行正常,排除数据库本身存在问题。
然后查看这些占用CPU资源很高的Oracle进程究竟是在做什么操作,使用如下SQL语句:
select sql_text,spid,v$session.program,process from
v$sqlarea,v$session,v$process
where v$sqlarea.address=v$session.sql_address
and v$sqlarea.hash_value=v$session.sql_hash_value
and v$session.paddr=v$process.addr
and v$process.spid in (PID);
用top中占用CPU很高的进程的PID替换脚本中的PID,得到相应的Oracle进程所执行的SQL语句,发现占用CPU资源很高的进程都是执行同一个SQL语句:
SELECT d.domainname,d.mswitchdomainid, a.SERVICEID,a.SERVICECODE,a.USERTYPE,a.STATUS,a.NOTIFYSTATUS,to_char(a.DATECREATED,'yyyy-mm-dd hh24:mi:ss') DATECREATED,VIPFLAG,STATUS2,CUSTOMERTYPE,CUSTOMERID FROM service a, gatewayloc b, subbureaunumber c, mswitchdomain d WHERE b.mswitchdomainid = d.mswitchdomainid and b.gatewaysn = c.gatewaysn AND a.ServiceCode like c.code||'%' and a.serviceSpecID=1 and a.status!='4' and a.status!='10' and a.servicecode like '010987654321%' and SubsidiaryID=999999999
基本上可以肯定是这个SQL引起了系统CPU资源大量被占用,那究竟是什么原因造成这个SQL这么大量占用CPU资源呢,我们先来看看数据库的进程等待事件都有些什么:
SQL> select sid,event,p1,p1text from v$session_wait;
SID EVENT P1 P1TEXT
---------- ----------------------------------------------------------------
12 latch free 4.3982E+12 address
36 latch free 4.3982E+12 address
37 latch free 4.3982E+12 address
84 latch free 4.3982E+12 address
102 latch free 4.3982E+12 address
101 latch free 4.3982E+12 address
85 latch free 4.3982E+12 address
41 latch free 4.3982E+12 address
106 latch free 4.3982E+12 address
155 latch free 4.3982E+12 address
151 latch free 4.3982E+12 address
149 latch free 4.3982E+12 address
147 latch free 4.3982E+12 address
1 pmon timer 300 duration
从上面的查询我们可以看出,大都是latch free的等待事件,然后接着查一下这些latch的等待都是什么进程产生的:
SQL> select spid from v$process where addr in
(select paddr from v$session where sid in(84,102,101,106,155,151));
SPID
------------
25774
26010
25873
25725
26014
26016
由此看出latch free这个等待事件导致了上面的那个SQL语句都在等待,占用了大量的CPU资源。我们来看看究竟主要是那种类型的latch的等待,根据下面的SQL语句:
SQL> SELECT latch#, name, gets, misses, sleeps
FROM v$latch
WHERE sleeps>0
ORDER BY sleeps;
LATCH# NAME GETS MISSES SLEEPS
---------- ----------------------------------------------------------------
15 messages 96876 20 1
159 library cache pin allocation 407322 43 1
132 dml lock allocation 194533 213 2
4 session allocation 304897 48 3
115 redo allocation 238031 286 4
17 enqueue hash chains 277510 85 5
7 session idle bit 2727264 314 16
158 library cache pin 3881788 5586 58
156 shared pool 2771629 6184 662
157 library cache 5637573 25246 801
98 cache buffers chains 1722750424 758400 109837
由上面的查询可以看出最主要的latch等待是cache buffers chains,这个latch的等待表明数据库存在单独的BLOCK的竞争这些latch,我们来看这个latch存在的子latch及其对应的类型:
SQL> SELECT addr, latch#, gets, misses, sleeps
FROM v$latch_children
WHERE sleeps>0
and latch# = 98
ORDER BY sleeps desc;
ADDR LATCH# GETS MISSES SLEEPS
---------------- ---------- ---------- ---------- ----------
000004000A3DFD10 98 10840661 82891 389
000004000A698C70 98 159510 2 244
0000040009B21738 98 104269771 34926 209
0000040009B227A8 98 107604659 35697 185
000004000A3E0D70 98 5447601 18922 156
000004000A6C2BD0 98 853375 7 134
0000040009B24888 98 85538409 25752 106
000004000A36B250 98 1083351 199 96
000004000A79EC70 98 257970 64 35
000004000A356AD0 98 1184810 160 34
……………
接着我们来查看sleep较多的子latch对应都有哪些对象:
SQL> select distinct a.owner,a.segment_name,a.segment_type from
dba_extents a,
(select dbarfil,dbablk
from x$bh
where hladdr in
(select addr
from (select addr
from v$latch_children
order by sleeps desc)
where rownum < 5)) b
where a.RELATIVE_FNO = b.dbarfil
and a.BLOCK_ID <= b.dbablk and a.block_id + a.blocks > b.dbablk;
OWNER SEGMENT_NAME SEGMENT_TYPE
---------------------------------------------------------------------------
TEST I_SERVICE_SERVICESPECID INDEX
TEST I_SERVICE_SUBSIDIARYID INDEX
TEST SERVICE TABLE
TEST MSWITCHDOMAIN TABLE
TEST I_SERVICE_SC_S INDEX
TEST PK_MSWITCHDOMAIN INDEX
TEST GATEWAYLOC TABLE
…………………
我们看到在开始的那个SQL语句中的几个对象都有包括在内,于是来看看开始的那个SQL的执行计划:
SQL> set autotrace trace explain
SQL>SELECT d.domainname,d.mswitchdomainid, a.SERVICEID,a.SERVICECODE,a.USERTYPE,a.STATUS,a.NOTIFYSTATUS,to_char(a.DATECREATED,'yyyy-mm-dd hh24:mi:ss') DATECREATED,VIPFLAG,STATUS2,CUSTOMERTYPE,CUSTOMERID FROM service a, gatewayloc b, subbureaunumber c, mswitchdomain d WHERE b.mswitchdomainid = d.mswitchdomainid and b.gatewaysn = c.gatewaysn AND a.ServiceCode like c.code||'%' and a.serviceSpecID=1 and a.status!='4' and a.status!='10' and a.servicecode like '010987654321%' and SubsidiaryID=999999999;
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT ptimizer=CHOOSE
1 0 NESTED LOOPS
2 1 NESTED LOOPS
3 2 NESTED LOOPS
4 3 TABLE ACCESS (FULL) OF 'SUBBUREAUNUMBER'
5 3 TABLE ACCESS (BY INDEX ROWID) OF 'GATEWAYLOC' 参考技术A dbms_lock.sleep(10);正常线程休眠10毫秒。
ORACLE后台进程
我们在内存中做操作,但是内存中所做的操作应该及时写到磁盘去,所以怎么保证内存的操作写入磁盘呢?
后台进程介绍
如何查看后台进程 [oracle@WHOST ~]$ ps -ef|grep gaga01 oracle 2704 1 0 17:46 ? 00:00:00 ora_pmon_gaga01 oracle 2706 1 0 17:46 ? 00:00:00 ora_psp0_gaga01 查看5个重要的后台进程 [oracle@WHOST ~]$ ps -ef|grep gaga01|egrep "pmon|smon|dbw0|lgwr|ckpt" oracle 2704 1 0 17:46 ? 00:00:00 ora_pmon_gaga01 [oracle@WHOST ~]$ grep和egrep的用法参考如下博客: http://www.cnblogs.com/tsw1107/p/2264a01aeec481d2044dfeda01417c64.html
在数据字典中查找后台进程 SQL> desc v$bgprocess
正在使用的后台进程查找: SQL> SELECT name,description FROM v$bgprocess WHERE paddr<>\'00\'; |
- DBWN,LGWR,CKPT进程
- SMON,PMON进程
- 可选后台进程:归档日志进程ARCH/ARCN
1、DBWN,LGWR,CKPT进程
DBWN | DBWN数据库写的条件
32bit--->dbw0---dbw9(最多可以跑10个) 64bit--->dbw0---dbw9,dbwa-dbwj(最多可以跑20个) 具体跑多少个,由参数db_writer_processes决定 如果设置db_writer_processes修改为22个,但是最终还是最多能开20个 SQL> show parameter db_w
NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ db_writer_processes integer 8
SQL> alter system set db_writer_processes=20 scope=spfile;
System altered.
SQL> show parameter db_w
NAME TYPE VALUE ------------------------------------ ----------- ---------------------- -------- db_writer_processes integer 8
SQL> startup force ORACLE instance started.
Total System Global Area 1653518336 bytes Fixed Size 2253784 bytes Variable Size 1073744936 bytes Database Buffers 570425344 bytes Redo Buffers 7094272 bytes Database mounted. Database opened. SQL> show parameter db_w
NAME TYPE VALUE ------------------------------------ ----------- ---------------------- -------- db_writer_processes integer 20
SQL> select count(name) from v$bgprocess where paddr<>\'00\' and name like\'DBW%\';
COUNT(NAME) ----------- 20
SQL> select name from v$bgprocess where paddr<>\'00\';
NAME ----- DBW0 …. DBW9 DBWa ….. DBWj |
LGWR | LGWR写的条件
Log buffer-->lgwr--logfile |
CKPT | CKPT是触发检查点
他是保证数据库里面的数据库文件、控制文件、日志文件中的三大要素实现同步的特殊进程,必须正常.
作用:
给信号给DBWN:给dbwn发信号,要求dbwn写数据,把数据缓冲区中脏数据通过DBWN写入数据文件. 更新数据文件头:把数据文件头的SN号更新 更新控制文件信息,如版本号.
这个时候控制文件、日志文件、数据文件就完全记录数据库里面的状态和数据,保证不会丢,他们的状态是一致性的.
CKPT触发DBWN,DBWN触发会要求LGWR写日志,保证内存中的数据全部写入全部的数据文件、控制文件、日志文件中.
CKPT中最重要的是:SCN系统变更号,system change number,SCN是标志数据库一致性判断的依据,只有SCN号相同,这些文件才一致性.
CKPT中所对应的文件,LGWR所对应的文件都不要有问题 |
2,SMON,PMON进程
系统监控进程SMON | 系统监控进程SMON(重要)
Coalesce every three seconds
Dellocated |
进程监控进程PMON | 清除失败的进程: 回滚事务rollback 释放锁 释放其他资源 重启死调的dispatchers 动态注册监听器 |
3,可选后台进程:归档日志进程ARCH/ARCN
归档日志进程ARCH/ARCN
归档日志进程可能是最重要的一个可选后台进程,因为如果oracle数据库的数据文件丢失或损坏,一般数据库要进行完全恢复,oracle数据库应运行在归档方式.
在oracle数据库中,重做日志文件被划分为若干个组,当一个组重做日志的文件被写满后,oracle就开始写下一组重做日志,这杯称为日志切换. 切换是以循环的方式进行的,即当最后一组写满后,又开始写第一组,因此如果只有重做日志文件,即oracle数据库运行在非归档方式下,当遇到数据文件丢失或损坏时,oracle系统很难保证完全恢复数据库中的数据,因为此时所需的重做记录可能因重做日志循环使用而被覆盖掉了.
在归档方式下,ARCn进程把切换后的重做日志文件复制到归档日志文件,可以把归档日志文件堪称是重做日志文件的备份,但归档日志文件是脱机的,即除了在进行复制时,oracle数据库在正常运行时是不会关注归档日志文件的,oracle系统确保一组重做日志文件的归档操作完成之前不会重新使用该组做日志,在oracle数据库中归档操作一般是自动进行的,利用这些归档日志文件,oracle系统就能确保在遇到数据文件丢失或损坏后可以完全恢复数据库中的数据.
Ho ps -ef|grep gaga01|grep arc
Select log_mode from v$database; archive log list;
切日志: Alter system switch logfile 日志切完后就会归档
查看归档到什么地方呢? Show parameter db_rec; SQL> show parameter db_rec;
NAME TYPE V ALUE ------------------------------------ ----------- - ----------------------------- db_recovery_file_dest string / u01/app/oracle/fast_recovery_ a rea db_recovery_file_dest_size big integer 4 182M db_recycle_cache_size big integer 0
/u01/app/oracle/fast_recovery_area/GAGA01/archivelog/2017_07_11
SQL> ho ls /u01/app/oracle/fast_recovery_area/GAGA01/archivelog/2017_07_11 o1_mf_1_43_dp7klx7w_.arc
归档进程有多少个,由于show parameter log_archive_max_processes参数来决定,这个参数最多可设置到30个 |
我们在内存中做操作,但是内存中所做的操作应该及时写到磁盘去,所以怎么保证内存的操作写入磁盘呢?
以下说明了后台进程的作用:
比如DBWR后台进程:
DBWn(Database Writer Process)
在什么触发DBWR进程的条件: 1.当脏缓冲区的数量超过了所设定的限额。 2.当所设定的时间间隔到了。 3.当有进程需要数据库高速缓冲区却找不到空闲的缓冲区时。当server process在buffer cache中无法找到可用的buffer时,调用该进程,保证用户进程始终可以在buffer cache中找到空闲的位置; 4.当校验点发生时。 接收到CKPT(检查点,checkpoint)进程的指令后,调用该进程,将数据写入到磁盘中。 5.当某个表被删除或被截断时。 6.当某个表空间被设置为只读状态时。 7.当使用类似于alter tablespace users begin backup的命令对某个表空间进行联机备份时。 8.当某个临时表空间被设置为只脱机状态或正常状态时。 |
为了保证redo log buffer内存中越来越大,所以需要将内存中的log写入磁盘中,释放内存空间。
LGWR(Log Writer Process) LGWR进程在启动实例时启动
LGWR是把log_buffer中的日志条目(ORACLE把客户提交的SQL语句转换成ORACLE能够识别、通过它可以重构数据的一种日志格式)写入到日志文件中.
LGWR保存日志条目,迅速释放log_buffer空间,只要该日志条目写入到日志文件,所占的内存空间就释放.所以log_buffer的功能就是临时的存放日志条目,循环的使用,如果log_buffer满了,就无法接受新的事务,就会发生实例挂起现象.
LGWR的作用: 将日志缓存区的数据从内存写到磁盘的redo文件里,完成数据库对象创建、更新等操作过程中的记录。
LGWR进程: LGWR是将redo log buffer中的日志写入到物理磁盘的redo log files里面。 内存中的日志会定时写入磁盘redo log files中。这些日志记录的作用是为了恢复。 |
这么多进程在写,那么如何保证进程之间协调工作呢?CKPT
- CheckPoint Process(CKPT) 保证数据同步。
只有触发CKPT后,才会触发DBWR写相关数据,DBWR被触发时LGWR也会触发。
所以这个时候,CKPT触发时,LGWR就会写日志,日志写完后DBWR就会写数据。
什么时候会触发CKPT呢?
- 人为执行commit操作
- 系统定时执行了一些操作
检查点,把内存中的数据写到磁盘上
- 会启动DBWn来写脏数据(SIGNALLING DBWn at CKPT.)
- 完后会更新DATAFILE的HEADER和控制文件的HEADER.而HEADER中有同步所需要的信息,即CHECKPOINT的信息.
- 在ORACLE中,正常情况下,所有文件必须同期性地同步;靠CHECKPOINT来完成.
SMON系统监控进程:资源的维护和管理,索引合并等
SMON(System Monitor Process)
SMON是Oracle数据库至关重要的一个后台进程,SMON 是System Monitor 的缩写,意即:系统监控。
作用:
- 实例恢复
- 前滚Rolls forward changes in redo logs
- Opens database for user access
- 回滚Rolls back uncommitted transactions
- 回收空间Coalesces free space
- 释放临时表Deallocates temporary segments
PMON进程监控进程:进程之间的监控和维护
- Process Monitor Process(PMON)
- 回滚事务
- 释放锁及其它资源
- 重启死掉的调度器.(在共享服务器中用mssql 怎么杀掉 sleeping