WINDOWS下的程序员出身,偶尔也写一些linux平台下小程序, 后转行数据库行业,专注于ORACLE和DB2的运维和优化。 同时也是ios移动开发者。欢迎志同道合的朋友一起研究技术。 数据库技术交流群:58308065,23618606
全部博文(599)
分类: Oracle
2010-01-10 01:21:32
回滚段的空间使用
回滚段管理(一) 回滚段的概述:http://blog.chinaunix.net/u3/107027/showart_2144676.html
当一个事务开始时,Oracle就开始向回滚段写入一个回滚段条目。该条目不能够扩展到其他任何回滚段,也不能动态地转向使用另一个回滚段。条目开始在回滚段的一个盘区中连续写入。这个盘区中的每一块必须只包含一个事务的信息。不同事务的块可以被存储在同一个盘区中(见图7 - 3 )。图7 - 3示出了回滚段中一个盘区的前五个块。两个不同事务正把回滚信息存储在这个回滚盘区中。
在理想的数据库中,一个盘区只有一个事务。然而,这种情况并不常见。这是因为,当一个事务处理无法在一个盘区中再获得空间时,回滚段会寻找另一个盘区来继续写入回滚段条目。数据库首先试图把条目扩展到回滚段的下一个盘区。如果当前盘区是回滚段的最后一个盘区,数据库则试图把条目扩展到它的第一个盘区。
然而,这第一个盘区可能已被使用。如果是这样的话,回滚段就不得不获得一个新盘区。
图7 - 4说明了这种扩展选择的过程。
如图7-4a所示,一个事务(这里是事务A )已占用回滚段r1的四个盘区。由于事务A从回滚段r1的盘区3开始,所以此事务开始时,这个回滚段的前两个盘区必须已不可用。这时,这个事务已拥有四个盘区,并且在寻找第五个盘区。
由于它已经占据了该回滚段的最后一个盘区(6#盘区),所以数据库将检查r1回滚段中的第一个盘区是否含有激活的事务数据。如果没有,则这个盘区将被用作事务A条目的第五个盘区(见图7-4b)。不过,如果这个盘区正被一个事务使用,则回滚段会动态进行自身扩展,从而7#盘区将用作事务A的第五个盘区(见图7-4c)。
一旦一个事务完成,它的数据不会从回滚段中删除。旧的回滚数据保留在回滚段中,以便对提交前开始执行的事务和查询提供服务。对于冗长的查询,这样可能会引发问题,产生如下的错误消息:
ORA-01555:snapshot too old (rollback segment too small)
这种错误是由对“active(激活的)”数据的定义引起的。考虑到图7-4a中事务A那样的大型事务,当一个冗长查询访问事务A所处理的表时,需要使用由事务A的回滚段条目存储的数据块。然而,一旦事务A完成,那些数据块将被标记为inactive(非激活)。尽管此时对这些数据块的冗长查询还没有结束,但这些数据块可能被其他事务所重写。这将导致对这些数据块的查询失败。具体情况如图7-5所示。
如图7-5所示,一个事务可以跨多个盘区。在图7-5a中,事务A使用回滚段的5个盘区并且已经完成。即使在事务完成后,其他用户也仍可使用这些数据。例如,如果其他用户在事务A完成前正在查询数据,就需要使用回滚段条目来重新构造所要查询的表数据。虽然事务A的回滚条目数据处于非激活状态,但它正在使用中。当事务B开始时(见图7-5b),它从回滚段的第一个可用盘区开始。当它扩展到第二个盘区后,事务A的回滚段条目数据将会被重写(因为数据为非激活状态),从而导致任何使用这些回滚段条目数据的行为失败(因为它们正在被使用着)。
这其中有两个导致查询失败的重要因素。首先,在进行一个冗长查询的同时,数据也正在被处理;换句话说,在这个时候,数据库中正同时进行着批处理和数据的联机事务处理。在前面对回滚段功能的讨论中,这种问题的解决方案已经很清楚:一个冗长查询操作不仅必须访问需要完成的所有表及索引,而且还必须访问存储在回滚段中的数据,以保证所读数据的一致性。
查询必须连续访问回滚段,直到查询完成为止。因此,冗长查询要求正在使用的回滚段条目没有被重写。但是这些条目一旦完成,就无法保证这种情况。错误消息(“回滚段太小”)中给出的建议是通过解决另一个相关问题来解决这个问题:通过增加回滚段空间来延长第一个盘区被重写的时间间隔,从而推迟回滚段中已存在的条目被重写。给回滚段增加更多的空间并不是一个真正的解决方案。这只是一个延时策略,因为回滚段最终会重写所有数据块。比较合适的方案是在联机事务处理最少时安排冗长查询。
最佳storage子句
如前面的图7 - 4所示,回滚段可以动态扩展来处理大型事务条目的装载。一旦这种扩展完成,回滚段就保留在扩展期间获得的空间。这可能就是回滚段空间管理问题的症结所在。因为一个大型事务处理可能消耗掉回滚段表空间的所有空间,这将阻止该表空间中其他回滚段的扩展。
可以通过两种改变回滚段所用storage子句的方法来解决这个问题。首先,不再需要回滚段的pctincrease参数。因为这会强制回滚段均匀增长,而不是几何增长。
第二种改变回滚段storage子句的方法是增加optimal参数。该参数允许数据库管理为回滚段指定一个最佳长度(以字节为单位)。当回滚段扩展超过这个长度时,它便会通过删除最旧的盘区来实现自身的动态收缩(shrink)。
初看起来,这似乎是一个灾难性的选择。它阻止一个回滚段使用表空间的全部自由空间。
不过请注意,这个数据库:
1) 动态扩展回滚段,造成性能问题。
2) 动态选择并删除最旧盘区,也同样造成性能问题。
3) 在非激活数据被覆盖前,删除它们。
最后一点会使具有optimal尺寸的数据库设置得太小,从而引发比图7 - 5所示的“快照太旧”情况更大的问题。这是因为旧的事务数据现在可以用两种方式消除:重写或者在收缩当中被删除。
图7 - 6展示了通过optimal参数扩展和收缩回滚段的进程。在事务大小不详且回滚段表空间的可用自由空间又有限时,这种方法很有用。然而即使如此,它也不是非常合适的回滚段尺寸解决方案。
如图7 - 6所示,当一个事务完成时,回滚段要检查自己的optimal值。如果超过了这个optimal值,回滚段会删除它最旧的盘区(本例中的盘区1 )。这样便可以在查询服务中使回滚段保持optimal值。收缩回滚段的副作用是减少了非激活回滚数据的数量,而这些非激活回滚数据对当前事务依然可用。
当回滚段超过其optimal值时,如果回滚段中没有非激活的盘区,将会出现什么情况呢?回滚段将必须继续扩展以支持该事务。如果该回滚段被强制(例如通过一个大型事务)超过其optimal值,则它需要的空间暂时是回滚段的一部分。结束时,下一个超过optimal设置值的事务在它结束时将促使数据库恢复使其超过optimal值的任何空间。