
2.6 Oracle数据库后台进程
后台进程是在实例启动时,在数据库服务器端启动的管理程序,它使得数据库的内存结构和数据库物理结构之间协调工作。从功能上考虑,数据库物理结构、数据库内存结构和后台进程之间的关系如图2-8所示。

图2-8 内存结构、后台进程和物理结构的关系图
数据库有五个后台进程是必须启动的,否则数据库实例无法启动成功。它们分别是:DBWR、LGWR、PMON、SMON、ARCH和CKPT。本节将主要讲解这6个后台进程,它们也是数据库服务器中最重要的几个后台进程。
2.6.1 系统监控进程(SMON)
系统监控进程的主要作用是数据库实例恢复。当数据库发生故障时,如操作系统重启,此时实例SGA中所有没有写到磁盘的信息都将丢失。当数据库重新启动后,系统监控进程将自动恢复实例。实例恢复包括如下三个步骤。
01 前滚所有没有写入数据文件而被记录在重做日志文件中的数据。此时,系统监控进程读取重做日志文件,把用户更改的数据重新写入数据块。
02 打开数据库,此时或许系统监控进程的前滚操作还没有完成,Oracle这样做的目的就是方便用户及时登录,以免前滚时间太长,影响用户的行为,这样用户就可以操作那些没有被事务恢复锁住的数据。
03 回滚未提交的事物。
除此之外,系统监控进程执行某些空间维护的作用。如Combine、coalesces、adjacent 数据文件中的自由空间和回收数据文件中的临时段。
2.6.2 进程监控进程(PMON)
进程监控负责服务器进程的管理和维护工作,在进程失败或连接发生异常时该进程负责一些清理工作。
01 回滚没有提交的事务。
02 释放所持有的当前的表或行锁。
03 释放进程占用的SGA资源。
04 监视其他Oracle的后台进程,在必要时重启这些后台进程。
05 向OracleTNS监听器注册刚启动的实例。如果监听器在运行,就与这个监听器通信并传递如服务名和实例的负载等参数,如果监听器没有启动,进程监控(PMON)会定期尝试连接监听器来注册实例。
2.6.3 数据库写进程(DBWR)
在介绍高速缓冲区时,提到了脏数据的概念,脏数据就是用户更改了的但没有提交到数据库中的数据,因为在数据库中的数据文件与数据库高速缓存中的数据不一致,所以被称为脏数据,这种脏数据必须在特定的条件下写到数据文件中,这就是数据库写进程的作用。
数据库写进程负责把数据库高速缓冲区中的脏数据写到数据文件中。或许读者会问,为什么不立即提交脏数据呢,这样就不需要复杂的数据库写进程来管理了。其实,Oracle这样设计的思路很简单,就是减少I/O次数,当脏数据量达到一定程度或者满足某种其他条件时,就提交一次脏数据。因为磁盘的输入、输出会花费系统时间,使得Oracle系统的效率降低。
图2-9是数据库写进程涉及的数据库组件,通过该图可以清晰理解数据库写进程工作中涉及的“实体”。

图2-9 数据库写进程“实体”关系
当以下事件发生时,会触发数据库写进程把脏数据写到数据库的数据文件中。
● 发生检查点事件。
● 脏数据量达到了门限值。
● 数据库缓冲区没有足够的缓存为其他事务提供足够的空间。
● 表空间处于热备份状态。
● 表空间被置为离线状态。
● 表空间被置为只读状态。
● 删除表或者截断表。
● 超时。
注意
数据库写进程的性能显然很重要,如果它写脏数据到数据文件的速度很慢,使得大量缓冲区无法释放,就会出现一些等待事件,如Free Buffer Waits等。实际在Oracle数据库上,一个数据库实例可以启动多个数据库写进程,在多CPU系统可以使用多个数据库写进程来分担单个写进程的工作负载。
2.6.4 重做日志写进程(LGWR)
重做日志写进程负责将重做日志缓冲区中的数据写到重做日志文件。此时重做日志缓冲区中的内容是恢复事务所需要的信息,比如用户使用UPDATE语句更新了某行数据,恢复事务所需的信息就是更新前的数据和更新后的数据,这些信息用于该事务的恢复。
重做日志写进程在满足以下条件时,会启动进程工作。
①当事务提交时。
②当重做日志缓冲区的1/3被占用时。
③当重做日志缓冲区中有1MB的数据时。
④当数据库写进程把脏数据写到数据文件之前。
⑤每3秒钟。
图2-10是重做日志写进程工作示例图。

