话说实例恢复的时候需要用到UNDO里的数据,对此有些不明白. 既然有日志还需要UNDO表空间的数据,这对数据库只需要日志来恢复来说讽刺意义吗?
还说 REDO也保护了UNDO段的数据. 生成某个条目. 最后写到日志文件中. 写日志文件是根据3个条件去写的, 也就是说有些事务没提交也被写进了日志文件.
日志文件写满了要进行切换要激发CHECKPOING的进程. 要搞清楚ORACLE内存关系和机制还是蛮难的.
第一 回滚段存放在UNDO表空间里的数据文件中.
第二 要修改某个数据,必须把此数据所在数据文件的数据块 读到 内存中SGA里的BUFFER CACHE中.
第三 UPDATE此数据块的数据前, 要向回滚段申请数据块, 就是向回滚段的UNDO文件获得地址,并把该地址读到内存中
第四 把要UPDATE的数据块的前期影像 放到回滚段所在内存中的数据块. (不太清楚这个前期影像 只的是数据记录还是数据块)
第五 回滚段数据块的值 假设原来是空的, 现在变成了 5 . 那么就要生成一条 REDO记录 有的说是矢量或者是条目 中文解释太烂了
第六 把要修改的数据块中的记录 更新成新值为3,同时产生一条REDO 记录.
第七 该事务 未提交 . REDO BUF保存了该UPDATE行为的两条REDO记录 分别是 数据块和回滚段的改变量.
第八 REDO 写进日志文件.
第九 DBWRIT 没有写脏数据到数据文中
第十 没有发生CHECKPION事件.
第11 断电 丢失了部分REDO BUF的事务.
第12 启动进行实例恢复
第13 恢复根据日志文件的 CHECKPOINT 点以后的日志 重新做一遍 也就是执行一遍 INSERT 然后UPDATE
我们对UPDATE语句要修改的记录以前的值 不确定是多少, 通过日志重做 对应的回滚块插入值为 5 在内存中把数据文件的值UPDATE 成3
这样 现场得到了恢复.
第14 对已经提交的事务 进行提交, 对未提交的事务 进行回滚. 就是把数据文件块中的3值 改回成5.
最后 实例恢复并不需要UNDO表空间的数据,只需要相应的数据块地址 也就是数据块对象. 毕竟UNDO和回滚段 旧值会被覆盖的.