深入解析oracle中的后台进程、实例

深入解析oracle中的后台进程、实例

. Oracle 的后台进程

在本章开篇已经ᨀ到:Oracle 的实例(Instance)是指一组后台进程(在 Windows 上是一组

线程)和一块共享内存区域。图 1-2 即为 Oracle 数据库的实例概要图,可以看到实例的内存区

域 SGA 和一系列的后台进程示意(详细介绍将在后面章节逐步展开):

图 1-0-2 Oracle 实例示意图

《深入解析 Oracle》

·8·

通过上一节ᨀ到的日志信息,可以清晰的看到后台进程启动的过程,这里对于数据库运

行最为至关重要的进程主要有:PMON、DBWn、LGWR、CKPT、SMON、VKTM 等。如果

这些进程出现异常终止,则数据库将会崩溃。

下面简要介绍一些这些进程的作用。

PMON – 其全名为 Process Monitor – 进程监控进程,用于监控其他用户进程,当出现用

户进程失败时,执行进程恢复工作。PMON 的主要恢复职责在于释放失败进程未能正常释放

的内存锁和其他资源,如清理事务表状态等。

作为实例第一个启动的后台进程,PMON 还肩负监控其他 Oracle 后台进程的职责,在必

要时重启这些后台进程;此外,PMON 还负责向 TNS 监听器注册实例。

DBWn – 其全名为 DataBase Writer Process – 数据库写进程,有时也被写作 DBWR 进程,

该进程负责将内存中变更的数据写入磁盘数据文件。由于可以存在多个进程,所以增加 n 作

为后缀,虽然大多数情况下一个数据库写进程(DBW0)就足䭧了,但是 Oracle 允许配置最多

20 个写进程,名称为:DBW0~DBW9,DBWa~DBWj。对于多处理器的系统,多个 DBWR 进

程可以ᨀ升写性能。

DBWn 进程在满足以下条件时执行脏数据(Dirty Buffer)写出:

• 当一个 Server 进程扫᧿一定量的 Buffer 后仍然不能发现可用的 Buffer 时,通知

DBWn 执行写出;

• DBWn 会自动阶段性的执行写出,增进检查点。

由于内存中数据块的变更是零散的,所以 DBWn 执行批量写出才能有利于性能ᨀ升,

LGWR 进程通过日志写操作,延迟 DBWn 的写操作,从而实现了协同与性能促进。

LGWR – 其全名为 Log Writer Process – 日志写进程,LGWR 进程管理 SGA 中的 Redo

Log Buffer,将其中的内容连续写出到在线的日志文件中。Oracle 的 Redo 中记录的是可以重演

事务变更的必要信息,在事务ᨀ交时,日志必须写出到日志文件中。通过 LGWR 对于日志文

件的连续写出,就可以推延了 DBWR 对于脏数据的写出,从而保证 DBWR 可以实现批量写出

的性能ᨀ升。

在以下条件下,LGWR 将执行写出操作:

• 用户ᨀ交事务

• 在线日志发生切换(Log Switch)

• 距上次写操作 3 秒

• Redo Log Buffer 1/3 满或者具备 1 MB 数据

• 在 DBWn 执行写出前,需要确保相关 Dirty Buffer 的对应日志都已写出,此时会

通知 LGWR 写出此前未完成写出的相关日志。

CKPT – 其全名为 Checkpoint Process – 检查点进程,它负责更新控制文件和数据文件头

的检查点信息,CKPT 进程还会通知 DBWn 进程去执行写操作。检查点信息包括检查点位置、

SCN、Redo 的恢复位置等。

SMON – 其全名为 System Monitor Process – 系统监控进程,负责执行一系列的系统级别

的清理和其他工作,包括:

• 在数据库启动时,执行必要的实例恢复。在 RAC 数据库中,SMON 进程负责为

失败实例执行实例恢复。

第 1 章 数据库的启动和关闭

·9·

• 执行在实例恢复时跳过的中断事务,如由于读文件或表空间离线等错误,在实例

恢复时无法执行,SMON 则可以在表空间或文件在线时执行事务恢复。

• 回滚死事务,当一个进程异常中断,它的未ᨀ交事务就成为死事务,由 SMON 进

程负责回滚。

• 清理不再使用的临时段,例如当索引创建失败时产生的遗留临时段。

• 在字典管理表空间中,执行连续自由区间的合并。

• 维护 SMON_SCN_TIME 系统表。SMON_SCN_TIME 表记录了 SCN 与时间的对

应关系,由 SMON 定期进行定新,并将一些较老的数据定期删除。

• 维护 col_usage$数据字典表、维护 mod_mods$系统表。

• 定期 OFFLINE 多余的回滚段。

• 清理 obj$数据字典表中的垃圾数据。

