Oracle 后台进程

数据库的进程可以简单地分为前台进程和后台进程,前台进程是Oracle客户端访问数据库而创建的影子进程,后台进程是维持Oracle数据库正常运行所必需的。

1. 进程结构

进程是操作系统中的一种机制,它可使用操作系统中的资源完成某个特定的任务。一个进程通常有其专用的存储区和特定的功能。Oracle进程体系结构的设计目的是尽可能地使用系统的资源,使访问者获得最大的吞吐量和最短的响应时间。

在多进程系统中,进程分为两类:前台进程(又分用户进程和服务进程)Oracle后台进程。当用户运行一个应用程序时,如PRO*C程序或Oracle工具(如SQL*Plus),系统会为用户运行的应用建立一个用户进程,该进程通过某种方式启动一个服务器进程(前台进程),用于处理连接到该实例的用户进程的请求。如果应用和Oracle在同一台机器上运行,而不通过网络,那么用户进程和服务器进程之间可以通过BEQ协议通信,从而降低系统开销。然而,当应用和Oracle运行在不同的机器上时,用户进程使用TCP/IP协议,通过服务器进程访问Oracle。

为了使系统性能最好并能够协调多个用户,多进程系统使用了一些附加进程,称为后台进程。在许多操作系统中,后台进程是在实例启动时自动建立的。一个Oracle实例可以包含许多后台进程,但它们不是一直存在的。后台进程的名称为:

  • DBWR,数据库写入程序;
  • LGWR,日志写入程序;
  • CKPT,检查点;
  • SMON,系统监控;
  • PMON,进程监控;
  • ARCH,归档;
  • RECO,恢复;
  • LCKn,封锁;
  • Dnnn,调度进程;
  • Snnn,服务器。

每个后台进程与Oracle数据库的不同组件进行交互,完成特定的功能。比如,DBWR负责脏数据存盘工作,LGWR负责将LOGBUFFER中的数据写入在线日志文件。

2. 后台进程的功能介绍

Oracle 的后台进程负责管理和维护Oracle实例。每个后台进程都负责一项独立的工作。这些后台进程互相协作,完成Oracle的公共职能。它们之间会互相监控,一旦发现核心的后台进程出现异常,会主动关闭实例。下面依次介绍主要后台进程的功能。

2.1 DBWR 进程

DBWR 进程执行将数据块缓冲区写入数据文件的工作,是负责缓冲存储区管理的一个Oracle后台进程。在修改DB Cache中的某个缓冲区时,会将它标志为“DIRTY”,DBWR的主要任务是将这些标为“DIRTY”的缓冲区写入磁盘,使缓冲区保持“CLEAN”。由于缓冲区填入数据库或被用户进程弄脏,未用的缓冲区数目会减少,最终可能导致用户进程从磁盘读入块到内存存储区时无法找到未用的缓冲区。DBWR将管理缓冲存储区,使用户进程总能得到未用的缓冲区。

Oracle采用LRU算法(最近最少使用算法)保持内存中的数据块是最近使用的,使I/O最小。在某些平台上,如果有多个CPU,那么一个实例可设置多个DBWR。在这样的实例中,DBCache被分为多个区,每个DBWR管理一个或者几个DBCache分区。这种结构可以让一些数据块写入一个磁盘,另一些数据块写入其他磁盘,从而提升并发写入的性能。参数db_writer_processes可以控制DBWR进程的个数。

2.2 LGWR 进程

LGWR进程是负责管理日志缓冲区的一个Oracle后台进程,它将日志缓冲区写入磁盘上的日志文件。LGWR进程将自上次写入磁盘以来的全部REDO LOG ENTRY写入到REDO LOG文件中。触发LGWR写操作的条件如下。

  • 当用户进程提交一事务时写入一个提交记录。
  • 每 3 秒将日志缓冲区输出。
  • 当日志缓冲区的已满 1/3 时,将日志缓冲区输出。
  • 当 DBWR 将修改缓冲区写入磁盘时,则将日志缓冲区输出。

LGWR 进程同步地写入到活动的镜象在线日志文件组。如果组中一个文件被删除或不可用,LGWR可继续地写入该组的其他文件,而数据库实例可以继续运行。日志缓冲区是一个循环缓冲区。当LGWR将日志缓冲区的日志项写入日志文件后,服务器进程即可将新的日志项写入到该日志缓冲区。LGWR的写入速度很快,以确保日志缓冲区总有空间可写入新的日志项。

Oracle使用快速提交机制,当用户发出COMMIT语句时,一条COMMIT记录立即被放入日志缓冲区,但相应的数据缓冲区改变被延迟,直到更有效时才将它们写入数据文件。提交时,将事务赋给一个系统变更号(SCN),它同事务日志项一起被记录在日志中。

2.3 CKPT 进程

CKPT 进程在检查点出现时,对全部数据文件的文件头进行修改,并在控制文件中记录该检查点。在早期版本中,该任务由LGWR执行。然而,在检查点明显地降低系统性能时,可使CKPT进程运行,将原来由LGWR进程执行的检查点的工作分离出来,由CKPT进程执行。另外,如果数据文件的数量很多,那么启用CKPT会对性能有一定的提升。

2.4. SMON 进程

SMON进程负责在实例启动时执行实例恢复,并清理不再使用的临时段。在具有并行服务器选项的环境下,SMON对有故障的CPU或实例进行实例恢复。从Oracle9i开始,事务回滚操作的默认行为也是由SMON来负责处理的。虽然SMON本身不做恢复操作,而是启用并行进程来处理,但是它起到整体协调的作用。SMON进程有规律地被唤醒,并检查是否有工作要完成,如有需要,就做相应的处理,否则继续休眠。

2.5. PMON 进程

