客户需要在数据库中以一个schema wm9为基础,新建40个schema,这样就想到了remap_schema。这个参数最好与remap_tablespace一起使用。
多个schema的映射记录一下过程。
查看了官方文档对于此参数的说明,其中有一段说明,
Multiple REMAP_SCHEMA lines can be specified, but the source schema must be different for each one. However, different source schemas can map to the same target schema.
可以指定多个REMAP_SCHEMA行,但每一行的源模式必须不同。但是,不同的源模式可以映射到相同的目标模式。
意思应该是不能用一个schema导入多个schema,可以用不同的schema导入相同的schema。那么也可以用不同的schema导入不同的schema。
思路:先将wm9导出,依次导入到5个schema,然后将5个schma导出,再用5个schema导入5个,这样会快一点。
1、wm9 有单独的表空间,先检查一下表空间是否自包含
SQL> EXEC DBMS_TTS.TRANSPORT_SET_CHECK(‘WM9_DATA‘,TRUE);
PL/SQL procedure successfully completed.
SQL> select * from TRANSPORT_SET_VIOLATIONS;
no rows selected
2、导出数据
expdp system/system DIRECTORY=DIR_DMP SCHEMAS=WM9 dumpfile=exp0729.dmp logfile=expdp.log job_name=expdp9 COMPRESSION=all exclude=statistics;
3、创建用户及表空间
执行过程略
4、导入
impdp system/system DIRECTORY=DIR_DMP DUMPFILE=exp0729.dmp REMAP_SCHEMA=WM9:WM11 REMAP_TABLESPACE=WM9_DATA:WM11_DATA logfile=wm11_2.log job_name=impdp11
此处一定要加上REMAP_TABLESPACE参数,否则将会在把数据都导入的wm9的表空间中,当然不需要使用独立表空间的话就不用了。
出现了如下报错
ORA-39083: Object type TYPE failed to create with error:
ORA-02304: invalid object identifier literal
Failing sql is:
CREATE TYPE "WM11"."STRSPLIT_TYPE" OID ‘8752B37EC5526594E05369A51DAC1876‘ IS TABLE OF VARCHAR2 (4000)
ORA-39083: Object type TYPE failed to create with error:
ORA-02304: invalid object identifier literal
Failing sql is:
CREATE TYPE "WM11"."TYPE_SPLIT" OID ‘8752B37EC5566594E05369A51DAC1876‘ as table of varchar2(50);
对于create type失败,可在导入命令中末尾加上 transform=OID:N,官文档中有以下说明:
By default, if schema objects on the source database have object identifiers(OIDs), then they are imported to the target database with those same OIDs. If anobject is imported back into the same database from which it was exported, but in‐to a different schema, then the OID of the new (imported) object would be thesame as that of the existing object and the import would fail. For the import to suc‐ceed you must also specify the TRANSFORM=OID:N parameter on the import. Thetransform OID:N causes a new OID to be created for the new object, allowing theimport to succeed.
大意就是说如果TRANSFORM参数设置成OID=N,表示在impdp的时候,新创建的表或这个类型会赋予新的OID,而不是dmp文件中包含的OID的值。但是这个参数的默认值是OID=Y,因此在进行Impdp的时候,新创建的表或者type会赋予同样的OID,如果是位于同一个数据库上的不同schema,那就会造成OID冲突的问题,因此解决这个问题也很简单,只需要在impdp的时候,显示设置transform 参数为OID=N既可以了。
重新导入
impdp system/system DIRECTORY=DIR_DMP DUMPFILE=exp0729.dmp REMAP_SCHEMA=WM9:WM11 REMAP_TABLESPACE=WM9_DATA:WM11_DATA logfile=wm11_2.log job_name=impdp11 table_exists_action=replace transform=OID:N
5、无效对象的处理
发现有较多无效的存储过程,函数、视图。对比了wm9与wm11的对象权限,都有dba权限,但有部分对象权限需要显式的授权,授权后重新编译后正常。
6、多个schema映射
创建表空间及用户略
expdp \‘/ as sysdba\‘ DIRECTORY=DIR_DMP SCHEMAS=WM9,WM11,WM12,WM13,WM14 dumpfile=exp_0729.dmp logfile=expdp.log job_name=expdpwh9 COMPRESSION=all exclude=statistics;
impdp system/sceadmin DIRECTORY=DIR_DMP DUMPFILE=exp_schema5_0730.dmp REMAP_SCHEMA=WM9:WM15,WM11:WM16,WM12:WM17,WM13:WM18,WM14:WM19 REMAP_TABLESPACE=WM9_DATA:WM15_DATA,WM11_DATA:WM16_DATA,WM12_DATA:WM17_DATA,WM13_DATA:WM18_DATA,WM14_DATA:WM19_DATA logfile=imp_5.log job_name=impdp15 transform=OID:N
开始很顺利,但还是遇到一个问题:忘记禁用触发器。对于触发器,REMAP_SCHEMA只影响触发器所有者。
客户反馈出现了关于触发器的报错,赶紧禁用新建schema的所有触发器。
执行以下脚本快速禁用触发器
declare
v_owner varchar2(60) := ‘WM11‘;
begin
for cur in (select t.TRIGGER_NAME from dba_triggers t where t.OWNER = v_owner) loop
execute immediate ‘alter trigger ‘|| v_owner||‘.‘||cur.trigger_name ||‘ disable‘;
end loop;
end;
/
查询所有owner与talbe不一致的触发器
select OWNER,TRIGGER_NAME,TABLE_OWNER,TABLE_NAME,STATUS from dba_triggers where owner<>table_owner order by 1;
用toad 的database browser功能一次获取用户所有的触发器DDL语句,替换所有schema,再执行重建触发器。