前面提到过Oracle数据库的四种方式,分别是 shutdown
、nomount
、mount
和 open
,对应着数据库从关闭状态到启动状态的四种形式。
而数据库进行关闭时,同样有四种关闭方式。分别是 abort
、immediate
、normal
和 transactional
。
官方提供的 shutdown
的语法为:
SHUTDOWN [ABORT | IMMEDIATE | NORMAL | TRANSACTIONAL [LOCAL]]
在Oracle数据库中,如果需要关闭一个正在运行的数据库实例,可以选择将数据库 closing(关闭)
并且 dismounting(卸载)
。而如果数据库是一个可插拔容器数据库的实例,那么当通过 shutdown
关闭数据库时则只会关闭可插拔数据库,数据库实例仍然会保持运行状态。
根据 shutdown
参数的不同,数据库对于关闭数据库实例时的处理逻辑也会不同。例如,shutdown normal
和 shutdown transactional
则会等待一段时间,给予数据库处理当前已连接的用户的请求,直到处理结束已连接用户的请求后进行关闭数据库的操作。当数据库中仍存在用户进程时,shutdown
命令会处于阻塞状态(有时间限制)直到用户会话完全断开。
倘若在执行 shutdown
后所有的用户请求都被阻塞了,这个时候数据库并不会关闭,而是会返回一个 ORA-01013 的错误。
ORA-01013: user requested cancel of current operation
以下部分为四种关闭数据库处理的逻辑
ABORT
abort
方式为关闭数据库最快速的方式,但是关闭数据库时并不会等待用户进程断开连接,这个时候,尽管数据库会拒绝新产生的用户请求进程,但数据库中可能还存在之前已经建立的用户进程,或者用户请求的事务未提交、或数据库已提交的数据尚未写入到存储设备中等等情况。
这种方式关闭数据库时,未提交的事务并不会进行回滚,已连接到数据库的用户请求会被 terminated(中断)
。并且通过 abort
方式关闭的数据库,在数据库下一次启动时需要做 Instance Recovery(实例恢复)
。
关闭数据库的方式危险较大,通常使用在数据库某些后台进程异常退出的场景下。
IMMEIDATE
immediate
方式关闭数据库与 abort
方式类似,新的数据库连接都不被允许,也不允许产生新的事务。不同的是,shutdown immediate
方式处理关闭数据库时,会将数据库中未提交部分的事务进行回滚。
正因为 immediate
方式关闭数据库时对未提交的事务进行了回滚,下一次数据库实例启动时不用进行实例恢复。
如果关闭数据库时库中有大量长事务存在,immediate
方式的关闭也不会很高。
NORMAL
normal
方式时Oracle关闭数据库的默认选项,这种方式关闭数据库时会等待用户会话从数据库断开连接后,此时数据库不再接受新的用户进程连接的请求,且数据库的请求会得到处理,未提交的事务会被回滚。
也因此,数据库下一次启动时无须进行实例恢复。
这种方式属于安全的方式,但因其关闭数据库时需要等待用户进程断开与数据库的连接,因此关闭数据库的时间相对较长。
TRANSACTIONAL
transactional
方式更像是一种定时任务式的关闭,正如 transactional
意为事务型。使用这种方式关闭数据库时,新连接到数据库的用户进程会被断开,对于已连接到数据库的用户并不会等待用户进程完全退出,而是当数据库中的事务被完全处理结束的时候,直接关闭数据库,可能这个时候数据库中仍然存在用户未释放的连接。
这种方式关闭数据库,可以有效防止数据库中丢失数据,因为数据库的关闭是在数据库中的所有事务处理结束后进行的。且无需用户断开与数据库的连接。数据库下一次启动时也不需要进行实例恢复。
transactional local
模式则指定仅当本节点的事务处理结束后进行数据库的关闭操作,而不是等待所有的数据库事务处理结束。