Oracle体系结构之进程
一、概述
Oracle中的每个进程都要执行一个特定的任务(或者一组任务),每个进程都会为自己分配内存(PGA)来完成它的任务。一个Oracle实例主要有以下3类进程:
(1) 服务器进程(server process):服务器进程包括专用服务器和共享服务器,用来处理你提交所有SQL。当你向数据库提交一个SELECT * FROM EMP查询时,就会有一个ORACLE专用/共享服务器进程来解析这个查询,把它放到共享池中(或者最好能发现这个查询已经在共享池中)。这个进程要自行制定查询计划(如果有必要),然后执行它,并尽可能地在缓冲区缓存中找到必要的数据,或者将从磁盘中将数据读入缓冲区缓存。
(2) 后台进程(background process):这些进程随着数据库的启动而启动,用于完成各种维护工作。
(3) 从属进程(slave process):类似后台进程,代表后台进程或服务器进程完成一些额外的工作。
二、服务器进程
(1) 专用服务器连接
采用专有服务器连接时,会在服务器上得到一个针对这个连接的专用进程。客户端连接和服务器进程(或者有可能是线程)之间有一个一对一的映射关系。如图显示了查询专用服务器进程和本地客户端进程。
(2) 共享服务器连接
共享服务器连接要求必须使用Oracle Net,即使客户端和服务器都在同一台机器上也不例外。如果不使用Oracle TNS监听器,就无法使用共享服务器。
客户端应用(其中链接了Oracle库文件)会与一个调度器程序物理连接在一起。调度器程序只负责从客户端应用接收入站请求,并把它们放入SGA中的一个请求队列。共享服务器进程池(其中包括了一些预先创建好的共享服务器进程)中第一个可用的进程会从队列中依次获取请求,并附加上相关会话的UGA。共享服务器进程将会处理这个请求,并将得到的输出放在响应队列中。调度器程序持续监控着响应队列中的结果,并将结果传回给客户端应用。
(3) 数据库常驻连接池
数据库常驻连接池(DRCP)是连接数据库并建立会话的一种可选方法。有些应用接口自身不支持高效连接池(如PHP),DRCP就是为这种应用接口设计的一种更为高效的连接池方法。
三、后台进程
Oracle实例由两个部分组成:SGA和一组后台进程。如下图显示了数据库的后台进程。
(1) PMON: 进程监控器
进程监控器(process monitor)负责在连接出现异常终止后进行清理工作,还负责监控其他的Oracle后台进程,并在必要的时候(而且可能)时重启这些后台进程。
注:在Oracle Database12C之前,PMON还负责处理注册监听的任务。从Database 12C开始,改由专门的监听注册后台进程(LREG)来注册实例和服务到监听器。
(2) LREG: 监听注册进程
从Database 12C开始,负责将数据库实例和服务注册到监听器中。当一个数据库实例启动时,LREG进程会去查看监听端口(一般为1521)是否已经有监听器在上面运行了。我们也可以通过LOCAL_LISTENER参数明确地指定当前的监听端口,也可以通过使用REMOTE_LISTENER参数来让LREG去注册服务到一个远程监听器。
(3) SMON: 系统监听器
SMON所做的工作包括以下几种:
1) 清理临时表空间;
2) 合并空闲表空间;
3) 针对原来不可用的文件恢复活动的事务;
4) 执行RAC中失败节点的实例恢复;
5) 清理OBJ$
6) 管理撤销段
7) 回滚段离线
(4) RECO: 分布式数据库恢复
RECO的核心任务:由于两阶段提交(2PC)期间的奔溃或连接丢失等原因,有些事务可能还保持在准备状态。这个进程就是要恢复这些事务。
(5) CKPT:检查点进程
实施检查点是DBWn进程的工作。CKPT仅仅是协助实际运行检查点的进程,来更新数据文件的文件头。
(6) DBWn: 数据库块写入器
数据库块写入器是负责将脏块写入磁盘的后台进程。DBWn的性能至关重要,如果它写出块的速度不够快,不能很快地释放缓冲区,就会看到Free Buffer Waits和Write Complete Waits这两个等待时间的数量和等待时间开始增加。
在Oracle Database 11g中,我们最多可以配置36个DBWn进程;而到了Database 12C,我们可以配置多达100个DBWn进程。
在最好的情况下,DBWn使用异步I/O将块写至磁盘。块写入器进程会将块分散地写到磁盘的各个位置,也就是说DBWn会执行大量的离散写。相比于LGWR的顺序写,离散写的速度慢很多,这也是在线重做日志存在的必要性。
(7) LGWR: 日志写入器
LGWR进程负责将SGA中重做日志缓冲区中的内容刷新输出到磁盘。LGWR通过顺序写,只把有变化的字节写出到磁盘。触发LGWR进行写操作的条件有以下三个:
1) 每过三秒;
2) 一个提交或者回滚发起时;
3) LGWR被告知进行日志文件切换时;
4) 重做日志缓冲区1/3满,或者已经包含1MB的缓冲数据。
(8) ARCn: 归档进程
ARCn进程的任务:当LGWR将一个在线重做日志文件填满时,将其复制到另一个位置。此后这些归档的重做日志文件可以用来完成介质恢复。在线重做日志用于在出现掉电(实例终止)时“修正”数据文件,而归档重做日志文件则出现在磁盘故障时用于“修正”数据文件。
(9) DIAG: 诊断进程
利用ADR(高级诊断库,Advanced Diagnostic Repository),它会负责监视实例的整体状况,而且会捕获处理实例失败时所需的信息。这既适用于单个实例配置,也适用于多实例的RAC配置。
(10) FBDA: 闪回数据归档进程
闪回数据归档功能是指能够闪回查询(as of查询)很久以前的数据。这种长期历史查询功能是通过维护行的历史变化记录,即记录一个表中的每一行的数据变化来实现的。FBDA负责维护这个历史。
(11) DBRM : 数据库资源管理器进程
DBRM进程会去实施那些为一个数据库实例配置的资源计划。它会设置指定的资源计划,执行相关的各种操作来实施/实现这些资源计划。资源管理器允许数据库管理员对数据库实例所用的资源、应用访问数据库所用的资源或者单个用户访问数据库所用的资源进行细粒化的控制。
(12) GEN0: 通用任务执行进程
通用任务执行进程是为数据库提供了一个执行通用任务的进程。这个进程的恶只要目标是分担进程中某些可能造成进程阻塞的处理过程(这些处理过程会造成一个进程的停止),并将它们放在后台中完成。
(13)其他一些进程
四、工具后台进程
这些后台进程都是可选的。下面为一些常用的可能遇到的进程:
(1)CJQ0和Jnnn进程:作业队列
作业队列进程监控一个作业表,这个作业表告诉它何时需要刷新系统中的各个快照。
(2) QMNC和Qnnn:高级队列
QMNC进程会监控高级队列,并在某个等待消息变为可用状态时,提醒其出队。
(3) EMNC:事件监视器进程
EMMC进程是高级队列体系结构的一部分,用于通知队列去订阅它们感兴趣的消息。
(4) MMAN:内存管理器
这个进程存在于Oracle Database 10g及以上的版本,用来自动设置SGA大小。MMAN进程负责各个共享内存组件(包括默认缓冲区池、共享池、Java池和大池)的大小设置和大小调整。
(5) MMON、MMNL和Mnnn:可管理性监视器
这些进程用于向自动工作负载存储库(AWR)中填充信息。MMNL进程会*调度将各种统计信息冲SGA刷新输出到数据库表中。MMON进程用于自动监测数据库性能问题,并实现自我调优功能。Mnnn进程类似于作业队列的Jnnn或Qnnn进程。
(6) CTWR:修改跟踪进程
CTWR进程负责维护修改跟踪文件。
(7) RVWR:恢复写入器
当使用FLASHBACK DATABASE命令时,它负责维护快速恢复区中块的“前”映像。
(8) DMnn/DWnn:数据泵主进程/工作进程
数据泵主进程(DMnn)收集客户端进程的所有输入,然后协调工作进程(DWnn)执行具体工作,DMnn进程完成元数据和数据的具体处理。
(9) TMON/TT00:传输监视器和重做传输从属进程
Oracle Database 12c中的两个Data Guard相关进程,会随数据库实例的启动而启动。TMON将会启动并监视一定数量的TT00进程。TT00进程用来通知LGWR进程去生成心跳重做。
(10) 其他工作后台进程
五、从属进程
(1) I/O从属进程
I/O从属进程用于在不支持异步I/O的系统和设备上模拟异步I/O,如磁带设备。由I/O从属进程来等待慢速的设备,而调用它们的进程则得以脱身,可以做其他重要的工作:收集下一次要写的数据。
有两个参数控制着I/O从属进程的使用:
1) BACKUP_TAPE_IO_SLAVES:指定RMAN是否使用I/O从属进程将数据备份、复制或恢复到磁带上,该参数是为磁带设备设置的。当该值为TRUE时,则使用一个I/O从属进程读写磁带设备;当该值为FALSE时,则用来执行本份的专用服务器进程会直接访问磁带设备。
2) DBWR_IO_SLAVES:指定了DBW0进程所用的I/O从属进程的个数。该值若为非0值,LGWR和ARCn也会使用自己的I/O从属进程。
DBWn I/O从属进程的名字是I1nn,LGWR I/O从属进程的名字是I2nn。
(2) pnnn:并行执行查询服务器
对于SELECT、CREATE TABLE、CREATE INDEX、UPDATE等SQL语句,创建一个执行计划,其中包含了可以同时执行的多个(子)执行计划。将每个执行计划的输出合并在一起构成一个更大的结果,其目标是用串行执行这个操作所需时间的几分之一来完成同样的工作。
在Oracle Database 12C之前,并行执行服务器的默认数量是0,我们可以通过修改PARALLEL_MIN_SERVERS参数值来修改它,该值默认为0;而在Oracle Database 12C开始,PARALLEL_MIN_SERVERS默认值已经设置为一个非0值(根据CPU_COUNT * PARALLEL_THREADS_PER_CPU * 2得到)。