主要讲一下关于Oracle在线传输表空间的一些注意事项,文中附有示例。
使用copy 数据文件+导入metadata的方式迁移数据
可以实现跨平台传输表空间
COLUMNPLATFORM_NAME FORMAT A36
SELECT * FROM V$TRANSPORTABLE_PLATFORM ORDER BY PLATFORM_NAME;
如果发现源、目标数据库的endian不相同,需要使用rman convert 转换,否则不需要
源、目标数据库必须拥有兼容的字符集。
字符集相同
源数据库的字符集必须是目标数据库的子集。(下面必须全部满足)
(1) 源数据库版本必须大于10.1.0.3
(2) 表中的列不包含semantics的定义信息,最大字符长度限制和目标数据库相同。
(3) 不包含clob数据类型,或者两个数据库的字符集同为single-byte orboth multibyte.
两个数据库必须拥有兼容的国家字符集
必须满足下面其中之一
(1)国家字符集相同
(2)source databaseis in version 10.1.0.3 or higher,并且没有NCHAR, NVARCHAR2, or NCLOB类型的数据
目标数据库中不能有相同名称的表空间。(传输之前rename一下)
底层依赖的对象必须全部包含在表空间集合中。
1.tablespace+partition
2. 备份数据到cd中
3. 拷贝只读表可能关键到多个数据库
4. 归档历史数据
5. 执行spitr 基于时间点的表空间恢复
1. 检查endian format,查看是否需要使用rman convert 转化endian(如果是相同平台可以忽略这一步)。
2. 选择一个自包含的表空间集合。
3. 在源库端,将表空间置为read only模式,并且生成可传输的表空间集合。(export metadatawith transportable tablespace)
4. 传输表空间集合(使用scp或者其他的传输方式将expdp导出的元数据以及数据文件发送到目标服务器上)
5.恢复表空间为read write模式(可选)
6.在目标端,导入表空间结合(import metadata)
test@ORCL>
SELECT d.PLATFORM_NAME, ENDIAN_FORMAT
FROM V$TRANSPORTABLE_PLATFORM tp, V$DATABASE d
WHERE tp.PLATFORM_NAME = d.PLATFORM_NAME;
PLATFORM_NAME ENDIAN_FORMAT
-------------------------------------------------------------------------------------------------------------------
Linux x8664-bit Little
test@ORCL>
SELECT * FROM V$TRANSPORTABLE_PLATFORM ORDER BYPLATFORM_NAME;
PLATFORM_IDPLATFORM_NAME ENDIAN_FORMAT
------------------------------------------------------------------------------------------------------------------------------
6 AIX-Based Systems(64-bit) Big
16 Apple MacOS Big
19 HP IA OpenVMS Little
15 HP OpenVMS Little
5 HP Tru64UNIX Little
3 HP-UX (64-bit) Big
4 HP-UX IA(64-bit) Big
18 IBM Power BasedLinux Big
9 IBM zSeries BasedLinux Big
10 Linux IA(32-bit) Little
11 Linux IA(64-bit) Little
13 Linux x8664-bit Little
7 Microsoft Windows IA(32-bit) Little
8 Microsoft Windows IA(64-bit) Little
12 Microsoft Windows x8664-bit Little
17 Solaris Operating System(x86) Little
20 Solaris Operating System(x86-64) Little
1 Solaris[tm] OE(32-bit) Big
2 Solaris[tm] OE(64-bit) Big
19 rows selected.
这里都是用Linux x86 64-bit 都是little endian 所以不需要使用rman convert 转换
(记得转换前先设置 表空间 read only 状态,保证数据文件在一个一致性的状态)
test@ORCL>
select t.name , d.name from v$tablespace t,v$datafile d where t.ts#=d.ts# ;
NAME NAME
------------------------------------------------------------------------------------------------------------------------
SYSTEM /u01/apps/oracle/oradata/orcl/system01.dbf
UNDOTBS1 /u01/apps/oracle/oradata/orcl/undotbs01.dbf
SYSAUX /u01/apps/oracle/oradata/orcl/sysaux01.dbf
USERS /u01/apps/oracle/oradata/orcl/users01.dbf
EXAMPLE /u01/apps/oracle/oradata/orcl/example01.dbf
IOTTBS /u01/apps/oracle/oradata/orcl/iottbs01.dbf
IOTEXTBS /u01/apps/oracle/oradata/orcl/iotextbs01.dbf
UNDOTBS1 /u01/apps/oracle/oradata/orcl/undotbs02.dbf
DEXTBS /u01/apps/oracle/oradata/orcl/dextbs01.dbf
SQLTDBS /u01/apps/oracle/oradata/orcl/sqlttbs01.dbf
10 rows selected.
传输iotextbs 表空间对应数据文件
/u01/apps/oracle/oradata/orcl/iotextbs01.dbf
如果没有输出,表示是自包含的表空间
sys@ORCL> EXECUTEDBMS_TTS.TRANSPORT_SET_CHECK('iotextbs',true) ;
PL/SQL procedure successfully completed.
sys@ORCL> SELECT * FROM TRANSPORT_SET_VIOLATIONS;
no rows selected
3.1 设置表空间为read only
altertablespace IOTEXTBS read only ;
3.2 exportmetadata
mkdir -p/u01/apps/oracle/tts_dir
create directory tts_dir as'/u01/apps/oracle/tts_dir' ;
expdp system/xiaojundumpfile=tts_iotextbs.dmp directory=tts_dir transport_tablespaces=iotextbslogfile=exp_tts_iotextbs.log
3.3(这里是同平台,所以不必转换,下面给出的是示例语句)
rman convert
CONVERT TABLESPACEsales_1,sales_2
TO PLATFORM 'Microsoft Windows IA (32-bit)'
FORMAT '/tmp/%U';
altertablespace IOTEXTBS read write ;
impdpsystem/xiaojundumpfile=tts_iotextbs.dmp directory=tts_dir transport_datafiles=/u01/oinsdir/ottbs01.dbf remap_schema=test:dexter logfile=tts_import.log
以下是测试过程
source |
target |
|
sid |
gg1 |
gg2 |
schema |
dexter |
dex |
tablespace |
dextbs,dextertbs |
dextbs,dextertbs |
ip |
192.168.100.20 |
192.168.100.21 |
sys@GG1> create tablespace dextbs datafile'/u01/apps/oracle/oradata/gg1/dextbs01.dbf' size 10m autoextend on next 100m ;
Tablespace created.
sys@GG1> create tablespace dextertbs datafile'/u01/apps/oracle/oradata/gg1/dextertbs01.dbf' size 10m autoextend on next 100m;
Tablespace created.
create table test01 tablespace dextbs as selectlevel id , level || 'name' as name from dual connect by level <= 10000;
create table test02 tablespace dextertbs asselect level id , level || 'name' as name from dual connect by level <=10000;
alter table test01modify id primary key ;
alter table test02 add constraint fk_test02_id foreign key (id)references test01(id) ;
只看主表所在的表空间(因为关系是由子表来维护的,所以单独迁移主表所在的表空间没有影响)
sys@GG1> EXECUTEDBMS_TTS.TRANSPORT_SET_CHECK('dextbs',true) ;
PL/SQL procedure successfully completed.
sys@GG1> SELECT * FROMTRANSPORT_SET_VIOLATIONS;
VIOLATIONS
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
ORA-39908: Index DEXTER.SYS_C0011314 in tablespace USERS enforces primaryconstraints of table DEXTER.TEST01 in tablespace DEXTBS.
如上所示
主键的索引SYS_C0011314在users表空间里面,不是自包含。
有两种解决办法
1. 包含users表空间
2. 将索引move到dextbs表空间中
sys@GG1> alter index DEXTER.SYS_C0011314rebuild tablespace dextbs ;
Index altered.
sys@GG1> EXECUTEDBMS_TTS.TRANSPORT_SET_CHECK('dextbs',true) ;
PL/SQL procedure successfully completed.
sys@GG1> SELECT * FROM TRANSPORT_SET_VIOLATIONS;
no rows selected
这个时候说明只迁移主表空间dextbs是可以的,没有任何问题。
我们看只包括子表的表空间
sys@GG1> EXECUTEDBMS_TTS.TRANSPORT_SET_CHECK('dextertbs',true) ;
PL/SQL procedure successfully completed.
sys@GG1> SELECT * FROM TRANSPORT_SET_VIOLATIONS;
VIOLATIONS
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
ORA-39906: Constraint FK_TEST02_ID between table DEXTER.TEST01 in tablespaceDEXTBS and table DEXTER.TEST02 in tablespace DEXTERTBS.
这里就因为外键的关系有报错信息了。
sys@GG1> EXECUTEDBMS_TTS.TRANSPORT_SET_CHECK('dextertbs,dextbs',true) ;
PL/SQL procedure successfully completed.
sys@GG1> SELECT * FROM TRANSPORT_SET_VIOLATIONS;
no rows selected
ok 没问题了,下面就可以迁移dextertbs , dextbs 两个表空间了
sys@GG1> alter tablespace dextbs read only ;
Tablespace altered.
sys@GG1> alter tablespace dextertbs read only ;
Tablespace altered.
expdpsystem/xiaojun dumpfile=tts_dextbs_dextertbs.dmpdirectory=tts_dir transport_tablespaces=dextbs,dextertbslogfile=exp_tts_dextbs_dextertbs.log
以下内容就不详细些出来了,注意:
目标数据库中药导入的用户必须存在否则报错