- 浏览: 87698 次
- 性别:
- 来自: 广州
文章分类
最新评论
-
zuowoziji123:
跟thinking in java里写的一模一样 晕
匿名内部类的初始化 -
hbyandy:
...
组合模式 -
speedup:
jvmlover 写道zwzm85 写道淘宝研究生是6k--8 ...
阿里巴巴和淘宝的校园应聘经历 -
sdh5724:
30以后的技术人员才是真正的在玩技术, 公司投资那么多IT设备 ...
阿里巴巴和淘宝的校园应聘经历 -
former:
我觉得:
"30岁转行"这句话也许你没有说 ...
阿里巴巴和淘宝的校园应聘经历
9.4.6 日志竞争
l redo放在一个慢速设备上:磁盘表现不佳。该购买速度更快的磁盘了。
l redo与其他频繁访问的文件放在同一个设备上。redo设计为要采用顺序写,而且要放在专用的设备上。如果系统的其他组件(甚至其他Oracle组件)试图与LGWR同时读写这个设备,你就会遭遇某种程度的竞争。在此,只要有可能,你就会希望确保LGWR拥有这些设备的独占访问权限。
l 已缓冲方式装载日志设备。你在使用一个“cooked”文件系统(而不是RAW磁盘)。操作系统在缓冲数据,而数据库也在缓冲数据(重做日志缓冲区)。这种双缓冲会让速度慢下来。如果可能,应该以一种“直接”方式了装载设备。具体操作依据操作系统和设备的不同而有所变化,但一般都可以直接装载。
l redo采用了一种慢速技术,如RAID-5。RAID-5很合适读,但是用于写时表现则很差。前面已经了解了COMMIT期间会发生什么,我们必须等待LGWR以确保数据写到磁盘上。倘若使用的技术会导致这个工作变慢,这就不是一个好主意。
9.4.7 临时表和redo/undo
临时表不会为它们的块生成redo。因此,对临时表的操作不是“可恢复的” 。修改临时表中的一个块时,不会将这个修改记录到重做日志文件中。不过,临时表确实会生成 undo,而且这个 undo 会计入日志。因此,临时表也会生成一些redo。初看上去好像没有道理:为什么需要生成undo?这是因为你能回滚到事务中的一个 SAVEPOINT。由于undo数据必须建立日志,因此临时表会为所生成的undo生成一些重做日志。这样似乎很不好,不过没有你想像中那么糟糕。在临时表上运行的 SQL 语句主要是 INSERT 和SELECT。幸运的是,INSERT 只生成极少的 undo(需要把块恢复为插入前的“没有”状态,而存储“没有”不需要多少空间),另外SELECT根本不生成undo。
注意:
l 对“实际”表(永久表)的 INSERT 生成了大量 redo。而对临时表几乎没有生成任何 redo。这是有道理的,对临时表的INSERT只会生成很少的undo数据,而且对于临时表只会为undo数据建立日志。
l 实际表的UPDATE生成的redo大约是临时表更新所生成redo的两倍。同样,这也是合理的。必须保存UPDATE的大约一半(即“前映像”)。对于临时表来说,不必保存“后映像”(redo)。
l DELETE 需要几乎相同的redo空间。这是有道理的,因为对DELETE的 undo很大,而对已修改块的redo很小。因此,对临时表的DELETE与对永久表的DELETE几乎相同。
因此,关于临时表上的DML 活动,可以得出以下一般结论:
l INSERT 会生成很少甚至不生成undo/redo活动。
l DELETE 在临时表上生成的redo与正常表上生成的redo同样多。
l 临时表的UPDATE会生成正常表UPDATE一半的redo。
有了以上了解,你可能会避免删除临时表。 可以使用TRUNCATE (当然要记住, TRUNCATE是 DDL,而 DDL 会提交事务,而且在 Oracle9i 及以前版本中,TRUNCATE 还会使你的游标失效) ,或者只是让临时表在 COMMIT 之后或会话终止时自动置空。执行方法不会生成 undo,相应地也不会生成 redo。你可能会尽量避免更新临时表,除非由于某种原因必须这样做。你会把临时表主要用于插入(INSERT)和选择(SELECT) 。采用这种方式,就能更优地使用临时表不生成redo的特有能力。
9.5分析 undo
9.5.1什么操作会生成最多和最少的 undo?
一般来讲,INSERT 生成的 undo 最少,因为 Oracle 为此需记录的只是要“删除”的一个rowid(行ID) 。UPDATE 一般排名第二(在大多数情况下)。DELETE生成的 undo最多。与加索引列的更新相比,对一个未加索引的列进行更新不仅执行得更快,生成的 undo 也会好得多。而更新有索引的列则可能生成大量的undo,因为索引结构本身所固有的复杂性,而且我们更新了这个表中的每一行,移动了这个结构中的索引键值。
9.5.2 ORA-01555: snapshot too old错误
注意 ORA-01555 与数据破坏或数据丢失毫无关系。在这方面,这是一个“安全”的错误;惟一的影响是:接收到这个错误的查询无法继续处理。
这个错误实际上很直接,其实只有两个原因,但是其中之一有一个特例,而且这种特例情况发生得如此频繁,所以我要说存在3 个原因:
l undo段太小,不足以在系统上执行工作。
l 你的程序跨COMMIT 获取(实际上这是前一点的一个变体)。我们在上一章讨论了这种情况。
l 块清除。
在充分说明这三种情况之前,我想先与你分享ORA-01555错误的几种解决方案,一般来说可以采用下面的方法:
l 适当地设置参数 UNDO_RETENTION(要大于执行运行时间最长的事务所需的时间)。可以用V$UNDOSTAT来确定长时间运行的查询的持续时间。另外,要确保磁盘上已经预留了足够的空间,使undo 段能根据所请求的UNDO_RETENTION增大。
l 使用手动 undo 管理时加大或增加更多的回滚段。这样在长时间运行的查询执行期间,覆盖undo数据的可能性就能降低。这种方法可以解决上述的所有3个问题。
l 减少查询的运行时间(调优)。如果可能的话,这绝对是一个好办法,所以应该首先尝试这种方法。这样就能降低对 undo 段的需求,不需求太大的 undo 段。这种方法可以解决上述的所有3个问题。
l 收集相关对象的统计信息。这有助于避免前面所列的第三点。 由于大批量的UPDATE或INSERT会导致块清除(block cleanout) ,所以需要在大批量UPDATE或大量加载之后以某种方式收集统计信息。
对于Oracle9i 和以上版本,管理系统中的undo有两种方法:
l 自动undo管理 (Automatic undo management):采用这种方法, 通过UNDO_RETENTION参数告诉 Oracle 要把 undo 保留多长时间。Oracle 会根据并发工作负载来确定要创建多少个undo段,以及每个undo段应该多大。数据库甚至在运行时可以在各个undo段之间重新分配区段,以满足DBA 设置的UNDO_RETENTION目标。这是undo管理的推荐方法。
l 手动undo管理(Manual undo management) :采用这种方法的话,要由DBA 来完成工作。DBA 要根据估计或观察到的工作负载, 确定要手动地创建多少个undo 段。 DBA 根据事务量 (生成多少undo)和长时间运行查询的长度来确定这些undo段应该多大。
在手动 undo 管理的情况下,DBA 要确定有多少个 undo 段,以及各个 undo 段有多大,这就产生了一个容易混淆的问题。有人说: “那好,我们已经配置了 XMB 的 undo,但是它们可以增长。我们把MAXEXTENTS 设置为 500,而且每个区段是 1MB,所以 undo 可以相当大。”问题是,倘若手动地管理undo段,undo段从来不会因为查询而扩大;只有INSERT、UPDATE 和DELETE才会让undo段增长。事实上,如果执行一个长时间运行的查询,Oracle不会因此扩大手动回滚段(即手动管理的回滚段)来保留数据,以备以后可能需要用到这些数据。只有当执行一个长时间运行的UPDATE 事务时才会扩大手动回滚段。在前面的例子中,即使手动回滚段有增长的潜力,但它们并不会真正增长。对于这样一个系统,你需要有更大的手动回滚段(尽管它们已经很大了)。你要永久地为回滚段分配空间,而不是只给它们自行增长的机会。对于这个问题,惟一的解决方案只能是适当地设置手动回滚段的大小。
在自动undo 管理的情况下,从ORA-01555角度看,问题则要容易得多。无需自行确定undo空间有多大并完成预分配,DBA 只有告诉数据库运行时间至少在这段时间内保留 undo。如果已经分配了足够的空间可以扩展,Oracle 就会扩展 undo 段,而不是回绕,从而满足 UNDO_RETENTION 保持时间的要求。这与手动管理的 undo 截然相反,手动管理是会回绕,并尽可能块地重用 undo 空间。这是由于这个原因(即自动undo管理支持UNDO_RETENTION参数) ,所以我强烈建议尽可能采用自动undo 管理。
使用手动undo管理时,还要记住重要的一点,遇到ORA-01555错误的可能性是由系统中最小的回滚段指示的(而非最大的回滚段,也并非平均大小的回滚段)。增加一个“大”回滚段不能解决这个问题。处理查询时只会让最小的回滚段回绕,这个查询就有可能遇到 ORA-01555 错误。使用遗留的回滚段时我主张回滚段大小要相等,以上就是原因所在。如果回滚段的大小都相等,那么每个回滚段即是最小的,也是最大的。这也是我为什么避免使用“最优大小”回滚段的原因。如果你收缩一个此前被扩大的回滚段,就要丢掉以后可能还需要的大量 undo。倘若这么做,会丢掉最老的回滚数据,从而力图使风险最小,但是风险还是存在。我喜欢尽可能在非高峰期间手动地收缩回滚段。
我们已经讨论过块清除机制,不过这里可以做一个总结:在块清除过程中,如果一个块已被修改,下一个会话访问这个块时,可能必须查看最后一个修改这个块的事务是否还是活动的。一旦确定该事务不再活动,就会完成块清除,这样另一个会话访问这个块时就不必再历经同样的过程。要完成块清除, Oracle会从块首部确定前一个事务所用的undo段,然后确定从 undo 首部能不能看出这个块是否已经提交。可以用以下两种方式完成这种确认。一种方式是Oracle可以确定这个事务很久以前就已经提交,它在undo段事务表中的事务槽已经被覆盖。另一种情况是COMMIT SCN还在 undo段的事务表中,这说明事务只是稍早前刚提交,其事务槽尚未被覆盖。
要从一个延迟的块清除收到ORA-01555错误,以下条件都必须满足:
l 首先做了一个修改并COMMIT,块没有自动清理(即没有自动完成“提交清除” ,例如修改了太多的块,在SGA块缓冲区缓存的10%中放不下) 。
l 其他会话没有接触这些块,而且在我们这个“倒霉”的查询(稍后显示)命中这些块之前,任何会话都不会接触它们。
l 开始一个长时间运行的查询。这个查询最后会读其中的一些块。这个查询从SCN t1开始,这就是读一致 SCN,必须将数据回滚到这一点来得到读一致性。开始查询时,上述修改事务的事务条目还在undo段的事务表中。
l 查询期间,系统中执行了多个提交。执行事务没有接触执行已修改的块(如果确实接触到,也就不存在问题了)。
l 由于出现了大量的COMMIT,undo 段中的事务表要回绕并重用事务槽。最重要的是,将循环地重用原来修改事务的事务条目。另外,系统重用了 undo 段的区段,以避免对 undo 段首部块本身的一致读。
l 此外,由于提交太多,undo段中记录的最低SCN 现在超过了t1(高于查询的读一致SCN)。
如果查询到达某个块,而这个块在查询开始之前已经修改并提交,就会遇到麻烦。正常情况下,会回到块所指的undo段,找到修改了这个块的事务的状态(换句话说,它会找到事务的COMMIT SCN)。如果这个 COMMIT SCN 小于 t1,查询就可以使用这个块。如果该事务的 COMMIT SCN 大于 t1,查询就必须回滚这个块。不过,问题是,在这种特殊的情况下,查询无法确定块的COMMIT SCN是大于还是小于t1。相应地,不清楚查询能否使用这个块映像。这就导致了ORA-01555错误。
万一你发现遭遇了这个问题,即选择(SELECT)一个表时(没有应用其他DML操作)出现了ORA-01555错误,能你可以试试以下解决方案:
l 首先,保证使用的事务“大小适当”。确保没有不必要地过于频繁地提交。
l 使用 DBMS_STATS 扫描相关的对象,加载之后完成这些对象的清理。由于块清除是极大量的UPDATE 或INSERT造成的,所以很有必要这样做。
l 允许undo表空间扩大,为之留出扩展的空间,并增加undo保持时间。这样在长时间运行查询期间,undo 段事务表中的事务槽被覆盖的可能性就会降低。针对导致ORA-01555错误的另一个原因(undo 段太小) ,也同样可以采用这个解决方案(这两个原因有紧密的关系;块清除问题就是因为处理查询期间遇到了 undo 段重用,而 undo 段大小正是重用 undo 段的一个根本原因) 。实际上,如果把undo表空间设置为一次自动扩展1MB,而且undo保持时间为900秒,再运行前面的例子,对表BIG 的查询就能成功地完成了。
l 减少查询的运行时间(调优)。如果可能的话,这总是件好事,所以应该首先尝试这样做。
发表评论
-
ORACLE 命令大全(2)
2010-08-08 16:42 1507一些常用的内置程序包: DBMS_OUTPUT 包输出 PL ... -
RMAN 命令拼凑版
2010-08-08 11:08 890http://blog.chinaunix.net/u1/4 ... -
ORACLE 命令大全(1)
2010-08-08 10:54 1529内容包括三大项: 1.o ... -
Oracle进程类别
2009-09-28 16:40 1985Oracle进程类别 n Oracle实 ... -
Oracle内存结构与管理(2)
2009-09-28 16:38 918自动SGA内存管理(ASMM): 要使用自动管理,需要设置参 ... -
Oracle内存结构与管理(1)
2009-09-28 16:34 1543Oracle内存结构与管理 内存结构 SGA(Sys ... -
Oracle触发器增量提取
2009-09-23 10:59 1742--insert触发器提取增量 --delete触发器提取增 ... -
9i SQL notes
2009-09-12 21:59 1285General functions:– NVL– NVL2– ... -
ORACLE 死锁实验
2009-07-25 17:02 789环境: DB: ORACLE 10.2 OS : RHE ... -
oracle启动
2009-07-23 09:10 930oracle启动的状态 学 ... -
Oracle 临时表
2009-07-16 11:22 1342Oracle 临时表 临时表(Temporary ta ... -
ORA-30036 错误重演实验
2009-07-15 21:01 2552实验步骤: 1. 建立一个很小的UNDO表空间,把系统当前的 ... -
Redo 与 Undo (1)
2009-07-14 20:33 1619通常对undo有一个误解, ... -
事 务
2009-07-12 10:48 1041事 务 Oracle中的事务体现了所有必要的ACID ... -
并发与多版本
2009-07-11 19:33 1235并发与多版本 7.1 ... -
Oracle 锁(2)
2009-07-11 15:03 14066.3 锁类型 Oracle中主要有3类锁,具体是: ... -
Oracle 锁(1)
2009-07-11 15:01 18266.1 什么是锁? 锁(lock)机制用 ... -
Oracle进程类别(2)
2009-07-09 22:54 1423后台进程 可以使用一个V$视图查看所有可能的Oracl ... -
Oracle进程类别(1)
2009-07-09 22:48 918Oracle进程类别 n Oracle实 ... -
Oracle内存结构与管理
2009-07-07 21:19 1518Oracle内存结构与管理 内存结构 SGA(Sys ...
相关推荐
BLOG_Oracle_lhr_【知识点整理】Oracle中NOLOGGING、APPEND、ARCHIVE和PARALLEL下,REDO、UNDO和执行速度的比较BLOG_Oracle_lhr_【知识点整理】Oracle中NOLOGGING、APPEND、ARCHIVE和PARALLEL下,REDO、UNDO和执行...
第9章第9章 redo与undo_a.pdf redo与undo_a.pdf第9章 redo与undo_a.pdf
RAC下的REDO和UNDO管理 收藏.docxRAC下的REDO和UNDO管理 收藏.docxRAC下的REDO和UNDO管理 收藏.docxRAC下的REDO和UNDO管理 收藏.docxRAC下的REDO和UNDO管理 收藏.docxRAC下的REDO和UNDO管理 收藏.docxRAC下的REDO和...
这个是做实验时,简单基本的Undo、Redo的操作、在一个winForm中实现,并且可以设置Undo的最大次数。包中除了项目外,还附有报告.
实现redo,undo操作,来源于网络分享下。
oracle_redo_undo
Delphi 中实现Redo Undo的一个简单实例,包含源码
Multiple Level Undo/Redo多级Undo/Redo功能的实现(7KB)
本工程用vs2008打开,但需要qt库的支持,需要先安装qt-in-vs2008,才可通过编译。或者直接将里面的代码拷贝出来,然后在自己的环境中编译也行。代码中应用了QUndoCommand来实现撤销与反撤销操作。
Oracle_Undo与Redo的通俗
1、用途 redo log undo log binlog2-2、存储内容、格式 redo log undo log binlog2-3、日志生成 redo log undo log binlog2-4、删除策略 redo log undo log binlog2-5、redo log 与 binlog 的区别三、两...
redo undo framework source code redo undo framework source code
针对一个window窗体实现了undo/redo功能,包括textBox,checkBox, listBox, comboBox, radioButton以及按钮焦点变化的实现。可能有些小bug思路仅供参考。完整的工程文件,VS打开即可运行,欢迎评论~ 详细说明参见...
cpp文件 undo redo 原型设计 部分代码 class Command { public: virtual BOOL UnDo() = 0; virtual BOOL ReDo() = 0; };
在Element增删改处 添加 IOperationStack .DO(); 方法,即可将Element的操作过程保存到操作堆 自行对Element的变化进行记录,以便在IOperation 中Redo Undo中使用
GIS 中的undo与redo实现的论文,采用命令模式实现,有相关的数据结构描述
Undo/Redo framework for editing controls in a Windows application 在Windows应用程序中编辑控件的撤销/重做框架。
oracle日志,Undo日志记录某数据被修改前的值,可以用来在事务失败时进行rollback;Redo日志记录某数据块被修改后的值,可以用来恢复未写入data file的已成功事务更新的数据。
实现多步Undo和Redo的方法,对于mfc绘图程序来说,这个很必要,而且很实用!
Oracle redo undo的说明解释