|
最初由 NinGoo 发布
[B]
你要考虑到并发
一个事务读入一个block,修改,commit,这是block还没有写回datafile,然后另外一个事务又修改这个
block,commit,还是没写回,另一个事务又修改。。。。
这么下去,你怎么比较SCN判断这个block要前滚到哪个时刻? [/B]
我并不是说要跟据scn来决定怎样回滚,不错,一个data block可以发生很多次tranction,但是在数据库
恢复的时候,应该是根据回滚段内容来选择数据块来回滚!!!
这样吧,我把我的思路一条条的列出来:
数据库发生崩溃时:
1.redo log 记录所有的已经提交的tranctions.
2.rollback segment file 中也记录tranctions(有已经提交的,也有没提交的),因为rollback
segment 不像redo log那样执行“立即写”的策略,所以在rollback segment中记录的tranctions 信
息并不是最新的。也就是说,有部分tranction可能没写入rollback segment file,或者有部分
tranction已经提交了,但是在rollback segment file中还是not commit的状态。
3.没有写入rollback segment file的tranctions,与这些tranctions想关的修改自然也没有写入到data
file。(因为先写rollback segment file,再写data file)。注意,我这里所说的修改指的是与这些
tranction相关的修改,有可能别的tranction(已写入rollback segment file的tranctions)也修改了这
些数据块,并且也完成了writed to disk。但是在data file 中的数据块不可能包含“没有写入rollback
segment file的tranctions”所产生的任何修改的。
4.在数据库恢复的时候,先从redo log中提取已经提交的tranctions的信息,然后对rollback segment
file中的tranction table进行处理,更新tranction table中已提交的tranctions和未提交的
tranctions信息.
5.对于已经提交的tranctions,使用redo file对与该tranctions相应数据块进行效验,必要时进行前
滚完成修改。
6. 对于rollback segment file中未提交的tranctions,使用rollback file中的信息对与该信息相关
联的数据块进行回滚。在这里我要指出,“与该信息相关联的数据块”可能需要回滚(崩溃前已经写
入disk的dirty block),可能不需要回滚(崩溃前没有write to disk的dirty block)。具体怎么操
作,可以通过回滚段数据与数据块数据进行比较来判定是否要回滚。(与回滚段数据一样的就不操作
,不一样的就回滚)
7.对于没有提交,也没有写入rollback segment file的tranctions,因为数据文件中没有产生相应的
修改,所以也就不需要处理。
8.可能有人要问怎么判断崩溃前有哪些rollback block已经写入disk,有哪些没写?这个可以根据
rollback block中的scn来判断。因为rollbakc block和data block不一样,一个rollback block只能
和一个tranction相关联。查找rollback segment file中未提交事务的scn,然后查找有这些scn标志
的rollbakc block就可以知道需要哪些rollbakc block来进行回滚。在rollbakc block中还会记录有
与这些回滚信息相关的数据块信息,所以通过这些rollbakc block可以找到相关联的data block。 |
|