PMON进程在用户进程出现故障时执行进程恢复,负责清理存储区和释放该进程所使用的资源。比如,某个进程死掉了,PMON要重置活动事务表的状态,释放锁资源,将该故障的进程ID从活动进程表中移去。PMON还周期性地检查调度进程(DISPATCHER)和服务器进程的状态,如果发现这些后台进程死掉,就需要重新启动。PMON有规律地被呼醒,检查是否有需要完成的工作。

2.6 ARCH 进程

ARCH 进程将已填满的在线日志文件复制到指定的存储设备。当日志为ARCHIVELOG使用方式并可自动归档时,ARCH进程才存在。

3. 是谁在执行 SQL

“是谁在执行SQL?”这个问题看似很简单,不过要认真考虑起来,却也不那么简单。客户端连接到数据库时,Oracle会创建一个服务进程(Server Process),Oracle的客户端通过和该进程通信来完成SQL的执行。如果是Oracle的后台进程来执行SQL,那么在一个大型的数据库系统中,会有数千甚至上万个客户端在访问数据库,光凭几个Oracle后台进程是肯定无法完成这个任务的,这样就会出现瓶颈。从这个角度来看,服务进程应该是执行SQL的“最佳人选”了。在独立服务器模式下,每个Oracle会话都拥有一个独立的服务进程,如果让它来担当执行SQL的角色,那么就不会出现资源瓶颈了。事实上,Oracle也是这样安排的,TWO TASK的服务器端的服务进程,担当的就是这样一个角色。客户端要执行的SQL,通过SQL*Net或者BEQ(客户端和数据库服务器运行在同一台服务器上时,可以不通过SQL*Net,而直接通过IPC通信协议BEQ来通信)发送给服务进程,由它来完成SQL的执行。

执行SQL的主体是会话(Session),执行SQL的呼叫是由会话发起的,会话是Oracle数据库用户进行SQL操作的唯一渠道。那么下一个问题又来了,会话又是什么呢?搞过网络编程的朋友可能早就听说过会话这个概念了。两个网络设备要进行通信,必须先建立起一个会话,这个会话就是承载所有通信工作的逻辑载体。再往前追溯,会话的概念来自通信行业,不过Oracle会话的本质更类似于网络设备之间的通信。大家都知道网络通信有面向连接的协议,也有面向无连接的协议。面向连接的协议一般适用于上下文和状态十分关键的应用场合。Oracle的会话正是具有这样的特征,所以采用面向连接的通信协议,目前最常用的就是TCP/IP协议。

出于安全考虑,在建立会话之初,Oracle需要通过安全认证,这也就是我们常见的“数据库登录”,Oracle的术语称为LOGON。在LOGON的时候,首先Oracle客户端通过SQL*Net协议或者BEQ协议创建一个服务进程。如果通过SQL*Net协议,客户端首先要和监听器通过TCP/IP、SPX等面向连接的网络协议建立通信会话,由监听器创建一个服务进程,客户端进程将网络通信会话重定向到这个服务进程,随后,客户端进程和服务进程建立通信会话。

和客户端通信的服务进程也就是Oracle术语中所说的前台进程,客户端和前台进程建立了通信会话并不等于说Oracle的会话已经建立了,会话是一个更为虚拟的概念。客户端和服务进程完成通信会话的握手后,首先将LOGON所需要的信息发送给前台进程。前台进程收到这些信息后,执行一个被称为LOGON的操作,校验用户和权限。这个校验工作可以有多种方式,最常见的是通过SYSTEM表空间中的USER$表中保存的用户名和密码进行校验。Oracle还支持其他方式的用户名、密码校验方式,比如操作系统校验、外部安全设备校验(LDAP)。

会话建立后,就成为客户进程和数据库实例之间的沟通渠道和桥梁,执行客户端对数据库的操作,包括执行SQL。不过会话是一个逻辑结构,必须依赖于其容器——服务进程(也叫前台进程)。在独立服务器模式下,每个会话对应一个独立的服务进程,Oracle也提供了一种共享服务器模式,在这种模式下,一个服务进程可以为多个会话服务,换句话说,一个服务进程可以成为多个会话的容器。

共享服务器模式下,一般会配有一个或者多个调度进程(DISPATCHER,比如D000)和一组服务进程,这些服务进程的最大数量受到max_shared_servers参数控制。当监听进程接收到来自客户端的连接请求时,不是创建独立的服务进程,而是使用现有的服务进程池来提供服务。监听进程首先会和调度进程通信,找到可用的服务进程,调度进程会将这个服务进程及其通信端口号发送给监听进程,监听进程将网络通信连接重定向到这个服务进程,完成客户端和服务进程之间的握手。

在共享服务器模式下,由于多个会话共享一个服务进程,因此服务进程作为共享资源,也可能成为一个瓶颈。如果使用同一个服务进程的几个共享会话中有一个执行了时间很长、开销很大的SQL,那么其他会话将会处于等待状态。共享服务器模式在早期的数据库系统中的使用是比较广泛的,因为早期的服务器内存资源有限,如果使用独立服务器模式,内存资源将会十分紧张,而使用共享服务器模式可以在内存资源有限的情况下,支持大量的数据库会话。在目前内存资源十分充裕的情况下,共享服务器模式的应用就越来越少了,一个进程为一个会话服务,可以有效地提高系统总体的吞吐能力。

不过,共享服务器模式也并不是完全没有了用武之地,尤其是现在服务器性能有了大幅提高,对于某些没有使用连接池的,以短连接为主的应用来说,如果执行的大多数是开销较小的SQL,那么使用共享服务器模式可以避免由于应用软件使用短连接而导致的数据库连接风暴,因为这种数据库连接避免了频繁启动和关闭服务进程带来的性能问题。

原文地址:https://www.sunansheng.com/blog/20180603/oracle-process.html