情况说明:
最近同事和我说,要从较大的生产库导表结构及数据至测试环境,原库数据量较多,大约为1T左右,测试环境空间无法满足,同时也由于该生产库的多次修改,原有的建表语句已有一定的差异性无法再使用。
解决思路:
一、分多次IMP导入,同时执行存储过程对表、表分区及索引进行shrink或REBUILD操作
缺点:
多次操作,较为繁琐
二、编写DDL触发器,在IMP导入操作的同时对create语句进行替换,直接修改STORAGE内的内容,然后执行修改后的DDL语句
解决方法:
针对第二种思路,进行了触发器编写,代码如下:
create or replace trigger hwm_create
instead of create on schema
when (ora_dict_obj_type in ('TABLE', 'INDEX') and sys.sysevent = 'CREATE')
declare
v_sql clob;
v_sql_t ora_name_list_t;
i_init number;
i_m number;
begin
case
when ora_dict_obj_type in ('TABLE', 'INDEX') and sys.sysevent = 'CREATE' then
for counter in 1 .. ora_sql_txt(v_sql_t) loop
if v_sql_t(counter) like '%initial%' then
i_init := 0;
i_m := 0;
i_init := instr(v_sql_t(counter), 'initial');
i_m := instr(v_sql_t(counter), 'M', i_init, 1);
if i_m = 0 then--i_init有值时,I_M必不为0
i_m := instr(v_sql_t(counter), 'K', i_init, 1);
end if;
if i_m <> 0 then
v_sql_t(counter) := substr(v_sql_t(counter), 1, i_init - 1) ||
'initial 0' ||
substr(v_sql_t(counter), i_m + 1);
end if;
end if;
v_sql := v_sql || v_sql_t(counter);
end loop;
if ora_dict_obj_type = 'INDEX' then
insert into xxb_log values(1,v_sql);
else
if ora_dict_obj_type = 'TABLE' then
EXECUTE IMMEDIATE v_sql;
end if;
end if;
end case;
end hwm_createtable;
现有情况:
一、建表时,语句可直接替换并执行,经过测试未出现问题
二、创建普通索引时,会报出无效的DDL语句,但直接执行弹出的修改后的DDL语句是没有问题的
三、创建主键索引时,会报出ORA-00600的内部错误
问题:
一、如何对索引创建语句进行直接替换并执行
二、如何对主键索引进行处理
麻烦各位大神进行指教,谢谢!



------解决方案--------------------
------解决方案--------------------
exp的时候,指定compress=N可以消除这种情况
其实数据量这么大,建议用expdp/impdp会快得多,并且要更加稳定
expdp/impdp不会有initial暴涨这种问题