暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

数据的一致性

原创 水煮鱼 2022-07-06
268

例:有ABCD4个账户,A账户1000元,B账户2000元,C账户3000元,D账户4000元

在8点的时候查询这4个账户的总额,由于数据查询及其缓慢,在8点20的时候账户A转了500到账户D,在8点30的时候读到账户D,那么这个时候读出来的账户D是4500还是4000?答案是4000。

了解两点:

1、SCN,全称System Change Number,这是一个只会增加不会减少的数字,存在于最小单位块里,当块改变时SCN会递增。

2、数据库的回滚段记录事务槽,当更新的某块,事务就会被写进事务槽,如果未提交或者回滚,该块就存在活动事务,数据库读到此块时就可以识别这种情况。

在8点的时候开始查询数据库,这个时候会获取8点的SCN并记录下来,这个时候8点的SCN8:00一定大于或等于记录在所有数据库头部的ITL槽中的SCN,读取数据的过程中如果ABCD四个账户均未更新,那个这四个账户的SCN一定小于SCN8:00,这个时候可以放心读数据。如果在8点20的时候账户D发生了变动,那么这个时候账户D的ITL槽中的SCN变为SCN8:20,当查询时发现大于SCN8:00,说明这个块有更新,于是根据ITL槽中记录了对应的undo块的地址找到undo块,将undo块中被修改前的数据(4000)取出,从而构建出被更新之前的数据。此外虽然账户A的块的SCN也变成了8:20,不过由于之前已经读过,所以不会回头去读,数据依然是1000。

如果在9点开始读,那么SCN9:00大于其他的SCN,读取的数据是500+2000+3000+4500,正确。

另外如果账户A在7点30被修改为500,但是未提交,虽然SCN8:00大于SCN7:30,但是由于oracle会发现这个块有活动事务,还是会去回滚段找之前的镜像数据1000。

由于回滚段数据不会一直保留,有可能1000这个数据被覆盖了,那么这个时候将会以

“ORA-01555”的报错而终止退出,查询失败。

因此ORACLE在做一致性读的时候,首先看发起的SCN是否大于当前查询块的SCN,如果小于则直接从回滚段取数据,如果大于,还要确保该块没有活动事务,否则还要去镜像中找数据。

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论