4.4 再议实例的启动和关闭
当我们发出startup命令启动实例时,整个实例的启动过程分为三个阶段:
⊙ nomount阶段
如果指定了pfile选项,则打开所指定的pfile;否则,到默认目录中找默认的spfile或pfile,并打开找到的初始化参数文件。根据参数文件里记录的参数值,启动数据库实例。同时,在该阶段,还会打开告警日志文件,也就是alert<SID>.log文件。如果SID为ora10g,则告警日志文件为alertora10g,该文件位于初始化参数background_dump_dest所指定的目录下。
通过startup nomount命令可以进入该阶段。启动到该阶段时,我们可以重建控制文件。
⊙ mount阶段
找到初始化参数文件里所记录的参数:control_files,根据该参数所记录的控制文件的路径以及名称,找到所有的控制文件(因为该参数可以指定多个控制文件),然后打开所有的控制文件。只要有一个控制文件无法打开,或文件格式损坏,就不能进入mount阶段。成功打开所有的控制文件以后,获取控制文件中所记录的数据文件和联机日志文件的路径及名称,但是不会校验这些文件是否都存在。
通过alter database mount命令从nomount阶段进入该阶段。启动到该阶段时,我们可以进行数据文件或联机日志文件的转移、对数据库进行还原和恢复、启动归档等操作。
注 意 所谓mount,指的是将实例与数据库物理文件关联的过程。
⊙ open阶段
根据控制文件里所记录的路径及名称,打开所有的数据文件和联机日志文件。只要有一个文件不能打开,就不能进入该阶段。实例打开后,整个数据库服务器就能对外提供服务了。
通过alter database open命令从mount阶段进入该阶段。或者在执行startup命令时,不指定具体阶段,则进入open阶段。
如果我们指定了启动到某个阶段时,则必须一个阶段一个阶段地往上走,不能跳。比如,如果我们发出startup nomount命令,将实例启动到nomount阶段,则这时就我们不能跳过mount阶段直接进入open阶段,必须先到mount阶段,再到open阶段。
对于我们发出shutdown命令关闭数据库实例来说,就不像startup那样可以进入不同的阶段。只要我们发出了shutdown命令,就会把数据库关闭。但是,对于shutdown来说,后面可以跟四个不同的选项,从而表示四种不同的关闭方式,如下所示。其中normal为默认关闭方式:
shutdown [normal | transactional | immediate | abort]
一旦我们发出shutdown命令,不管后面跟什么选项,都不允许再建立新的到数据库的连接。
⊙ abort选项
如果发出shutdown abort命令,则就相当于模拟了数据库服务器突然断电的情况。这时,实例所在的内存立即被清空。实例里所含有的数据都还没有来得及写入数据文件。如果这时有某些事务正在运行,则这些事务被立即中断。这些被中断的事务既没有提交也没有回滚,处于中间状态。
⊙ immediate选项
如果发出shutdown immediate命令,则Oracle会强制中断当前正在运行的所有事务,并回滚这些事务;回滚完毕以后,强行中断当前正处于连接状态的用户;将实例里所有的数据都写入数据文件;做完这些事情以后,将实例所占的内存清空。
⊙ transactional选项
如果发出shutdown transactional命令,则Oracle会等待当前正在运行的事务主动提交或回滚;当所有的事务都主动结束(提交或回滚)以后,则强行中断当前正处于连接状态的用户;将实例里所有的数据都写入数据文件;做完这些事情以后,将实例所占的内存清空。因此,如果用户对事务始终都不提交或回滚,则实例是无法被关闭的。
⊙ normal选项
如果发出shutdown或者shutdown normal命令,则Oracle不仅会等当前正在运行的事务主动提交或回滚,而且还会等当前正处于连接状态的所有用户都主动断开连接。只要有一个用户不主动断开连接,实例就无法关闭。
很明显,abort关闭数据库速度最快,normal则最慢,transactional较慢,而immediate则较快。
对于非abort选项关闭的实例来说,数据库都会触发一个完全的检查点(checkpoint),从而将内存里所有的数据都更新到数据文件里。因此关闭以后的数据库体现了关闭时的数据状态,我们称这样的数据库为干净的数据库,也叫作一致的数据库。所谓的一致就是指当前数据库里的数据与实例关闭时内存中所含有的数据是一致的。下次启动数据库时,直接打开数据库即可,不需要进行恢复。
而对于abort选项关闭实例或startup force(这相当于shutdown abort再startup),或者由于掉电、硬件故障、软件故障等而导致实例突然消失,这时数据库还来不及进行完全的检查点。因此这时实例中最新的数据可能还来不及更新到数据文件里去,数据库就关闭了。也就是说,这时数据文件里所含有的数据与实例关闭时,内存里所含有的数据是不一致的,这样关闭以后的数据库叫做脏的数据库,也叫作不一致的数据库。下次启动数据库时,SMON进程要进行实例恢复,恢复完毕以后才能打开数据库。实例恢复的具体过程会在第5章进行深入探讨。
因此,可以看出,我们应该尽量正常关闭数据库,一般采用shutdown immediate命令。因为这样做,我们既可以获得一个关闭后干净的数据库,关闭的速度也会比较快。