VKTM – 其全名为Virtual Keeper of TiMe – 虚拟时钟进程,这个进程是在Oracle Database

11g 中引入的进程,用于ᨀ供一个数据库内部的虚拟时钟,以计算各种时间间隔量度等,VKTM

的引入降低和操作系统之间的交互,从而ᨀ高了性能。

VKTM 有两种运行模式:

• 基础模式,秒级间隔更新;

• 或者作为参考时间计数器,这种方式每 20 毫秒更新一次,仅在高优先级时可用。

对于不同的版本,VKTM 的设定模式可能不同,具体可以从告警日志文件中查知。

在 Oracle 11g 启动的过程中,信息ᨀ示:

K@)qu fgghg4usru5ovv,bVut cehbh>gu

在 Oracle 12c 中,信息ᨀ示:

K@)qubrs rc*uYhrDuth*[A-u.9uh*[oARvvusruclc7src*ut h> hr3

K@)qu fgghg4usru52vV,but cehbh>g

这个进程作为一个必选进程,对于数据库运行变得必不可少。

1.1.4. V$PROCESS 视图

细心的读者朋友通过前面的阅读或许已经注意到,在日志的进程启动信息里,并没有 pid=1

的进程,那么这个进程是否存在呢?

通过数据库中的 v$process 视图,可以找到对应于操作系统的每个进程信息:

9#=wubclcerus** -th*-bth*-fbc gs,c-t >4 s,uG >,u7dt >ecbbF

6SS0uuuuuuuuuuuu_iSu9_iSuuuuuuuU9'0n6q'u_0.y06q

BBBBBBBB BBBBBBBBBB BBBBBBBBBB BBBBBBBB BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB

TI'o%26Puuuuuuuuuuouuuuuuuuuuuuuuuuuuuuu_9'US.

TI'o%E%vuuuuuuuuuu2u%2Rvuuuuuuu> selcuuu> selcac34lcu5_q.nV

TI'o%'oNuuuuuuuuuuAu%2R2uuuuuuu> selcuuu> selcac34lcu5_9_vV

TI'o;APEuuuuuuuuuuNu%2RNuuuuuuu> selcuuu> selcac34lcu5qq6nV

TI'o;R;PuuuuuuuuuuTu%2R%uuuuuuu> selcuuu> selcac34lcu5S$(vV

TI'o;IAvuuuuuuuuuu%u%2REuuuuuuu> selcuuu> selcac34lcu5=y(0V

《深入解析 Oracle》

·10·

TI'oEN'Nuuuuuuuuuu;u%Avvuuuuuuu> selcuuu> selcac34lcu5P@_)V

mmmmmmmmm

注意以上输出,pid=1 的进程是一个 PSEUDO 进程,这个进程被认为是初始化数据库的

进程,启动其他进程之前即被占用,并在数据库中一直存在。通过 Oracle 的 oradebug 工具可

以稍微浏览一下这个进程的信息,以下是简要步骤,转储 SYSTEMSTATE:

9#=wue>ggceruMusbub3b*1s

P>ggcerc*m

9#=wu> s*c1f4ubcr,3th*

9rsrc,cgrut >ecbbc*m

9#=wu> s*c1f4u*f,tub3brc,brsrcuov

9rsrc,cgrut >ecbbc*m

9#=wubD>Yuts s,crc ufbc C*f,t

n6q' uuuuu)x_' K6=U'

BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB BBBBBBBBBBB BBBBBBBBBBBBBBBBBBBBBBBBBBBBBB

fbc C*f,tC*cbr uuuuubr hg4 MroM> sroM*hs4M *1,bMrooo4M)ooo4Mr sec

在 user_dump_dest 目录中可以找到进程转储文件,其中进程 1 的信息如下,供读者参考:

_0.P'99uoQu

uuBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB

