我的oracle笔记-01 之 MVCC协议

好吧,现在做回文艺青年。

我决定把自己对ORACLE MVCC的了解分享出来,毕竟前期折腾了这么长时间,现在算是利用一下剩余价值吧。其实你如果要做一些多用户环境下的数据管理,数据库中的许多技术都值得你去借鉴,尽管你不一定需要ACIDMVCC就是这样一种技术,它可以在保证数据一致性的同时,实现最大的并发。其实我觉得ORACLE中最有价值的就是MVCCRAC,至于其它的,都属于“强者更强”的自然发展吧。

试图用最直白的自然语言把MVCC说清楚,对我来说可不是一件容易的事情,但我仍然对当年研究DSI时的痛苦记忆尤深,希望我的介绍对大家有所帮助,毕竟DSI是写给SUPPORT看的,更多的时候,它只是告诉你How,而不是Why

从协议上看,MVCC很简单,就是你总是只能看到数据库在某个时间点的状态(ReadConsistencyRC),而不管其后那些数据是否发生了更新,所以实际上你是看到了数据的某个历史版本,在ORACLE中,这个点就是你(事务)开始的时间,这样我们就实现了所谓的读写并行,也就是你的读总是能成功(而且你每次读到的都是同一个数据),即使数据正在被人更新(因为你们其实操作的是不同的版本)。

然而任何好处都必须有代价,不是吗。你所付出的代价就是所谓的写写串行,没错,写被严格串行了,记住,尽管你可以读取数据的任意历史版本,但写只会作用于数据的当前版本,或者叫最新版本。所谓写写串行,就是说如果在你开始事务和写数据之间,数据已经被其它人改了,或者说得准确点,当你看到的版本不是当前版本时,You Are Killed(事务回滚)。所以你会注意到,ORACLE本质上并不适合于写写冲突剧烈的应用(听到这,DB2笑了)。

为了更准确地描述协议,我们需要引入一个关于时间点的术语,SCN,关于SCN,有人叫它SystemChange Number,也有人叫System Commit Number,好吧,我并不在意这个。SCN机就是一种时间序,系统会维护一个GlobalSCN表示当前的时间,每个事务开始时(严格地说,是你开始发出第一条SQL时),你会获得当前时间,那就是你能够看到的时间,ORACLE中,这个时间叫做快照时间(SnapshotSCN),也就是说,就好像你在这个时候给数据库排了个快照。当事务提交的时候,你会获取当前时间并把GlobalSCN+1,这个时间叫做提交时间(CommitSCN)。当你更新数据时,你会产生一个新的版本,并把你的CommitSCN赋给这个版本(注意这里的语病,实际上这时候你还没有拿到CommitSCN,好吧,这个问题我们以后再说)。

所以事务有快照SCN和提交SCN,数据也有SCN,接下来我们可以准确地定义ORACLEMVCC

关于读,你能够看到这个数据,如果:

   1)它是你自己的更新,或者

   2)它是已经提交的数据,并且SCN <=你的SnapshotSCN

关于写,你能够更新这个数据,如果:

   1)它是最新的,并且

       2.1)它是你自己的更新,或者

       2.2)它是已提交的数据,并且SCN <=你的SnapshotSCN

前面说到,在关于写写串行中,如果你看到的版本不是当前版本,你会被Killed。好吧,我承认这样说对ORACLE不公平,事实上有两点:1)如果当前版本尚未提交,那么你可以等待,如果那个事务最后回滚了,那么你有很大的机会能过关。2ORACLE实际上定义了两个时间点,或者说两种隔离级别,一种是事务级RC,也就是你只能看到本事务开始时数据库的状态,另一种是语句级RC,你只能看到本条语句开始时数据库的状态,在语句级RC中,在你被Killed之前,你可以重启当前语句,于是你便获得了一个更大的SnapshotSCN(比那个数据的SCN更大),然后再试一次,你过关了。

所以感谢上帝,在ORACLE中,除非你特别指定,否则你总是在语句级RC中幸福地徜徉,因此只要你愿意不断地去重试(如果我们不去考虑重启的代价),事实上我们就实现了一种理论上最佳的并发协议,事务永不Killed

但是现实总是残酷的,再好的协议,落地的时候总是会.....

好吧,先说到这吧,我得准备下周一和用户交流的PPT去了,这周看来是没什么时间了。

转载自:http://blog.sina.com.cn/s/blog_d3bf72ff0101nrhy.html

你可能感兴趣的:(我的oracle笔记-01 之 MVCC协议)