4.3 实例中的后台进程
在一个大型数据库系统中,每时每刻都可能处理大量的用户请求,在数据库服务器中需要执行非常复杂的处理。例如,将脏缓冲区中的内容写入数据文件,将重做日志缓冲区中的重做日志写入重做日志文件,发出检查点以维护数据文件、控制文件和重做日志文件间的一致状态,在数据库服务器重新启动时进行实例恢复,进行重做日志归档等,这些任务都由实例中的后台进程来完成。
当实例启动时,这些后台进程将自动启动。每个进程都有特定的功能,同时,这些进程之间也会相互协作。例如,LGWR进程用于把重做日志缓冲区中的重做日志写入重做日志文件,当重做日志文件被写满后,LGWR进程将向ARCH进程发信号,由ARCH进程对重做日志文件进行归档。
需要注意的是,并不是所有的后台进程都需要启动。常用的后台进程及其功能如表4.1所示。
实例启动后,可以查看正在运行的后台进程。例如,在SQL*Plus中查询动态性能视图V$BGPROCESS,可以获得正在运行的后台进程:
SQL>SELECT name FROM v$bgprocess WHERE paddr<>'00';
NAME
PMON
DBW0
LGWR
CKPT
SMON
RECO
其中条件paddr<>'00'限定了“正在运行的后台进程”。
实例中的后台进程与SGA、数据文件、控制文件和重做日志文件的关系如图4.3所示。
图 4.3 后台进程与SGA及数据库文件的关系
4.3.1 DBWR进程
DBWR进程的功能是将数据库高速缓存中的脏缓冲区内容写入数据文件中的数据块。当用户执行DML命令时,服务器进程在数据库高速缓存中的缓冲区中修改数据,并将修改后的缓冲区标志为“脏缓冲区”。DBWR进程将在一定的条件下将脏缓冲区的内容写入数据文件。
用户执行了DML命令后,被修改的缓冲区并不是被立即写入数据文件,而是保留一段时间,即使用户执行了COMMIT操作。DBWR进程开始工作时,它将把一批脏缓冲区的内容一块写入数据文件。这样做的好处有两点,一是减少了写磁盘的次数,因为多次写磁盘的操作被合并为一次写操作。二是减少了读磁盘的次数,因为如果另外一个用户正好也要对同样的数据进行处理,便可直接在脏缓冲区中进行。如果脏缓冲区被写入了数据文件,它将成为空闲缓冲区,并且可能马上被其他的访问所使用。一旦空闲缓冲区被再次使用,那么当另外一个用户要访问这个缓冲区中以前的内容时,只好重新从数据文件中读取。
用户访问数据库时,服务器进程如果发现需要的数据不在数据库高速缓存中,它将把数据从数据文件读到空闲缓冲区中,在此之前,服务器进程要在LRU队列中搜索合适数量的空闲缓冲区,在搜索过程中如果遇到一个脏缓冲区,服务器进程将把它记录在脏队列中,然后继续搜索。如果遇到忙缓冲区,将忽略它。DBWR进程工作时,将扫描脏队列,把那些位于脏队列中,并且最近很少被访问的脏缓冲区写入数据文件。而那些虽位于脏队列,但最近仍被频繁访问的脏缓冲区,或者那些还没有被记录在脏队列中的脏缓冲区,仍然可以保持“脏”状态,直到被写入数据文件。
在一个实例中可以启动多个DBWR进程,在默认情况下只启动一个。如果用户的事务很频繁,那么在数据高速缓存中将瞬间产生大量的脏缓冲区,对于一个DBWR进程来说,要把这些脏缓冲区写入数据文件,负载是很重的。这时候可以考虑启动额外的DBWR进程,以提高写数据的效率。DBWR进程的数目由初始化参数DB_WRITER_PROCESSES指定,最多可以启动20个(DBW0-DBW9以及DBWa-DBWj)。
DBWR进程并不是越多越好,一个基本的原则是,这个进程的数目不要超过CPU的数目,如果计算机中只有一个CPU,多个DBWR进程在CPU中只能以串行方式运行。而且计算机中如果只有一个硬盘,对数据库的写操作也只能以串行方式进行,如果多个DBWR进程同时写数据文件,将发生磁盘访问冲突。
DBWR进程在以下几种情况执行写操作:
·固定的时间间隔(如每隔3秒)。
·当数据库服务器发出检查点时。
·当脏队列中的缓冲区数目达到一定值时,也就是说在数据库高速缓存中不能有太多的脏缓冲区。
·当用户执行了某操作,需要在数据库高速缓存中搜索一定数量的空闲缓冲区时,空闲缓冲区的数量不能满足要求,这时DBWR进程将把脏队列中的一部分脏缓冲区写入数据文件,这部分脏缓冲区将重新成为空闲缓冲区。