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的进程分为三大类
      • 用户进程:客户端用于连接数据库的程序
      • 服务器进程:服务器端响应用户操作请求的程序
      • 后台进程:维护DB Server正常运行以及一些特定功能所需要的进程,随着实例启动而启动
    • oracle的用户进程就是客户端连接数据库的程序
    • 当客户端程序发出连接请求,用户进程启动,当断开连接,用户进程释放
    • 服务器进程就是服务器端响应用户操作请求的进程,同用户进程一样,连接开始,服务器进程分配,连接断开,服务器进程释放
    • 后台进程用于执行DB SERVER中特定的任务,根据进程的功能,后台进程被分为必要的和可选两种
      • 必要的后台进程是系统运行必须的,有五种
        • DBWn数据写进程
        • PMON进程监视器
        • CKPT检查点
        • LGWR日志写进程
        • SMON系统监视器
      • 可选的后台进程更多一些,主要被用于实现或增强某方面的特殊功能

     

    如何查看后台进程

    [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\';

 

 

  1. DBWN,LGWR,CKPT进程
  2. SMONPMON进程
  3. 可选后台进程:归档日志进程ARCH/ARCN

 

1DBWN,LGWR,CKPT进程

DBWN

DBWN数据库写的条件

  • 发声检查点
  • 脏缓存到达限制
  • 没有自由的缓存
  • 超时发生
  • RAC Ping请求
  • 表空间离线
  • 表空间只读
  • 表被删除或截断
  • 开始备份表空间

 

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写的条件

  • 提交的时候
  • 达到三分之一满
  • 日志的大小到1M
  • 每隔三秒
  • DBWn进程写之前
  • 按照顺序循环写
  • 一般情况下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,SMONPMON进程

系统监控进程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后台进程:

  • DBWR会将data buffer cache中已提交标识的数据写入到数据文件data file物理磁盘中去。也就是说,在data buffer cache中标记已提交的数据会通过DBWR后台进行写入到数据文件中去。
  • 但是,redo log buffer是记录所有块更改的信息的,如果redo log buffer没有把块更改的变化信息记录下来,DBWR是不会将提交的数据写入到数据文件中去。
  • 也就是说,当data buffer cache中的更改的数据标记了提交,并且redo log buffer将更改的信息记录下来后,DBWR才会将提交了得数据写入到数据文件中。

DBWn(Database Writer Process)

  • n是指ORACLE可以启动多个Database Writer Process
  • 内存中有很多脏数据,有很多数据在修改,一个Database Writer Process不够用,就会启多个Database Writer Process
  • DBWn是数据库后台写入进程,负责把buffer cache内的脏数据(当buffer cache被修改了,就会标成脏数据)写入数据库.DBWn的主要工作是把脏数据写入磁盘以保证buffer cache是干净的.
  • 用户进程会产生脏数据,空余的缓冲区会减少.如果空闲的缓冲区太少,用户进程从磁盘读取block进缓冲区的时候就找不到空余的位置了.DBWn管理buffer cache保证用户进程始终可以找到空闲的位置.

 

在什么触发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.)
  • 完后会更新DATAFILEHEADER和控制文件的HEADER.HEADER中有同步所需要的信息,CHECKPOINT的信息.
  • ORACLE,正常情况下,所有文件必须同期性地同步;CHECKPOINT来完成.

 

 

 

 

SMON系统监控进程:资源的维护和管理,索引合并等

SMON(System Monitor Process)

SMON是Oracle数据库至关重要的一个后台进程,SMONSystem Monitor 的缩写,意即:系统监控。

作用:

  • 实例恢复
    • 前滚Rolls forward changes in redo logs
    • Opens database for user access
    • 回滚Rolls back uncommitted transactions
  • 回收空间Coalesces free space
  • 释放临时表Deallocates temporary segments

 

 

 

PMON进程监控进程:进程之间的监控和维护