未提交事务所修改的数据块会不会被写回磁盘

我是这样理解的:
(1)实例恢复的时候跑日志是从控制文件中记录的LRBA一直到日志的最后一条记录
(2)增量检查点发生的时候会将检查点队列中第一个脏块的LRBA地址记录到控制文件中
假设这样一种情况:
        一个未提交的事务修改了一个数据块,这个数据块被放到检查点队列中,这时候DBWR把这个脏块写回磁盘了,这个块就变成干净的了,这个脏块会被从检查点队列中移除,控制文件中记录的那个LRBA地址被更新,如果此时实例崩溃了,那么跑日志的时候这个脏块就不会被构造出来,因为它的LRBA地址在控制文件记录的那个LRBA地址之前。这样的话,岂不是那个未提交事务所做的修改不就永久的生效了吗。我就是想不明白这一点,望高手解答!
标签: 暂无标签
寻水的鱼

写了  篇文章,拥有财富 ,被  人关注

转播转播 分享分享 分享淘帖
回复

使用道具

P4 | 发表于 2015-8-18 10:22:16
我也正纳闷着个问题,怎么没高手回答?

补充内容 (2015-8-18 11:32):
我认为是有这种可能的。我是这样分析的:首先如果发生了COMMIT,一定会发生REDOLOG BUFFER的数据写入到REDOLOG FILE中,如果是没有发生COMMIT,那么REDOLOG BUFFER中的数据有可能会写到REDOLOG FILE中,也有可能不会写到REDOLOG FILE中,也就是说REDOLOG BUFFER写入REDOLOG FILE也有可能是其它原因的,如REDOLOG BUFFER使用超过三分之一等等。其次:如果DATA BUFFER 中的脏数据要写入磁盘,一定是这个脏数据块对应的在REDOLOG BUFFER中的日记记录已经写入到REDOLOG FILE中,或者说如果DATA BUFFER 的脏数据对应的REDOLOG BUFFER中的日记记录没有写到REDOLOG FIEL中,这个脏数据是不可能写到磁盘的,否则ORACLE无法保证提交后的数据不发生丢失。这两种情况我想应该是肯定的。基于以上两点,可能会出现第三种情况:当REDOLOG BUFFER的日记记录由于其它原因而非COMMIT(如日记超过了1M等)写入到了REDOLOG FILE中,而此时DATA BUFFER中的缓存由于种种原因(如脏缓冲区的数量超过阈值),这个时候ORACLE不得不触发DBWR,把脏数据写回到磁盘。同时由于这个脏数据块对应的日记记录已经写入REDOLOG FILE中,因此这个脏数据也有可能会写入磁盘。但是问题来了:如果此时事务正好要回滚怎么办呢?由于脏数据变成了干净数据。我是这么想的,但不能十分确定:事务没有提交,UNDO段始终保留了这个块在修改前的数据,虽然这个块已经变成了干净块,只要事物没提交,这个UNDO数据始终是在UNDO段中的,而且是不能被覆盖,也不能被回收的。如果要回滚,首先把UNDO段保留的数据块写回到这个干净块,干净块又变成了脏数据块,或者构造出了个全新的脏数据块。在这个过程中还会在REDOLOG BUFFER中产生日记。此时磁盘中保留着的数据块保留着修改后的数据,UNDO段中的数据块和DATA BUFFER中的脏数据反而保留着修改前的数据。当DATA BUFFER中的脏数据对应的日记记录在写入REDOLOG FILE中后,DATA BUFER的这个脏数据块(保留着修改前的数据)在适当的时候触发DBWR,又写回磁盘,磁盘中又回到了修改之前的数据,DATA BUFFER的脏数据块又变成了干净块,同时释放UNDO段,即修改位于这个事务所在的UNDO段第一个块的事务表中(1~47个)对应的XID中的FLAG标志,这样这个事务表的这个记录可以被下一个事务覆盖。因此,第一次把脏数据写入到磁盘的行为是无效的,降低了IO性能?不知道ORACLE在这方便设计上是否有问题?不知道对不对?请高手指点!
回复

使用道具

P4 | 发表于 2015-8-27 09:06:39
我想那些未提交事务修改的数据块虽然被写到磁盘了,在提交之前,数据块挂了,下次启动的时候这些数据块应该是会被回滚的,要不然就不对了,但就是不知道什么时候或者说在什么情况下会回滚。
回复

使用道具

您需要登录后才可以回帖 登录 | 加入社区

本版积分规则

意见
反馈