图2-10 数据库重做日志写进程
注意
从图2-10可以看出,日志写进程会通知数据库写进程将脏数据写到数据文件,但是数据库写进程不会把脏数据写到在线重做日志,也不会通知日志写进程做任何事情。
数据库写进程是离散写到不同的数据库文件上的,在执行一个更新时,数据库写进程会修改不同空间中存储的数据块和索引块,所以数据库写进程的离散写的速度很慢。而重做日志写进程是顺序写,它比离散写的效率要高,把每个事务的重做信息全部放在重做日志中,通过在数据库高速缓存中缓存脏数据块,而由重做日志写进程完成大规模顺序写,从整体上可以提高系统的性能。
2.6.5 归档日志进程(ARCH)
归档日志进程是可选进程,该进程并不在实例中启动,而是自动启动。它的作用是把写满的重做日志文件的数据写到一个归档日志中,这个归档日志用做介质故障时的数据库恢复。图2-11是归档日志进程涉及的实体关系,即归档日志和重做日志之间的关系。

图2-11 归档日志进程
重做日志文件负责实例失败时的数据恢复,因为SGA中没有被保存的数据会全部丢失,这样使用重做日志文件就可以完全恢复事务。而归档日志进程用于介质恢复,比如磁盘损坏时,可以使用以前备份的数据文件,利用归档日志和重做日志就可以完全恢复数据库。
归档进程不是实例启动时自动启动,在生产数据库中必须使用归档模式,以防止灾难性的数据损坏。可以使用例子2-19查看系统的归档模式。
例子2-19 查看系统的归档模式
SQL> connect system/Oracle@orcl as sysdba; 已连接。 SQL> archive log list; 数据库日志模式 非存档模式 自动存档 禁用 存档终点 USE_DB_RECOVERY_FILE_DEST 最早的联机日志序列 3 当前日志序列 5
例子2-19说明当前的数据库处于非归档模式,没有启动归档进程,归档文件存储在USE_DB_RECOVERY_FILE_DEST参数指定的目录下。那么,如何设置数据库为归档模式呢?
可以使用例子2-20设置数据库为归档模式,并且启用自动归档,但前提是必须首先关闭数据库,以mount参数启动数据库,更改后再启动到open状态即可。下面演示这个过程,注意这里的迁移是已经关闭了数据库。
例子2-20 设置数据库为归档模式的过程
SQL> shutdown immediate 数据库已经关闭。 已经卸载数据库。 Oracle 例程已经关闭。 SQL> startup mount; ORA-12514: TNS: 监听程序当前无法识别连接描述符中请求的服务 SQL> connect /as sysdba; 已连接到空闲例程。 SQL> startup mount; Oracle 例程已经启动。 Total System Global Area 535662592 bytes Fixed Size 1334380 bytes Variable Size 260047764 bytes Database Buffers 268435456 bytes Redo Buffers 5844992 bytes 数据库装载完毕。 SQL> alter database archivelog; 数据库已更改。 SQL> alter database open; 数据库已更改。
再使用例子2-21查询更改结果。
例子2-21 查询当前数据库的归档模式
SQL> archive log list; 数据库日志模式 存档模式 自动存档 启用 存档终点 USE_DB_RECOVERY_FILE_DEST 最早的联机日志序列 7 下一个存档日志序列 9 当前日志序列 9
在例子2-21中,数据库的日志模式改为存档模式,自动存档已经启动,归档日志的存储目录即存档终点是数据库恢复文件目录。
我们可以通过下例查询参数DB_RECOVERY_FILE_DEST的位置。
例子2-22 查看数据库恢复目录的位置
SQL> show parameter db_recovery_file_dest; NAME TYPE VALUE --------------------------------------------------------- ------------------ ------------------------------ db_recovery_file_dest string F:\app\Administrator\flash_rec overy_area db_recovery_file_dest_size big integer 2G
参数db_recovery_file_dest的value值为F:\app\Administrator\flash_recovery_area,说明了数据库恢复文件目录的位置,而参数db_recovery_file_dest_size的value值为2G,说明该存储目录分配的磁盘空间大小。
2.6.6 校验点进程(CKPT)
首先介绍检验点,检验点是一个事件,当数据库写进程把SGA中所有被修改了的数据库高速缓存中的数据写到数据文件上时产生,这些被修改的数据包括已提交的和未提交的数据。由于引入了校验点,使得所有校验点的所有变化了的数据都写到数据文件中,在实例恢复时,就不必恢复校验点之前的重做日志中的数据,加快了系统恢复的效率。
校验点进程并不是用于建立校验点,只是在校验点发生时,会触发这个进程进行一系列工作。包括如下两点。
①校验点进程要将校验点号码写入相关的数据文件的文件头中。
②校验点进程把校验点号码、SCN号、重做日志序列号、归档日志名字等都写入控制文件。
图2-12是数据库校验点进程的工作示意图。

图2-12 数据库校验点进程
Oracle提供一个指令,用户可以强制产生校验点,使得用户可以干预校验点的产生,如下例所示。
例子2-23 强制执行校验点
SQL> alter system checkpoint;