alter table table_name enable row movement

  • Row movement 从字面意思解释为行移动.默认情况下,oracle数据块中的一行其生命周期内是不会发生移动的,即其rowid不会发生改变. 但是在某些情景下,我们希望行的rowid可以发生变化,这时候我们就需要启动表的row movement特性。

    启用row movement特性,使用如下语句:

     

    Alter table table_name enable row movement;

     

     

    通查在三种情景下,需要启用row movement

    1:分区表

    当我们允许分区表的分区键是可更新的时候,如果分区键的更新导致当前修改的数据条目需要移动到其他分区,此时就会发生rowid的改变。

     

    SQL> create table city_office(office_number number,city_id varchar2(10))

      2  partition by list(city_id)

      3  (

      4  partition p1 values('1'),

      5  partition p2 values('2'),

      6  partition p3 values('3'));

     

    Table created.

     

    SQL> insert into city_office values(1,'1');

     

    1 row created.

     

    SQL> insert into city_office values(2,'2');

     

    1 row created.

     

    SQL> insert into city_office values(3,'3');

     

    1 row created.

     

    SQL> insert into city_office values(4,'1');

     

    1 row created.

     

    SQL> commit;

     

    Commit complete.

     

    SQL> select * from city_office partition(p1);

     

    OFFICE_NUMBER CITY_ID

    ------------- ----------

                1 1

                4 1

     

    SQL> select * from city_office partition(p2);

     

    OFFICE_NUMBER CITY_ID

    ------------- ----------

                2 2

     

    SQL> update city_office set city_id=2 where office_number=4;

    update city_office set city_id=2 where office_number=4

           *

    ERROR at line 1:

    ORA-14402: updating partition key column would cause a partition change

     

     

    SQL> alter table city_office enable row movement;

     

    Table altered.

     

    SQL> update city_office set city_id=2 where office_number=4;

     

    1 row updated.

     

    SQL>

    SQL>

    SQL> select * from city_office partition(p1);

     

    OFFICE_NUMBER CITY_ID

    ------------- ----------

                1 1

     

    SQL> select * from city_office partition(p2);

     

    OFFICE_NUMBER CITY_ID

    ------------- ----------

                2 2

                4 2

     

    2:闪回操作

    在闪回操作时,我们同样需要开启表的row movement特性。

     

    SQL> alter table city_office disable row movement;

     

    Table altered.

     

    SQL> select current_scn from v$database;

     

    CURRENT_SCN

    -----------

        1291848

     

    SQL> select count(*) from city_office;

     

      COUNT(*)

    ----------

             4

     

    SQL> delete from city_office where city_id=1;

     

    1 row deleted.

     

    SQL> commit;

     

    Commit complete.

     

    SQL> flashback table city_office to scn 1291848;

    flashback table city_office to scn 1291848

                    *

    ERROR at line 1:

    ORA-08189: cannot flashback the table because row movement is not enabled

     

     

    SQL> alter table city_office enable row movement;

     

    Table altered.

     

    SQL> flashback table city_office to scn 1291848;

     

    Flashback complete.

     

    SQL> select count(*) from city_office;

     

      COUNT(*)

    ----------

             4

     

    为什么flashback table会造成rowid的改变那?通过下面的实验来研究一下:

    SQL> create table easy(id number);

     

    Table created.

     

    SQL> insert into easy values(1);

     

    1 row created.

     

    SQL> commit;

     

    Commit complete.

     

    SQL> alter table easy enable row movement;

     

    Table altered.

     

    SQL> select current_scn from v$database;

     

    CURRENT_SCN

    -----------

        1292223

     

    SQL> update table easy set id = 2;

    update table easy set id = 2

           *

    ERROR at line 1:

    ORA-00903: invalid table name

     

     

    SQL> update easy set id = 2;

     

    1 row updated.

     

    SQL> commit;

     

    Commit complete.

     

    SQL> alter session set tracefile_identifier = 'ee';

     

    Session altered.

     

    SQL> alter session set sql_trace=true;

     

    Session altered.

     

    SQL> flashback table easy to scn 1292223;

     

    Flashback complete.

     

    SQL> select * from sys_temp_fbt ;

     

    SCHEMA     OBJECT_NAME             OBJECT# RID                            A

    ---------- -------------------- ---------- ------------------------------ -

    EASY       EASY                      76906 AAASxqAAGAAAAC0AAA             D

    EASY       EASY                      76906 AAASxqAAGAAAAC0AAA             I

     

    通过查看trace文件,我们可以发现oracle  flashback table 是通过一个临时表sys_temp_fbt来实现的。trace文件中的部分内容如下:

    ********************************************************************************

     

    SQL ID: fbk9spd3mwsfg Plan Hash: 3764894756

     

    INSERT /*+ APPEND */ into SYS_TEMP_FBT SELECT /*+ FBTSCAN FULL(S) PARALLEL(S,

      DEFAULT) */ :1, :2, :3, rowid, SYS_FBT_INSDEL FROM "EASY"."EASY" as of SCN

     

    ********************************************************************************

     

    SQL ID: 7fh8jd0y92mv9 Plan Hash: 1584303325

     

    DELETE /*+ BYPASS_UJVC */ FROM (SELECT /*+ ORDERED USE_NL(S) PARALLEL(S,

      DEFAULT) PARALLEL(T,DEFAULT) */ S.rowid FROM SYS_TEMP_FBT T, "EASY"."EASY"

      S

    WHERE

     T.rid = S.rowid and T.action = 'D' and T.object#  = : 1) V

     

    ********************************************************************************

     

    SQL ID: gpj0cz9m8173z Plan Hash: 1430220360

     

    INSERT /*+ PARALLEL(S, DEFAULT) PARALLEL(T, DEFAULT) */ INTO "EASY"."EASY"

      SELECT /*+ USE_NL(S) ORDERED PARALLEL(S, DEFAULT) PARALLEL(T, DEFAULT) */

      S.* FROM SYS_TEMP_FBT T , "EASY"."EASY" as of SCN :1 S WHERE T.rid =

      S.rowid and T.action = 'I' and T.object# = :2

     

    由此可见,oracle是通过SYS_TEMP_FBT进行删除操作,而后进行插入操作,因此行的rowid有可能发生改变、

     

     

     

     

    . 

     

     

    Java代码  

    收藏代码

    1. SQL> ALTER TABLE CITY_OFFICES ENABLE ROW MOVEMENT;  
    2. Table altered.  
    3. SQL> FLASHBACK TABLE CITY_OFFICES  
    4.   2    TO TIMESTAMP (SYSTIMESTAMP - INTERVAL '05' minute);  
    5. Flashback complete.  
    6. SQL> SELECT * FROM CITY_OFFICES;  
    7. OFFICE_NUMBER CITY_ID      OFFICE_NAME  
    8. ------------- ------------ ------------------------------  
    9.             1 282          DENVER  
    10.             2 282          DENVER TECH CTR  
    11.             3 282          DENVER WEST  
    12.             4 283          BROOMFIELD  

     

    If the table has row movement disabled, why is it you can drop the table and flashback the table to before the drop without row movement being enabled? 

     

    Java代码  

    收藏代码

    1. SQL> ALTER TABLE CITY_OFFICES DISABLE ROW MOVEMENT;  
    2. Table altered.  
    3. SQL> DROP TABLE CITY_OFFICES;  
    4. Table dropped.  
    5. SQL> FLASHBACK TABLE CITY_OFFICES TO BEFORE DROP;  
    6. Flashback complete.  

     

     

    3:回收空间

    在收缩空间时,也会造成行的移动,如下

     

    SQL> alter table easy disable row movement;

     

    Table altered.

     

    SQL> alter table easy shrink space;

    alter table easy shrink space

    *

    ERROR at line 1:

    ORA-10636: ROW MOVEMENT is not enabled

     

     

    SQL> alter table easy enable row movement;

     

    Table altered.

     

    SQL> alter table easy shrink space;

     

    Table altered.

     

    Shrink space操作(without  compact)会导致所有已经打开的游标失效,因此需要谨慎使用。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值