我正在研究一些 DBA 的东西,我遇到过实例故障/恢复。
假设用户 A执行 DML,用户 B也执行 DML。
在这一点上,我相信可以安全地假设 DB 缓冲区缓存包含更改的表块和撤消段,并且日志缓冲区包含新表块值和新撤消段值的重做信息。
情况 1:没有用户发出 a
COMMIT
并且 DBWn 和实例崩溃没有写入磁盘。结果:数据库未损坏。就好像他们的 DML 从未发生过一样。情况 2:只有用户 A发出 a
COMMIT
。用户 B未提交的更改被写入磁盘,然后实例崩溃。LGWR 将在重做日志中写入足够的数据,尤其是用户 B的撤消段,以便恢复的回滚阶段使数据库再次保持一致情况 3:没有用户发出 a
COMMIT
但他们更改的表块已经足够旧,可以让 DBWn 将它们写入磁盘。然后砰!实例崩溃。如何SMON
执行回滚以清除此处数据文件中的脏块?特别是因为这里的重做日志中没有它们的撤消段值。
脏块只有在该块的修改时间之前的所有更改都已写入重做日志时才能写入磁盘。Oracle 12g2 数据库概念指南说
因此,在恢复数据库后,它包含直到特定时间的所有修改,并且没有在此时间之后进行的修改。如果事务已提交,则重做日志包含对其事务的修改,因此在恢复期间将其修改写入数据文件。未提交的事务要么只修改了内存结构(缓冲区缓存),因此所有修改都因崩溃而丢失,或者他们对文件进行了一些修改,但随后撤消信息也写入了包含撤消的文件段和此撤消信息将用于撤消此事务的更改。
情况 3: 如果数据文件的一个脏块被写回磁盘,那么在该块修改之前所做的所有更改都已经在重做日志中,因此撤消信息已经在重做日志中
情况 1:如果没有用户发出提交,并不意味着更改已写入数据文件或重做日志。但是,如果某些内容已写入磁盘,则可以如上所述将其撤消。
情况 2:不得将未提交的更改写入磁盘。仅保证将提交的更改写入磁盘。