Oracle TTS From windows to linux +ASM

前言

一直想试试Oracle的TTS迁移方案,刚好公司最近有项目需要进行已购平台的数据库迁移,正好派上用场。以下为大致过程,具体细节不做描述,只概括主要操作。

环境

源端

项目 说明
操作系统 Microsoft Windows 7 64位
endianness格式 little
数据库版本 11.2.0.1

目标端

项目 说明
操作系统 CentOS 6.3 64位
endianness 格式 little
数据库版本 11.2.0.4

操作

查看字符集

1
2
3
SQL>SELECT *  
FROM NLS_DATABASE_PARAMETERS T
WHERE T.PARAMETER LIKE '%CHARACTERSET';

如果字符集不一致,需要修改字符集:

1
2
3
4
5
6
7
8
9
SQL> SHUTDOWN IMMEDIATE
SQL> STARTUP MOUNT
SQL> ALTER SYSTEM ENABLE RESTRICTED SESSION;
SQL> ALTER SYSTEM SET JOB_QUEUE_PROCESSES=0;
SQL> ALTER SYSTEM SET AQ_TM_PROCESSES=0;
SQL> ALTER DATABASE OPEN
SQL> ALTER DATABASE NATIONAL CHARACTER SETINTERNAL_USE UTF8;
SQL> SHUTDOWN IMMEDIATE
SQL> STARTUP

检查db time zone

源端和目标端的db time zone 是否一致:

1
SQL> SELECT version FROM v$timezone_file;

Oracle 9i 的time zone 文件version是1,10g 是2,到了11gR2,time zone files 可以从1到14.
默认情况下:
11.2.0.1 的time zone 是11。
11.2.0.2的time zone 是14。
11.2.0.3的time zone 是14。
如果time zone 不同,那么在import 时会报ORA-39322 的错误,不过该问题已在11.2.0.4解决 。

查看要迁移表空间文件

1
2
3
SQL> SELECT FILE_NAME
FROM DBA_DATA_FILES T
WHERE T.TABLESPACE_NAME = 'TablespaceName'

表空间检查

TTS 仅支持对象都在要传输的表空间里,表空间里的对象不能与其他表空间有逻辑上或者物理上的依赖关系。
可以使用TRANSPORT_SET_CHECK过程来检查表空间是否自包含。调用该过程需要EXECUTE_CATALOG_ROLE角色。
检查表空间自包含:

1
SQL> EXECUTE DBMS_TTS.TRANSPORT_SET_CHECK('TablespaceName', TRUE);

dbms_tts 检查自包含的结果可以通过TRANSPORT_SET_VIOLATIONS视图查看,如果为空,就是自包含,如果不是自包含的,会列出这些对象。

1
SQL> SELECT * FROM TRANSPORT_SET_VIOLATIONS;

设置表空间为只读

1
SQL> ALTER TABLESPACE TablespaceName READ ONLY;

创建datapump目录

  • 源端:

    1
    SQL>create directory backup as 'F:\datapump';
  • 目标端:

    1
    SQL>create directory backup as '/home/oracle/datapump';

    源端导出表空间元数据

  • 使用expdp:

    1
    2
    3
    $expdp \'/ as sysdba\' dumpfile=expdat.dmp directory=backup transport_tablespaces=TablespaceName transport_full_check=y 
    logfile=expdat.log
    Username: /as sysdba
  • 使用exp:

    1
    2
    3
    exp userid=\'/ as sysdba\' transport_tablespace=y 
    tablespaces=TablespaceName file=expdat.dmp log=expdat.log
    statistics=none

    上传表空间原始数据至目标端datapump目录

上传表空间数据文件至目标端数据库数据文件存储目录

1
ASMCMD> cp /home/grid/temp/file.DBF +data/datafile/file.DBF

查看平台及字节序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
SQL> column platform_name format a40
SQL> column endian_format format a40
SQL> SELECT A.PLATFORM_NAME
,A.ENDIAN_FORMAT
FROM V$TRANSPORTABLE_PLATFORM A
,V$DATABASE B
WHERE A.PLATFORM_NAME = B.PLATFORM_NAME;
目标端:
PLATFORM_NAME ENDIAN_FORMAT
------------------------------------ --------------
Linux x86 64-bit Little
源端:
PLATFORM_NAME ENDIAN_FORMAT
------------------------------------ --------------
Microsoft Windows IA (32-bit) Little

endianness转换

如果TTS在不同的平台上,并且ENDIAN_FORMAT也不同,那么就需要先使用RMAN 进行endianness的转换,这个过程可以在Source 端处理,也可以在Target 处理。

  • 源端处理:

源端只能使用 covert tablespace。

1
RMAN> CONVERT TABLESPACE TablespaceName1,TablespaceName2 TO PLATFORM 'PLATFORM_NAME' DB_FILE_NAME_CONVERT='/oradata/datafile/','/tmp/' FORMAT '/tmp/%U';
  • 目标端处理:

源端只能使用 covert datafile。先将datafile从source 端拷贝到Target ,然后在Target 端进行转换。

1
2
3
RMAN> CONVERT DATAFILE     '/tmp/file.dbf'
TO PLATFORM="Linux IA (32-bit)" FROM PLATFORM="HP TRu64 UNIX"
DB_FILE_NAME_CONVERT="/tmp/","+data/datafile/";

查询源端使用了相应表空间的用户

1
2
3
SQL> SELECT DISTINCT OWNER
FROM DBA_SEGMENTS T
WHERE T.TABLESPACE_NAME = 'TablespaceName';

目标端创建相应用户

将上一步列出的用户在目标端创建

1
SQL> create user username identified by "pwd";

导入数据

  • 使用impdp:

    1
    $ impdp \'/ as sysdba\' directory=backup dumpfile="expdat.dmp" transport_datafiles=+data/datafile/file.DBF logfile=expdat.log   

    如果目标端与源端schema不对应,使用remap_chema参数对应,如remap_schema=schema1:user1 remap_schema=schema2:user2

如果表空间在Target上已经存在,那么可以使用remap_tablespace 参数来进行表空间的转换

  • 使用imp

    1
    $ imp userid=\'/ as sysdba\' TRANSPORT_TABLESPACE=Y datafiles=/database/db101b2/V101B2/datafile/reposit01.dbf file=tts.dmp log=imp_tts.log 

    将表空间设置为读写模式

    1
    SQL> alter tablespace TablespaceName read write;

    修改用户默认表空间

如果涉及用户默认表空间发送更改,需要修改用户的默认表空间

1
SQL> alter user username default tablespace TablespaceName;