主要讲一下关于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 基于时间点的表空间恢复
在线传输表空间的工作流程(processes)
1. 检查endian format,查看是否需要使用rman convert 转化endian(如果是相同平台可以忽略这一步)。
2. 选择一个自包含的表空间集合。
3. 在源库端,将表空间置为read only模式,并且生成可传输的表空间集合。(export metadatawith transportable tablespace)
4. 传输表空间集合(使用scp或者其他的传输方式将expdp导出的元数据以及数据文件发送到目标服务器上)
5.恢复表空间为read write模式(可选)
6.在目标端,导入表空间结合(import metadata)
示例一
1、查看目标和源端的endian是否相同
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 状态,保证数据文件在一个一致性的状态)
2、选择自包含的表空间
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、生成可传输的表空间集合
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‘;
4、传输数据文件以及expdp导出的meta文件到目标数据库服务器上
5、将源端的表空间置于read write模式
altertablespace IOTEXTBS read write ;
6、将元数据导入到目标数据库中
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
以下内容就不详细些出来了,注意:
目标数据库中药导入的用户必须存在否则报错