【IT168 技术文档】 ROW MOVEMENT特性最初是在8i时引入的,其目的是提高分区表的灵活性——允许更新Partition Key。这一特性默认是关闭,只是在使用到一些特殊功能时会要求打开。除了之前提到的更新Partition Key,还有2个要求打开的ROW MOVEMENT的功能就是flushback table和Shrink Segment。所以,只有当使用到以上3个功能特性时,ROW MOVEMENT才会真正起作用。我们如果需要知道ROW MOVEMENT会对系统产生什么影响,就只要看这3个功能使用时会产生什么影响。
Flashback Table
先看Flashback Table。这一功能能帮助我们及时回滚一些误操作,防止数据意外丢失。在使用该功能之前,必须先打开ROW MOVEMENT,否则就会抛ORA-08189错误。我们看以下例子,可以说明在使用Flashback Table功能时,ROW MOVEMENT产生了什么作用:
SQL代码
SQL> create table test_move as select * from dba_users;
Table created.
SQL> select username, rowid from test_move;
USERNAME ROWID
------------------------------ ------------------
DMP AAAwSfAAFAAAVlMAAA
MYTBC AAAwSfAAFAAAVlMAAB
CS2 AAAwSfAAFAAAVlMAAC
TBC AAAwSfAAFAAAVlMAAD
WOW AAAwSfAAFAAAVlMAAE
REPO AAAwSfAAFAAAVlMAAF
... ...
SYSTEM AAAwSfAAFAAAVlMAAk
OUTLN AAAwSfAAFAAAVlMAAl
38 rows selected.
SQL> delete from test_move where username = 'MYTBC';
1 row deleted.
SQL> commit;
Commit complete.
SQL> flashback table test_move to timestamp(systimestamp - interval '3' minute);
flashback table test_move to timestamp(systimestamp - interval '3' minute)
*
ERROR at line 1:
ORA-08189: cannot flashback the table because row movement is not enabled
Table created.
SQL> select username, rowid from test_move;
USERNAME ROWID
------------------------------ ------------------
DMP AAAwSfAAFAAAVlMAAA
MYTBC AAAwSfAAFAAAVlMAAB
CS2 AAAwSfAAFAAAVlMAAC
TBC AAAwSfAAFAAAVlMAAD
WOW AAAwSfAAFAAAVlMAAE
REPO AAAwSfAAFAAAVlMAAF
... ...
SYSTEM AAAwSfAAFAAAVlMAAk
OUTLN AAAwSfAAFAAAVlMAAl
38 rows selected.
SQL> delete from test_move where username = 'MYTBC';
1 row deleted.
SQL> commit;
Commit complete.
SQL> flashback table test_move to timestamp(systimestamp - interval '3' minute);
flashback table test_move to timestamp(systimestamp - interval '3' minute)
*
ERROR at line 1:
ORA-08189: cannot flashback the table because row movement is not enabled
此时,由于ROW MOVEMENT还未打开,命令出错。继续完成演示:
SQL代码
SQL> alter table test_move enable row movement;
Table altered.
SQL> flashback table test_move to timestamp(systimestamp - interval '3' minute);
Flashback complete.
SQL> select username, rowid from test_move;
USERNAME ROWID
------------------------------ ------------------
DMP AAAwSfAAFAAAVlMAAB
MYTBC AAAwSfAAFAAAVlMAAm
CS2 AAAwSfAAFAAAVlMAAn
TBC AAAwSfAAFAAAVlMAAo
WOW AAAwSfAAFAAAVlMAAp
REPO AAAwSfAAFAAAVlMAAq
... ...
SYSTEM AAAwSfAAFAAAVlMABJ
OUTLN AAAwSfAAFAAAVlMABK
38 rows selected.
Table altered.
SQL> flashback table test_move to timestamp(systimestamp - interval '3' minute);
Flashback complete.
SQL> select username, rowid from test_move;
USERNAME ROWID
------------------------------ ------------------
DMP AAAwSfAAFAAAVlMAAB
MYTBC AAAwSfAAFAAAVlMAAm
CS2 AAAwSfAAFAAAVlMAAn
TBC AAAwSfAAFAAAVlMAAo
WOW AAAwSfAAFAAAVlMAAp
REPO AAAwSfAAFAAAVlMAAq
... ...
SYSTEM AAAwSfAAFAAAVlMABJ
OUTLN AAAwSfAAFAAAVlMABK
38 rows selected.
当开启ROW MOVEMENT后,表被顺利的flashback了,数据被找回。此时,再比较flashback前后记录的ROWID,大多数记录的物理位置都变化。这个过程的内部操作, 可以通过对Flashback Table做SQL Trace来进一步观察。通过Trace,我们不难发现,Flashback Table实际是通过Flashback Query将表中数据进行了一次删除、插入操作,因此ROWID会发生变化。