uu9.QuvYgc Qu5ghlV-uGls4Quini)MBMBMve[vecbb-uGhlc[/bfmDu=in'Qo2%o%-ut4[v

uu5t >ecbbVu. selcuth*Qo-ubc Qv-uesllbuef Mr>tQu5ghlVM5ghlV

uuuuuuuuuuuuGls4buQu5v<2vVu_9'US.> Quv-ueslluc > Quv-ubcbbuc > Quv-ur uv

uuuuuuuuuuuuhgr uzfcfcQuc,tr3

uuuu/bf*ltuI6=9'usrul>esrh>gQuv

uu5t>bruhgG>V lsbrut>bru cech7c*Quvuvuv

uuuuuuuuuuuuuulsbrut>bru cech7c*Bl>esrh>gQun>ut>br

uuuuuuuuuuuuuulsbrut >ecbbur>ut>bru,cQug>gc

uuuuuuuuuuuuuulsbrut>brubcgrQuvuvuv

uuuuuuuuuuuuuulsbrut>brubcgrBl>esrh>gQun>ut>br

uuuuuuuuuuuuuulsbrut >ecbbut>brc*u13u,cQug>gc

uuuu5lsreDuhgG>VuYshrCc7cgr[vu1hrb[v

uuuu.M9uhgG>Qufbc Qu-urc ,Qu-u>bth*Quu5S'6SV

uuuu.9Suth*uhgG>QuUghecbbuth*Quv-uh,s4cQu_9'US.

uuuuBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB

uuuu9.Quv<%vvveEAE-ur3tcQuT-u>Ygc Quve[5ghlV-ugs,c[/bbuts cgr-uGhlc[/bb2mDu=in'QoAE-ut4[v

uu_9.ueDhl*ubrsrcu>1|cerueDsg4cbuQ

Sf,tu>Gu,c,> 3uG >,uvuv selcac34lcu1*f,tpdutbuBcG:4 ctu> sC

> selcuuuu%2Rvuuuuuouuvuo2QN2u?uuuuuuuuvvQvvQvvu> sCt,>gCc34lc

> selcuuuu%2R2uuuuuouuvuo2QN2u?uuuuuuuuvvQvvQvvu> sCtbtvCc34lc

> selcuuuu%2RNuuuuuouuvuo2QN2u?uuuuuuuuvvQvvQvvu> sC,,sgCc34lc

> selcuuuu%2R%uuuuuouuvuo2QN2u?uuuuuuuuvvQvvQvvu> sC*1YvCc34lc

> selcuuuu%2REuuuuuouuvuo2QN2u?uuuuuuuuvvQvvQvvu> sCl4Y Cc34lc

> selcuuuu%Avvuuuu ouuvuo2QN2u?uuuuuuuuvvQvvQvvu> sCe/trCc34lc

mmmmmmmmm

如果在操作系统上发现某个进程表现异常(如占用很高的 CPU 资源),那么通过操作系

统上的 PID 和 V$PROCESS 视图中的 SPID 关联,就可以找到这个 OS 上的进程在数据库

内部的化身,从而可以进行进一步的跟踪诊断。

V$PROCESS 视图包含当前数据库中活动进程的相关信息,这些进程在操作系统上都存在

与之对应的 OS 进程。其中 LATCHWAIT 列代表进程当前正在等待的 LATCH 信息,

LATCHSPIN 则记录进程正在通过 SPIN 进行 LATCH 的竞争。Latch 通常被称为闩,是数据库

内部的串行锁机制,主要用来控制内存上的并发,在多处理器系统上,Oracle 进程通过自旋(spin)

来进行 Latch 争夺。

这个视图结构如下所示(Oracle 10gR2 版本):

9#=wu*cbeu7dt >ecbb

ns,cuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuunfll?uuuu)3tc

BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB BBBBBBBB BBBBBBBBBBBBB

6SS0uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu06(5NV

_iSuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuunUq$'0

9_iSuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuK60Pk6025o2V

U9'0n6q'uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuK60Pk6025oTV

9'0i6=juuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuunUq$'0

)'0qin6=uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuK60Pk6025AvV

_0.y06quuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuK60Pk6025NEV

)06P'iSuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuK60Pk60252TTV

$6P@y0.UnSuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuK60Pk6025oV

《深入解析 Oracle》

·12·

=6)Pk(6i)uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuK60Pk6025EV

=6)Pk9_inuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuK60Pk6025EV

_y6CU9'SCq'quuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuunUq$'0

_y6C6==.PCq'quuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuunUq$'0

_y6CI0''6$='Cq'quuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuunUq$'0

_y6Cq6!Cq'quuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuunUq$'0

注意这里的 ADDR 字段代表的是进程的地址,进程的状态等信息在内存中记录,这个

ADDR 记录的正是这样的内存地址信息。ADDR 在数据库中(甚至是所有软件中)是非常重

要的,虽然通常并不会用到,但是深入理解这些知识有助于大家更好的了解 Oracle 数据库。

进程的地址(Address of process)进一步的被缩写为 PADDR,在 V$SESSION 视图中记

录的 PADDR 就是 V$PROCESS.ADDR 的进一步延伸,通过两者关联,可以向数据库进

一步深入。

如果向操作系统端延伸,则 SPID 代表的正是操作系统进程标识符(Operating system

process identifier),通过 SPID 和 OS 中看到的进程 PID 关联,就可以建立从操作系统到数据库

的关联。

所以 V$PROCESS 被认为是从操作系统到数据库的入口。此外,和 PGA 相关的几个

字段则记录了进程的 PGA 使用情况。

1.1.5. 从操作系统到数据库

在上一节我们ᨀ到,V$PROCESS 被认为是从操作系统到数据库的入口,而进入数据

库内部,进程需要创建会话(Session)执行数据库操作和访问,通常一个进程创建一个

会话,特殊情况下,一个进程也可以创建多个数据库会话。会话信息通过视图

V$SESSION 进行体现和管理。

V$SESSION 视图在不同版本中被不断增强,尤其是自 Oracle 10g 开始,整合了

V$SESSION_WAIT(会话正在发生的等待信息)视图。

我们来看一下,如何完成从系统到数据库内部的导引。以下是一个简单的诊断分析

案例,在故障时刻,通过 TOP 工具观察到,有两个操作系统进程占用了极高的 CPU 资

源:

dur>t

l>s*us7c s4cbQuuom%o-uuom2E-uuom2Tuuuuuuuuuuk9(6_89S$uuuuuuuuuuuuuovQTvQNN

o;2ut >ecbbcbQuo%vublccthg4-uou fgghg4-uAuW>,1hc-u%ubr>ttc*-u2u>guetf

P_UubrsrcbQuuuuu&uh*lc-uuuuu&ufbc -uuuuu&u/c gcl-uuuuu&uh>Yshr-uuuuu&ubYst

qc,> 3QuNmvyu csl-uomNyuG cc-uomRyubYstuhgufbc-uEmRyubYstuG cc

uuu_iS U9'0n6q'u)k0u_0unP'uu9i+'uuu0'9u9)6)'uuu)iq'uI=)9uuuuP_UuP.qq6nS

2vT2o > selcuuuuuouNvuuuvuuomEyuuom;yu fguuuuu%QA;uuuuvuN;m;;&u> selc

2vENT > selcuuuuuouNvuuuvuuomEyuuom;yuetfv2uuuvQNouuuuvuNvmRE&u> selc

第 1 章 数据库的启动和关闭

·13·

2vEN;u> selcuuuuuouTEuuuvuuomEyuuom;yublcctuuuvQvvuuuuvuuvmEN&u> selc

2v;Evu> selcuuuuuouNEuuuvuuomEyuuom;yublcctuuuvQv2uuuuvuuvmEA&u> selc

oTE2Eu> selcuuuuuouTEuuuvuuomEyuuom;yublcctuuuvQTEuuuuvuuvmTA&u> selc

这两个进程分别是 20521 和 20845.通过 PS 命令可以找到这两个进程更为详细的信息:

dutbuBcG:4 ctu2vT2o

uu> selcu2vRvRu2vE;TuuvuovQTvQTAutrbMovuuuvQvvu4 ctu2vT2o

uu> selcu2vT2ouuuuuouN;uovQNAQTRu?uuuuuuuu%QNTu> selc|bDbu5=.P6=[n.V

dutbuBcG:4 ctu2vENT

uu> selcu2vENTuuuuuouNNuovQTvQvvu?uuuuuuuuvQTTu> selc|bDbu5=.P6=[n.V

uu> selcu2vRoEu2vE;TuuvuovQTvQTRutrbMovuuuvQvvu4 ctu2vENT

这两个 LOCAL=NO 的进程显然是来自应用的远程连接,通过如下脚本,关联 V$PROCESS

视图和 V$SESSION 视图、V$SQLTEXT 视图,可以找出这个进程正在执行的 SQL 语句,这

里只需要一个“发动”条件,就是进程号(PID):

9'='P)uuuMH~u.0S'0'SuHM

uuuuuuuuubzlCrcgu1

uuuuuuuuuuuuu(k'0'u1mts** u[u59'='P)us**

uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuI0.qu7dt >ecbbue

uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu(k'0'uembth*u[uJZth*JVV

.0S'0u$xuthcecu69P

M

注意这里我们涉及了 3 个视图,并应用其关联进行数据获取,核心逻辑分解如下:

1.首先输入一个 pid,这个 pid 即 Process id,也就是在 Top 或 ps 中看到的 PID。

2.通过 pid 和 v$process.spid 相关联我们可以获得 Process 的相关信息。

3.通过 v$process.addr 和 v$session.paddr 相关联,可以获得和 session 相关的所有信息。

4.再结合 v$sqltext,即可获得当前 session 正在执行的 SQL 语句。

可见通过 v$process 视图,我们得以把操作系统和数据库关联了起来

相关数据流

科普文章
靠谱网站365

科普文章

⌚ 07-06 👁️‍🗨️ 7779
驱入虚空🔥新人必看!超详细开荒攻略💎
线上365bet注册

驱入虚空🔥新人必看!超详细开荒攻略💎

⌚ 06-27 👁️‍🗨️ 444
微信订阅号怎么开通 微信订阅号开通方法【详细教程】
靠谱网站365

微信订阅号怎么开通 微信订阅号开通方法【详细教程】

⌚ 06-29 👁️‍🗨️ 7886