压缩表转非压缩表(在线重定义)

来源:这里教程网 时间:2026-03-03 19:03:59 作者:

1.重定义需要源表存在主键,使用dbms包检测 exec dbms_redefinition.can_redef_table('PAR', 'TEST'); ERROR at line 1: ORA-12089: cannot online redefine table "PAR"."TEST" with no primary key ORA-06512: at "SYS.DBMS_REDEFINITION", line 143 ORA-06512: at "SYS.DBMS_REDEFINITION", line 1635 ORA-06512: at line 1 如果没有主键,可以使用rowid的方式(使用rowid方式,会产生名为M_ROW$$的unused列,可以在重定义后删除) EXEC DBMS_REDEFINITION.CAN_REDEF_TABLE('PAR','TEST', DBMS_REDEFINITION.CONS_USE_ROWID); 事后删除隐藏列: 查看隐藏列 select table_name,column_name,hidden_column from dba_tab_cols where table_name='T_01'; 删除隐藏列 alter table DEF.T_01 drop unused columns; 2.获取源表ddl和索引ddl 获取源表ddl set linesize 1000 set pagesize 0 set echo off set heading off set feedback off set trims ON set term off set trimout on set long 99999 select dbms_metadata.get_ddl('TABLE','TEST','PAR') from dual; 获取源表的local index的ddl索引 select dbms_metadata.get_ddl('INDEX','LOCAL_ID','PAR') from dual; 3.修改ddl语句,并创建表和索引 表的ddl(删掉压缩)   CREATE TABLE "DEF"."T_01"    (    "A" NUMBER,         "B" NUMBER,         "C" NUMBER    ) SEGMENT CREATION IMMEDIATE   PCTFREE 0 PCTUSED 40 INITRANS 1 MAXTRANS 255  COMPRESS BASIC LOGGING   STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645   PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1   BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)   TABLESPACE "USERS" 索引的ddl Xxxxxxx 4.检查是否开启行迁移(2个表都要看) select row_movement from dba_tables where table_name='TEST' and owner='PAR'; select row_movement from dba_tables where table_name='TEST_NEW' and owner='PAR'; 开启行迁移 alter table test enable row movement; alter table test_new enable row movement; 5.开始在线重定义 开始: exec dbms_redefinition.start_redef_table('PAR','TEST','TEST_NEW',null,dbms_redefinition.cons_use_rowid); 脚本: source ~/.bash_profile sqlplus / as sysdba >/tmp/start.log << EOF conn BUSBIKE/BUSBIKE alter table TERM_TRAN_LOG_TBL parallel 8;        exec dbms_redefinition.start_redef_table('BUSBIKE','TERM_TRAN_LOG_TBL','TERM_TRAN_LOG_TBL_QY',null,dbms_redefinition.cons_use_rowid); alter table TERM_TRAN_LOG_TBL parallel 1; exit EOF 如果第一次执行失败,需要重新执行,记得删除物化视图以及物化视图日志 drop materialized view test_new; SELECT LOG_OWNER,MASTER,LOG_TABLE FROM DBA_MVIEW_LOGS; DROP MATERIALIZED VIEW LOG on TEST; 6.复制表属性(传输触发器,权限,约束等依赖) 开始: declare num_errors PLS_INTEGER; BEGIN DBMS_REDEFINITION.COPY_TABLE_DEPENDENTS('PAR','TEST','TEST_NEW', DBMS_REDEFINITION.CONS_ORIG_PARAMS, TRUE, TRUE, TRUE, TRUE, num_errors); END; / 脚本: 创建存储过程 create or replace procedure p_test is num_errors PLS_INTEGER; BEGIN DBMS_REDEFINITION.COPY_TABLE_DEPENDENTS('BUSBIKE','TERM_TRAN_LOG_TBL','TERM_TRAN_LOG_TBL_QY', DBMS_REDEFINITION.CONS_ORIG_PARAMS, TRUE, TRUE, TRUE, TRUE, num_errors); END p_test; 后台脚本执行  source ~/.bash_profile sqlplus / as sysdba >/tmp/copy.log << EOF alter table BUSBIKE.TERM_TRAN_LOG_TBL parallel 8; exec p_test alter table BUSBIKE.TERM_TRAN_LOG_TBL parallel 1; exit EOF 7.同步数据(可以减少结束重定义过程的锁表时间) 开始: exec dbms_redefinition.sync_interim_table('PAR','TEST','TEST_NEW'); 脚本: 增量 source ~/.bash_profile sqlplus / as sysdba >/tmp/add.log << EOF conn BUSBIKE/BUSBIKE alter table TERM_TRAN_LOG_TBL parallel 8;   exec dbms_redefinition.sync_interim_table('PAR','TERM_TRAN_LOG_TBL','TERM_TRAN_LOG_TBL_QY'); alter table TERM_TRAN_LOG_TBL parallel 1; exit EOF 8.完成在线重定义(期间会锁表) 开始: EXEC DBMS_REDEFINITION.FINISH_REDEF_TABLE('PAR','TEST','TEST_NEW'); 脚本: source ~/.bash_profile sqlplus / as sysdba >/tmp/finsh.log << EOF conn BUSBIKE/BUSBIKE alter table TERM_TRAN_LOG_TBL parallel 8;        EXEC DBMS_REDEFINITION.FINISH_REDEF_TABLE('BUSBIKE','TERM_TRAN_LOG_TBL','TERM_TRAN_LOG_TBL_QY'); alter table TERM_TRAN_LOG_TBL parallel 1; exit EOF **此时test表与test_new完成替换** 9.收尾 收集统计信息 begin dbms_stats.gather_table_stats ( ownname => 'PAR', tabname => 'TEST', granularity => 'ALL', estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE, method_opt => 'for all columns size auto', no_invalidate => false, degree => 1, cascade => true); END; 我的: exec dbms_stats.gather_table_stats(ownname => 'USER',tabname => 'TEST',estimate_percent => 10,method_opt=> 'for all indexed columns',cascade=>TRUE);   关闭行迁移 alter table test_new disable row movement; 删隐藏列 查看隐藏列 select table_name,column_name,hidden_column from dba_tab_cols where table_name='T_01'; 删除隐藏列 alter table DEF.T_01 drop unused columns;

相关推荐