楼主: jiangzx

[精华] db2回滚处理问题

[复制链接]
论坛徽章:
1
121#
发表于 2005-11-30 15:00 | 只看该作者
学到东西了,我觉得ibm的商业手段有的时候用的多了一点,当然这也是生存之道。我相信在这个议题上面ibm&oralce之间也在互相学习,当然不至于有一点缺陷就不能用了,在编程面还是可以解决的,平台面只能靠理论和实践的发展迭代,有了不同我们才有了选择,这是我在交替使用db2/oracle的时候的小小体会。

使用道具 举报

回复
论坛徽章:
0
122#
发表于 2006-1-15 10:33 | 只看该作者
tks
谢谢各位的意见,让我对DB2的了解增加了一些,谢谢

使用道具 举报

回复
论坛徽章:
3
授权会员
日期:2006-02-05 11:03:26数据库板块每日发贴之星
日期:2006-02-10 01:02:41IBM软件技术精英协会成员
日期:2006-12-21 15:37:12
123#
发表于 2006-1-25 16:26 | 只看该作者
oracle 提供的一篇文章

cwp_9ivsdb2_perf.pdf

87.11 KB, 下载次数: 120

使用道具 举报

回复
论坛徽章:
3
授权会员
日期:2006-02-05 11:03:26数据库板块每日发贴之星
日期:2006-02-10 01:02:41IBM软件技术精英协会成员
日期:2006-12-21 15:37:12
124#
发表于 2006-1-25 17:20 | 只看该作者
从我使用db2的经验来看,db2的锁确实很多,尤其是当oltp业务和查询/打印报表同时做的时候,简直晕,后来的解决办法是,尽量把这两类的业务分时,并且把一些非关键的查询采用ur的隔离级别。

使用道具 举报

回复
论坛徽章:
0
125#
发表于 2006-1-29 05:08 | 只看该作者
各位老大过年好!

最初由 hannibal 发布
[B]...
oracle利用回滚段巧妙的避免了幻影读,但是有一个问题是oracle读出的数据当前可能是不正确的,oracle可以利用SCN找到最早的数据(注意这不是当前的数据),但他读出的数据是错误的。
...[/B]

