|
shrink space分两个阶段: 1)通过把segment后面的数据delete,然后insert到segment的前面,来把表里的块变得更加紧凑。这个操作的事务单位比较小,操作过程中,会在表上加模式为3的表锁,这种锁的等级跟DML事务在表上加的锁等级一样,一般比较安全,不会阻塞这个表上的DML操作。在这个过程中即使把当前会话取消掉,也不会有风险。下次可以继续上一次的操作。而不是很多人理解的,取消掉后,会回滚之前的所有的delete+insert 操作。由于这个阶段的事务单位比较小,因此取消(比如ctl+c)后,只会回滚此次没有提交掉的事务。如果你的表比较大,那么可以分多次来做这个操作,每次可以放心的把它cancel掉,下次继续。第一个阶段对应的命令为:
从上图看到在执行操作一过程中,ORACLE启动了一个小事务,这个小事务的ID1,ID2在不断的变化。 可是对于这个操作大家可能会有一些误解: 1)这个操作非常安全,可以在线做,不会阻塞DML。上面已经说了,第二个阶段会持有表上模式为6(排他)的锁,会阻塞表上所有的DML操作,如果表比较大,第二个阶段的操作时间就会比较长。因此对于DML操作频繁的大表,这个操作的风险还是非常大的。 2)第二个误解是,很多人都觉得不做第二步,即不降低高水位似乎就没有什么效果。第二步是必须做的吗?其实如果你的表都是通过索引来访问的,那么第二个阶段完全没有必要做了,当然会浪费点空间。第一个阶段做完后,你的表数据就已经非常的紧凑了,第二步的降低高水位,只是为你释放了点空间。如果你的表上不存在全表扫描(或全表扫描极少),你完全没有必要做第二步。 最后提醒大家,shrink操作完成后,最好把索引rebuild online下。 |


