2005-05-20:一篇关于Oracle与DB2精彩讨论

现在还看不懂。先Po下来留着慢慢看。他说精彩。肯定有他的道理

(转自:http://wh2000.spaces.live.com/Blog/cns!1pFIsXi-WI_k0U_mTp4GMfFw!109.entry

db2回滚处理问题

本人是DB2的初学者,和oracle,sybase,sql server作比较,发现在处理rollback时有些疑问,象oracle是有rollback segment,sybase和sql server有日志段,但在DB2中好象是找不到类似于oracle的rollback segment或者是sybase之类的日志段,是不是其恢复和rollback都是利用其日志文件来实现,因为好象其日志文件有primary和secondary之分,而且有整个日志文件大小限制,是不是这个大小限制也决定了其能rollback的程度,不知道理解是否正确,请指导。

--------------------------------------------------------------------------

你发现了DB2的一个大问题!

没错,DB2没有rollback segment,它只有log.
回退时使用的是online log.

你再往深处想想,这样一来缺省情况下DB2就失去了读一致性,可怕吧.
当然可以通过调整参数来强行保证读一致性,但又失去了并发性.

个人认为这是DB2的一个大缺陷!

--------------------------------------------------------------------------

呵呵,其实发现db2在某些方面还是不错的,特别是在大型处理方面,可以比较方便的把数据库分散到多个节点上,但这其实也存在一个问题,在Unix平台下,好象需要把实例的相关代码放在共享NFS磁盘上,这好象又增加了安全方面的考虑了

--------------------------------------------------------------------------

第一,任何由于日志空间满或主动roll back的交易,都可以被完整rollback;
第二,log file和读一致性没有关系。

一致性是可以通过isolation level解决,但这是以牺牲并发性为代价的.
DB2有四种隔离级别: 未提交读、游标稳定性(缺省)、读稳定性和可重复读. 未提交读的并发性最好,但是没有任何读一致性可言; 缺省的游标稳定性的并发性已经不如ORACLE(select 和update互相影响,ORACLE无此问题),而且读一致性也不能保证,其他两种级别应该可以保证读一致性,但并发性完全不可接受.
之所以银行可以用DB2有两个原因:
1.有些银行用的是390,机制不同
2.其他银行用UDB,但是银行和许多其他如电信等行业不同,对OLD IMAGE的要求不高,所以DB2的一致性和并发性的问题被掩盖.

这些问题我发现时也很疑惑,简直不敢相信.但我与IBM的资深工程师探讨过多次后,才一致共同确认DB2是存在此类缺陷.

这就是事情的经过,有些问题你光从DB2的角度看不出来,你如果能同时掌握DB2和ORACLE,就很容易看出来了.当然,以DB2的角度,ORACLE也不是没问题.

--------------------------------------------------------------------------

没错,ROLLBACK 是ORACLE特有的,但可能恰恰是它的一个极大优势,这个问题不展开了.
说到结构,ORACLE使用的是share-disk结构, 4节点共享一块存储;DB2使用的是share-nothing结构, 4节点分别拥有各自的存储.如果ORACLE的一个节点宕,对其他节点几乎没有影响.而DB2一般来说表空间分散在nodegoup上,而nodegroup一般根据应用要求往往会包含至少2个节点.这样一来,DB2的一个节点宕,在相关资源切换完之前会对nodegroup内其他节点的可用性带来严重冲击.尽管如果设计得好, 切换时间可以控制在分钟级,但一个节点宕会影响其他节点这一点令电信类关键应用很难接受.DB2的share-nothing结构的提出主要是为了保证可扩展性和IO吞吐.但在目前高端存储和SAN网络开始流行的情况下,该架构的优点已经失去,相反稳定性上的缺点开始暴露.对ORACLE来说正相反.

--------------------------------------------------------------------------

1. 很重要,除了uncommited read以外,不存在读一致性的问题,而这不是ur所能提供的。
2. 很少有(几乎没有)rr/rs的应用,正如你所说,并发行很差(包括oracle)。
3. Oracle采用data page(block)上记录ITL来控制并发,代价是增加磁盘的开销。
4. 不管哪种方式都有其利弊,从实践上看,Oracle的机制好一些,db2的应用碰到的并发问题很多都是因为从Oracle移植过来 ,不过移植是很痛苦的。
5. share-disk的问题不仅仅是IO吞吐,而是全局的锁,以及仅仅一个节点为请求工作。Oracle从未发布过比较好的/大的tpc-h cluster(RAC)测试。而这恰恰是SHARE-NOTHING的SCALABILITY的优势。我称之为inbeing 。
6. share-disk的可用性(inbeing)确实好,但不是宕机对其他节点没有影响,因为它涉及到remaster以及GCS重建 - 不知道10G有没有改进。DB2准备用Informix的HDR技术来解决这个问题。

--------------------------------------------------------------------------

很高兴与大家交流.由于时间关系很多观点我先不说了.
不过我想全局锁的问题,ORACLE9I的RAC比起原来的OPS来说,以我的实际经验来看,似乎确实长进不少.

实际上我现在的一个很强烈的感觉是:我不敢用DB2代替ORACLE.以前我曾经以为DB2可以,但自从我学DB2后就不敢了.我们电信业看重的是并发性能和稳定性,尤其是后者.考核也是很严的,可能外人会觉得不尽人情.在这种情况下,DB2的很多优点我都只能视而不见了,而稳定性和并发性上的缺陷对我而言几乎否定了DB2的一切.其实我还是就事论事纯粹讨论技术的,有些话我没有说,怕引起DB2爱好者的反感.实际上,DB2培训完之后,有ORACLE DBA说:'真想不到DB2这样一个具有如此致命缺陷的数据库竟然会有人感用!?连一致性都没有!?'实际上我当时也有类似想法,所以事后我才找IBM工程师探讨,谈了很多,谈到了390,还有IBM和银行业的关系,等等.后来我才明白DB2的许多特点(无论是优点还是缺点)是怎么来的.但现在我个人仍然认为在关键OLTP上,选择DB2类似于自杀,但在DSS或BATCH业务(如ERP和银行业务)上,DB2没问题.个人观点,欢迎指正.

--------------------------------------------------------------------------

现在单台服务器的oltp性能已经很好了,单台p690上db2已经可以跑到1,000,000 tpmC(Oracle在Superdome上也做到了)。

--------------------------------------------------------------------------

我前面已经说了,有些问题要对ORACLE和DB2都有了解之后才能发现.....
从我个人经验来说,别的不说,我几乎可以肯定ORACLE真正做到了一致性和并发性的平衡,DB2则在这一点上存在差距.这种差距是否致命各人有个人的看法,我从我的实际经验判断认为还是比较严重的.你怎么认为是你的事.你我也没必要强求一致.这些不要再纠缠了吧,该说的我前面的贴子都说了,多说也无益.

还有,所谓国外DB2市场DB2占用如何如何优势这种言论,不信也罢.这种数据商业气息太浓,你知道它是怎么统计出来的?什么平台上的?什么行业的?ORACLE和DB2都可以认为自己是老大,关键看是从哪个角度去统计,看谁的文字游戏和商业欺诈玩得出色,仅此而已.

具我所知,似乎还是IBM的文字游戏和商业欺诈更出色些.上次有家公司招标,该公司的人对数据库不了解,于是要求做测试,谁快选谁.一开始怎么测都是DB2快,ORACLE很不解.后来发现,你猜怎么着?原来DB2把许多参数都调了,许多必要的校验都去掉了,速度那个快啊,和飞似的.(怎么调的?比如我就知道把隔离级别降低不就是公开的一招吗?别的还有.不过ORACLE可是没有这种公开招数的.)后来ORACLE也联系老美,如法炮制加上了内部参数,结果速度也一样快.不知道后来那公司选的是什么.我说这些,是想让你明白,技术是技术,商业是商业,呵呵!

--------------------------------------------------------------------------

行了行了,别老是技术技术的,你们选用4节点的RAC,就说明你们根本不是认真从技术上考虑。我大概也可以猜到你是哪个公司的,4节点的RAC分明就是给ORACLE的商业手段给骗了,之前是否有成功的案例也没有仔细调查吧,而且没有先对选项做试验。当然IBM也这么玩,上次打算卖给我们的XPS,当然就直接找测试环境加应用测试,马上否决。
而且当时测试的还挺搞笑,因为用EMC的设备,EMC的一个销售(原来做ORACLE,而且据说做的挺高)偷偷低拉我过去说:“你们这么大的数据库,INFORMIX不行啊,干嘛不用ORACLE呢?如果在你们的库再大点,ORCLE也不行了,应该用DB2“。哈哈。

--------------------------------------------------------------------------

对于并发问题我基本可以得到结论了,DB2缺省的隔离级别游标稳定性是比CR(ORACLE的缺省隔离级别)高的隔离级别。由于两者的隔离级别不相同,最好参考INFORMIX这种既有CR也有游标稳定性的数据库的隔离级别就清楚了。
隔离级别高当然导致可能并发性能的下降,就这样简单而已,ORACLE和INFORMIX是提供了一个满足SQL-92标准的东西,可以有比较好的并发性,DB2可能还是考虑原来主要在金融领域的应用,试图增加一些东西提供更强的隔离级别,但是自然并发就下降了。
至于DB2无法保证读一致性,纯属胡说。
当然由于DB2缺省的隔离级别的问题,要提高性能,DB2建议对读也要进行提交

--------------------------------------------------------------------------

数据一致性的“及时性”是个人的看法,主要针对的异构数据库。
muti-transaction,snapshot,MQ等等其实都对异构数据库的数据一致性提出了的及时性的解决方案,因此,在这里应用了“数据一致性的及时性”一词,暂时还没有找到更好的词,呵呵。

http://www.51cmm.com/
《Gartner:数据质量低下致许多IT项目失败》

我理解,DB2多NODE模式的存在就是为了适应超大型的应用,而这种应用的“数据一致性”就是NODE需要解决的问题,而不是靠isolation level将nodes分割成为信息孤岛。斑竹提到的2 phase解决方式就是muti-transaction方式。


--------------------------------------------------------------------------

本人做了一个简单的对比,有不当的地方请DX指点

DB2 V8.11与ORACLE 9I RELEASE 2的区别
1
DB2的表中的列只可以添加,不可以删除,改名,并且只有VARCHAR类型的长度可以增加 udb V8.2可以改字段

名称,删除字段,字段类型转换等,但是有时会发生错误
ORACLE的表的列中可以添加,删除,改名,某些字段类型可以相互转换

2
DB2和ORACLE都可以预读
DB2:可以针对每个表空间设定不同的预读大小ALTER TABLESPACE USERSPACE1 PREFETCHSIZE 4;
ORACLE:通过参数修改DB_FILE_MULTIBLOCK_READ_COUNT来指定ORACLE实例的预读大小

3
DB2的页相当于ORACLE的DB BLOCK
DB2表的EXTENT大小是相等的,ORACLE表的EXTENT可以是不等的

4
DB2在建立表空间时可以指定页的大小,ORACLE的主DB BLOCK SIZE在建立数据库时确定以后不可以更改,但

是可以修改参数DB_N_CACHE_SIZE,然后建立从块大小的表空间

5
DB2可以建立系统管理和数据库管理的表空间,系统管理表空间可以自动扩展,但数据库管理表空间不能自

动扩展
ORACLE可以建立字典管理和本地管理的表空间都可以自动扩展

6
DB2只有一种被表空间使用的缓冲池可以被手工创建并且可以创建多个,一个表空间只能选用一个缓冲池,D

B2也有日志缓冲等其它缓冲池但不可以人为创建或手工设定,ORACLE有多种类型的缓冲池如日志缓冲池,字

典缓冲池,数据缓冲池,JAVA池,LARGE池都可以通过参数据设定其大小,但是每种缓冲池只有一个

7
DB2的表空间类型有普通类型,大类型,系统临时类型,用户临时类型的表空间
ORACLE的表空间有永久,临时,还原类型的表空间

8
DB2创建表时可以指定CLOB 或BLOB型字段属于某一个大型表空间,索引属于某一个数据库管理的表空间,其

它的列属于一个数据库管理表空间,并且这样的表只能使用数据库管理的表空间,只有数据库管理的表空间

中的表可以跨表空间,表建立以后将不能更改所属表空间,可以更改主索引名称
CONNECT TO XYFDB;
ALTER TABLE ADMINISTRATOR.E DROP PRIMARY KEY ADD CONSTRAINT IDAAA PRIMARY KEY ( A) ;
CONNECT RESET;

ORACLE创建表时可以将多个字段和索引按照值的范围自动的属于多个表空间,但是如果表中有LONG字段将

不支持此表成为分区表,并且ORACLE的表只能含有一个LONG型字段,可以更改所属表空间如
ALTER INDEX "XYF"."IDX_AAAAAA"
REBUILD
PARTITION "A"
TABLESPACE "USERS"
但是不可以更改索引的名称

9
ORACLE有回滚段,ORACLE的回滚依赖回滚段,前滚依赖日志,能够实现读一致性(注意与数据库不同版本特性

WORKSPACE的区别),实现高度的事务隔离,对于大事务要求大的回滚段,回滚段不够大有可能出现快照太旧

的错误,含有活动事务的日志可以被归档,而不会影响数据库的运行.
DB2没有回滚段,前滚回滚都依赖于日志,因此,含有活动事务的日志不可以成为脱机归档日志,如果主日志

写满,就产生附加的日志,如果附加日志有数量限制,达到限制后数据库将会被挂起.个人认为DB2存在读一

致性的问题,UNCOMMIT READ隔离级可以并发读取,但是是脏读,Read Stability隔离级不能做到高度的事务
隔离,Repeatable Read可以实现事务隔离,但是并发性受到限制。

如果有人对ORACLE的读一致性有疑惑可以看一看以下的例子:
下面是几个关于回滚段和死锁的事例:
有表:Test (id number(10)) 有记录1000000条
SQL> create table test (id number(10)) tablespace users;
表已创建。
SQL> begin
2 for i in 1..1000000 loop
3 insert into test values(i);
4 end loop;
5 commit;
6 end;
7 /
PL/SQL 过程已成功完成
一,大SELECT,小UPDATE
A会话----Select * from test;----设scn=101----执行时间09:10:11
B会话-----Update test set id=9999999 where id=1000000----设scn=102-----执行时间09:10:12
我们会发现B会话会在A会话前完成,A会话中显示的ID=100000是从回滚段中读取的,因为A会话在读到ID=1000000所在的BLOCK时发现BLOCK上有事务信息,因此要从回滚段中读,如果UPDATE在SELECT读到此BLOCK之前已经COMMIT,则SELECT 读到此BLOCK时发现其BLOCK上没有事务信息,但是会发现其BLICK的SCN比SELECT自己的SCN大,因此也会从回滚段中读取。因此是否从回滚段读一是看是否有事务信息,二是比较SCN大小。如果B会话在A会话结束前连续多次对同一条记录UPDATE并COMMIT,那么在回滚段中将记录多个“前映像”,而每个“前映像”中不但包括了原BLOCK的数据和SCN也记录了“前前映像”的回滚段地址,因此A会话在查询到被UPDATE过的BLOCK时,会根据BLOCK记录的回滚段的地址,找到回滚段中的“前映像”,发现这个“前映像”的SCN也比自己的大,因此将根据这个“前映像”中记录的“前前映像”的回滚段地址,在回滚段中找到“前前映像”,再与这个“前前映像”比较SCN,如果比自己小就读取,如果还比自己大,则重复以上步骤,直到找到比自己SCN小的“前…前映像”为止,如果找不到,就会报ORA-01555快照太旧这个错误。Oracle回滚段确保了事务的高度的隔离性。即只要回滚段足够大,那么一个SELECT不管执行多长,它读取的所有数据都将是在这条SELECT语句开始执行瞬间这个时间点的值,而不会被其它用户在SELECT读取期间对数据是做过修改而影响。
二、大UPDATE,小SELECT
A会话----Update test set id=1;----设scn=101----执行时间09:10:11
B会话-----select * from test where id=1000000----设scn=102-----执行时间09:10:12
我们会发现B会话会在A会话前完成,B会话中显示的ID=1000000是从BLOCK中直接读取的,因为B会话在读到ID=1000000所在的BLOCK时,A会话还没有来得及对其锁定,因此B会话既不会发现BLOCK上有事务信息,也不会发现BLOCK上的SCN比SELECT的大,因此会从BLOCK中直接读取,如果SELECT在UPDATE锁定此BLOCK后才发出,B会话读到此BLOCK时发现其BLOCK上有事务信息,因此会从回滚段中读取。

三、大UPDATE,小UPDATE
A会话----Update test set id=1;----设scn=101----执行时间09:10:11
B会话1-----Update test set id=999999 where id=1000000----设scn=102-----执行时间09:10:12
B会话2----- select * from test where id=2----设scn=103-----执行时间09:10:14
B会话3----- update test set id=3 where id=2----设scn=104-----执行时间09:10:15
我们会发现B会话1会完成,A会话将一直等待,因为B会话1会先于A会话锁定ID=1000000所在的BLOCK,并改写头部的事务信息,A会话在试图锁定此BLOCK时,发现其上有事务信息,将会一直等待B会话1事务结束后再行锁定, B会话2查询到的ID=2是从回滚段中读取的而不是从BLOCK中直接读出来的。因为A会话已将ID=2的BLOCK锁定,并写入了回滚段,从B会话3可以证明这一点,B会话3发出后,B会话3会收到死锁的信息,死锁的原因是A会话在等待B会话对ID=1000000所在的BLOCK解锁,现在B会话又在等待A会话对ID=2所在的BLOCK解锁,因此形成死锁,因此证明ID=2所在的BLOCK已被A会话锁定,然后A会话也会收到死锁的信息

--------------------------------------------------------------------------

并发性好不好和能否达到读一致性没有关系。
谈了这么多读一致性,也没有给出一个定义?没有定义的概念如何讨论?

ACID,数据库的重要理论之一
http://databases.about.com/od/speci...ucts/a/acid.htm

另外,日志只要写满,就可以被归档,日志满数据库不会被挂起,达到日志满的交易会被回滚,可以用参数设定日志满时block新的交易。另外,db2 v8支持无限日志。

--------------------------------------------------------------------------

那我们来看一看同样这三个实验在DB2中会有什么结果(将DB2命令行处理器的自动提交设为否)
DB2SET DB2OPTIONS=-c-
同样有表TEST(ID NUM(10,0))
有50000条记录,值是从1到50000

第一个大SELECT,小UPDATE
A会话----Select * from test;设执行时间09:10:11
B会话-----Update test set id=99999 where id=50000----设执行时间09:10:12
我的实验结果是B会话先完成,如果B会话不COMMIT,那么A的会话将永远不会结束,在显示到47767时停止运行,我想是由于B会话锁定了ID=50000所在页的原因,使得A会话无法锁定页而进入等待状态,(ORACLE不存在这个问题,它是从回滚段中读取的,以上已有详细说明)。正是由于DB2没有回滚段来提供一致性读视图而影响了DB2的并发,难道不是吗?如果一个用户一个月不COMMIT,那么所有SELECT这张表的用户都要等待,这也叫好的并发吗?
如果B会话在A会话读到最后一页之前COMMIT,则A会话可以完成,但是所显示的最后一个值是99999(与ORACLE不同,ORACLE仍然显示的是50000),从这里我们可以说DB2的读稳定性隔离级没有提供事务的高度隔离,(ORACLE可以真正提供基于一个时间点的状态值,而不受其它的影响)。DB2正是没有回滚段来提供一致性读才使用可重复读隔离级来阻止幻像读.

二、大UPDATE,小SELECT
A会话----Update test set id=1;----设执行时间09:10:11
B会话-----select * from test where id=1000000----设执行时间09:10:12
我们会发现B会话会永远也不会完成,除非A会话COMMIT,如果A会话忘了COMMIT,B会话的活还干不干了,这是不是影响并发?

三、大UPDATE,小UPDATE
第三个实验做不下去了,因为跟第二个同样的原因,A会话在COMMIT或ROLLBACK之前,B会话只有等

你可能感兴趣的:(oracle)