hannibal 论述“oracle读出的数据当前可能是不正确的”的论据是“oracle可以利用SCN找到最早的数据(注意这不是当前的数据)”。这个论据是错误的,我的依据如下:
“Whenever a transaction is committed, LGWR writes the transaction redo records from the redo log buffer of the SGA to a redo log file, and assigns a system change number (SCN) to identify the redo records for each committed transaction.”(摘自Oracle联机文档 http://download-west.oracle.com/ ... 4231/onlineredo.htm)。无论多么小的事务,每次提交commit产生一个新SCN号。
“When the Oracle server begins executing a SELECT statement, it determines the current system change number (SCN) and ensures that any changes not committed before this SCN are not processed by the statement.”(摘自Oracle DBA教材) 。注意是“current”SCN ,不是hannibal 认为的“最早的”SCN。
假设多个查询发起时SCN不一样(不同时开始),而且多个查询发起之间出现了相关数据提交,即便多个查询同时结束,查询的结果也会不同,即,查询结果有多个版本。每个查询都查到自己发起那一时刻的一致性数据(每个查询发起时的数据快照),结果中没有未提交的数据,即,没有不一致数据。这就是Oracle“多版本读一致性”。所以,我的结论是Oracle读的是正确的数据。


最初由 cliser  发布
[B]...
oracle可以看到别人正在修改而没有提交“之前”的数据。......在oracle环境下,储户要查自己的存款,朋友正好在异地好给这个人存款,储户这时看到存款没有到,而实际上朋友正在存,储户就获得了虚假的信息,
...[/B]

“oracle可以看到别人正在修改而没有提交“之前”的数据。”意思正确,但是容易引起歧义,因为“之前”可以理解为“修改之前”和“提交之前”,“提交之前”的理解显然错了。建议表述为“Oracle可以看到别人‘正在修改而没有提交’的数据的原始值。”
cliser  的例子中,“朋友正在存”,还没有提交,显而易见,储户本来就不应该看到朋友的未提交存款,所以,Oracle提供的不是“虚假的信息”,是可以对账的正确信息,所以,cliser的“储户就获得了虚假的信息”的结论是错误的。
假设这时候储户看到了朋友的存款,但是朋友又取消了存款,这种情况下储户看到的信息才是虚假信息。Oracle默认设置下是不会读到虚假信息的,而DB2在允许读取未提交信息的状态下会读出虚假信息(脏读,UR)。顺便说一句,Oracle通过设置一些少用的参数,也可以实现DB2的功能,例如UR,当然UR不是什么好功能。

A用户修改数据但是没提交,B用户可以读修改前的数据,这是很多并发系统具有的特征。例1,你用PowerPoint打开一个文档正在修改没有关闭,当你再到资源管理器中打开一次时,PowerPoint就提示你以只读方式打开未修改的版本;例2,当你从文档管理软件(例如VisualSafe)中Check Out一个文档来修改,在你Check In之前,其他人只能只读这个文档的原始版本。

有一致的数据,就应该能被读出来,这是数据库应有的功能。如果不能被读出来,有什么好处呢?难道就是通知B用户有个用户正在改数据?

DB2, SQL Server, Sybase因为没有回退段,回退靠Log实现,结果Log争抢激烈,再加上读一致性要求,带来特别多锁问题,开发人员要手工管理复杂的锁机制。Oracle没有这些问题,用不着开发人员管理锁,全自动。据我了解,开发那些数据库人员换用Oracle后,都感觉像脚踏车换成摩托车,甚至有人说Oracle的缺点是很难蹬着跑,哈哈。

DB2等数据库之所以有这么多个隔离级别和锁设置,主要是没有回退段而带来的开发和管理复杂性提高,并发行和读一致性无法兼顾。Oracle有回退段,并发行和读一致性都能兼顾,所以没有这方面的复杂性。
DB2和Oracle之间的比较就好比脚踏车和摩托车比较。脚踏车轻便,但是费劲;摩托车省力,但是多了个发动机。如果骑两种车的条件都具备,多数人会选择哪种车呢?

使用道具 举报

回复
论坛徽章:
0
126#
发表于 2006-1-29 12:03 | 只看该作者
大家可以看看图了解一下Oracle多版本读一致性和其他数据库的区别。
Oracle多版本读一致性的功能:
读取查询开始一瞬间的一致数据,没有读取其他用户未提交数据的“脏读”(一种缺陷)。读不加锁。读、写互不阻碍。

不否认某些大事务把回退段耗尽,造成其他事务因无法读一致而报错。但是这种情况很罕见,而且可以通过调整回退段很容易解决。我们不能因噎废食,是吧。

multi-version_read_consistency.gif (15.68 KB, 下载次数: 169)

multi-version_read_consistency.gif

使用道具 举报

回复
论坛徽章:
2
授权会员
日期:2005-10-30 17:05:332011新春纪念徽章
日期:2011-02-18 11:43:33
127#
发表于 2006-2-1 10:18 | 只看该作者
请教个问题:
        我在9:00发起个查询A,共50000条记录,需要3分钟(其中张三的贵宾卡余额记录是最后一条,余额在9:00时是1000元),也就是说要9:03才能结束.如果张三在9:01刷卡,消费200元,也就是说在9:02时余额是800元.你说在查询A中看到的张三余额是1000还是800?

        机器有点慢,呵呵,大概是这个意思.

使用道具 举报

回复
论坛徽章:
0
128#
发表于 2006-2-4 19:08 | 只看该作者
最初由 cliser 发布
[B]        我在9:00发起个查询A,共50000条记录,需要3分钟(其中张三的贵宾卡余额记录是最后一条,余额在9:00时是1000元),也就是说要9:03才能结束.如果张三在9:01刷卡,消费200元,也就是说在9:02时余额是800元.你说在查询A中看到的张三余额是1000还是800?
[/B]


我上次提到“每个查询都查到自己发起那一时刻的一致性数据(每个查询发起时的数据快照)”,就是说Oracle的Select返回其开始执行一瞬间的数据快照(数据集),而不管这个Select执行了多长时间,不管期间其他会话(Session)如何修改数据,以及是否提交修改。换句话说,就是Select和其他会话隔离(Isolation)开了,执行期间不受其他会话的影响。

举个例子,你复制一个大文件,别人同时改这个文件,你希望自己复制的是9:00的前后一致的文件,还是有9:00、9:01和9:03混合内容的文件?文件前后不一致都可能打不开。放到数据库上,如果Select出来的数据前后不一致,数据可能无法使用。以你的这个50000条记录的表为例说明,假设Select和其他会话没有隔离开,执行一个自连接查询(一条记录的外键是另一条记录的主键),开头明明看到有条记录指向张三的1000元,过去一看变800了,这不就违反数据一致性了嘛。这是自连接的例子,外连接您可以自己设想一下。

隔离级别(Isolation Level)越高越好,但是隔离级别会越高并发性就可能越低。当达到常用的Read committed级别时,DB2、SQL Server、Sybase等并发性都会降低,而Oracle通过回退段巧妙的解决了这个问题,所以Oracle默认就是Read committed级别。

参考:
《Data Concurrency and Consistency》
http://download-west.oracle.com/ ... /b14220/consist.htm

《关于oracle怎么保证读一致性》(作者 biti)
http://biti_rainy.itpub.net/post/330/1641

《ORACLE的隔离级别》(作者 Parrotao)
http://epub.itpub.net/3/4.htm

使用道具 举报

回复
论坛徽章:
2
授权会员
日期:2005-10-30 17:05:332011新春纪念徽章
日期:2011-02-18 11:43:33
129#
发表于 2006-2-8 08:19 | 只看该作者
如何理解“数据一致性”?
    关键是数据库是否满足需求自己的需求!
    oracle的高并发性使以牺牲数据准确性为代价的,当查询要求的准确性不高的情况下是可以的。想想看,大家在9:00发起查询,你说你要的是9:00查询结果,还是想要9:03的结果,我想大多数人会要9:03的结果,Oracle查询的数据是不能反映当前真实情况的,当然这种情况对于实际来说,比较少见,对于一般的系统可以接受的。但Oracle的“数据一致性”对于严格要求是无法满足的。DB2,SYBASE,SQL SERVER的默认隔离级别要高于Oracle的默认级别,所以并发性要低于Oracle。
    “而Oracle通过回退段巧妙的解决了这个问题”,你如果仅仅是看查询开始的时间点的数据值,Oracle确实“巧妙”的解决了问题!但是如果我要的是查询结束后的结果,Oracle没有解决这个问题!关键是你的用户是否接受Oracle的查询出的结果可能不是最后的结果这一“瑕疵”,那么,Oracle比Db2,Sybase等的并发性要高!如果你的客户眼里容不得“沙子”,Oracle的并发性就和Db2等一样了。

    “举个例子,你复制一个大文件,别人同时改这个文件,你希望自己复制的是9:00的前后一致的文件,还是有9:00、9:01和9:03混合内容的文件?文件前后不一致都可能打不开。放到数据库上,如果Select出来的数据前后不一致,数据可能无法使用。以你的这个50000条记录的表为例说明,假设Select和其他会话没有隔离开,执行一个自连接查询(一条记录的外键是另一条记录的主键),开头明明看到有条记录指向张三的1000元,过去一看变800了,这不就违反数据一致性了嘛。这是自连接的例子,外连接您可以自己设想一下。”
     对于这个问题,DB2,SQLSERVER如果对这些5000条记录的查询用了“自连接”或“外连接”,会对这5000条记录加锁,禁止修改,保证查询的一致性,也就是并发性要降低,但是你看到的是最终结果,而不是发起查询时的结果。
       不管怎么说,如果用同一把尺子,同样的数据准确性上,oracle和db2等的并发性是一样的。这把尺子是客户的,不是你Oracle的,也不是Db2的。

使用道具 举报

回复
论坛徽章:
0
130#
发表于 2006-2-13 01:35 | 只看该作者
最初由 cliser 发布
[B]如何理解“数据一致性”?
关键是数据库是否满足需求自己的需求![/B]

“一致性”(Consistency) 是数据库理论中的一个名词,含义明确,怎么能因客户需求不同而理解不同呢?
一致性是数据库追求的目标之一,也是发明“事务”(Transaction)的主要原因。所谓一致性,就是数据必须符合数据库的规则(Rule)和完整性约束(Integrity Constraints),通俗讲就是数据都对的上。事务开始一刻、事务结束一刻和事务回退结束一刻的数据必须一致,事务内部的数据可以不一致,事务和事务之间的数据可以不一致。一条SELECT读出其他事务内部的数据(脏读)是语句级非一致读,读出不同事务的结果数据也是语句级非一致读。(为表述方便,后面的一致性和非一致性都是指语句级的。)

最初由 cliser 发布
[B]    oracle的高并发性使以牺牲数据准确性为代价的,当查询要求的准确性不高的情况下是可以的。想想看,大家在9:00发起查询,你说你要的是9:00查询结果,还是想要9:03的结果,我想大多数人会要9:03的结果,Oracle查询的数据是不能反映当前真实情况的,当然这种情况对于实际来说,比较少见,对于一般的系统可以接受的。
[/B]

cliser提到“准确性”,那我们看准确性。继续50000记录查询的例子,假设所有余额都是1000元,9:00开始查询所有余额,9:01管理员把所有记录改成800元,9:03查询结束。你觉得全是1000元的结果准确,还是1000元、800元混合结果准确?全是1000元叫“一致性”数据,反映了查询开始时间点的真实情况;全是1000元是9:00以前事务的结果,全是800元是9:01以后事务的结果,混在一起就是非一致性数据,非一致性数据反映了哪个时间点的真实情况?
如果按照cliser 越“反映当前真实情况”越好来推论,那么“脏读”就是最好的读,连人家正在修改数据的意图都读出来了。
理想的数据库是9:00开始查询并在一瞬间结束,返回的全是1000元。可惜世界上没有哪种数据库能在一瞬间作完查询,返回全是1000元结果就成为最接近于理想状况的实现。
读一致性是非常常见的需求,所有和数字相关的系统,例如,金融、ERP、库存、生产、人口等等,在查询时都尽可能避免非一致性读,因为非一致性读会出现对不上账、对不上物或者对不上人的混乱,大多数人会喜欢这种情况?所以常会见到“截至xxxx时间”的统计数据,截至时间之后的统计进行之中出现的数据变化是不能被读出来的。
我们不否认,不重要的数据允许非一致读。我们也不否认,非一致读在没有人修改数据的好运气下能读出一致性数据。

最初由 cliser 发布
[B]但Oracle的“数据一致性”对于严格要求是无法满足的。
[/B]

我上面已经论述了Oracle实现了一致性读,比非一致性读级别高。请问cliser所指“严格要求”是什么?

最初由 cliser 发布
[B]DB2,SYBASE,SQL SERVER的默认隔离级别要高于Oracle的默认级别,所以并发性要低于Oracle。
[/B]

(注:SYBASE和SQL Server是同宗数据库,不赘述)
Oracle默认隔离级别完全实现DB2默认隔离级别CS (Cursor Stability)和SQL SERVER默认隔离级别RC(READ COMMITTED),Oracle更胜一筹得是在保证并发性的前提下保证数据读一致性,类似DB2更高隔离级别RS(Read Stability, 比CS并发性低)。所以Oracle默认隔离级别更高,数据更准。
为什么有这个差异?因为数据库存取事务信息的结构不同,实现读一致性开销差别很大,DB2、SQL Server、Sybase主要靠日志存取事务信息,开销很大,所以他们都默认有事务一致性而没有读一致性;Oracle除了日志以外,还用回退段存取修改前的数据,开销较小,所以默认有事务一致性和读一致性。

只引用Oracle和ITPub的文章让人觉得有失公允,那我们看Oracle的竞争对手MS的文章。SQL SERVER已经意识到默认隔离级别RC的不足,在SQL SERVER 2005中新增重要特性 快照隔离(SNAPSHOT Isolation),模拟Oracle默认隔离级别,参阅MS官方  http://www.microsoft.com/china/t ... ql/2005/sql05b.mspx ,文中也提到RC的不足——“并不能保证读取一致性”,快照隔离在RC的基础上又增加“非阻碍、非锁定和语句级的读取一致性”,[B]这和Oracle一样[/B],和Oracle不一样的是它会降低很多性能,而且注意事项很多,所以MS推荐“在没有审慎的考虑和具备很多最佳做法之前,不应选择实施这种做法。”

最初由 cliser 发布
[B]但是如果我要的是查询结束后的结果,Oracle没有解决这个问题!
[/B]

如果“要的是查询结束后的结果”,应该在9:03再读一次,9:01的读是幻像读(Phantom reads)。DB2,SYBASE,SQL SERVER和Oracle的默认隔离级别都不能避免幻像读。

最初由 cliser 发布
[B]关键是你的用户是否接受Oracle的查询出的结果可能不是最后的结果这一“瑕疵”,
[/B]

一致性是数据库追求的目标,怎么能称为“瑕疵”?

最初由 cliser 发布
[B]     DB2,SQLSERVER如果对这些5000条记录的查询用了“自连接”或“外连接”,会对这5000条记录加锁,禁止修改,保证查询的一致性,也就是并发性要降低,但是你看到的是最终结果,而不是发起查询时的结果。
[/B]

DB2,SQL SERVER的提高隔离级别,降低并发性后,查询“对这5000条记录 (cliser笔误,应是50000条记录) 加锁,禁止修改”,查出来的就是9:00的一致数据,不是和Oracle默认隔离级别查出来的一样吗,你觉得哪个好?

最初由 cliser 发布
[B]       不管怎么说,如果用同一把尺子,同样的数据准确性上,oracle和db2等的并发性是一样的。这把尺子是客户的,不是你Oracle的,也不是Db2的。 [/B]

从前面我的论述可以看出,默认隔离级别下,Oracle数据更准确,而且由于Oracle读、写互不影响,并发性更高。“尺子是客户的”,但是度量单位是国际统一的,量出哪个好就用哪个呗。

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表