深究Oracle 9i和10g之间如何进行传输表空间

关于传输表空间可以参考笔者的这篇文章

http://czmmiao.iteye.com/blog/1260792

当一个Little Endian的系统试图从一个Big Endian的系统中读取数据时,就需要通过转换,否则不同的字节顺序将导致数据不能被正确读取。那么另外一个问题出现了,如果字节序相同的不同平台进行文件交互,数据能否被正确读取呢

理论上的确是可以的,但是由于在不同的平台上操作系统会在数据文件头写上系统信息,这部分信息无法跨越平台,所以仍然会导致跨平台的文件无法被数据库正确识别(Oracle10g中同字节序平台数据文件头不再存在跨平台的迁移问题)。

接下来让我们通过Windows和Linux平台来进行一个跨平台测试,相信通过这个测试可以对以上提出的问题作出一个很好的回答。
实验环境:Windows XP + Oracle10g 10.2.0.1:

SQL> select * from v$version;
BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod
PL/SQL Release 10.2.0.1.0 - Production
CORE 10.2.0.1.0 Production
TNS for 32-bit Windows: Version 10.2.0.1.0 - Production
NLSRTL Version 10.2.0.1.0 - Production

Red Hat Enterprise Linux AS release 3 + Oracle 9iR2 9.2.0.4

SQL> select * from v$version;
BANNER
----------------------------------------------------------------
Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production
PL/SQL Release 9.2.0.4.0 - Production
CORE 9.2.0.3.0 Production
TNS for Linux: Version 9.2.0.4.0 - Production
NLSRTL Version 9.2.0.4.0 - Production

看一下Linux平台,文件头被操作系统保留了8192字节:

SQL> select file_name,bytes from dba_data_files
2 where tablespace_name='USERS';
FILE_NAME BYTES
----------------------------------- ----------
/opt/oracle/oradata/eygle/users.dbf 10485760

SQL> !
[oracle@jumper eygle]$ ll users.dbf
-rw-r----- 1 oracle dba 10493952 Mar 23 10:14 users.dbf
[oracle@jumper eygle]$ exit
exit

SQL> select 10493952 -10485760 diff from dual;
DIFF
----------
8192

Windows平台上数据文件头同样保留了8192字节:

SQL> select file_name,bytes from dba_data_files
2 where tablespace_name='USERS';
FILE_NAME BYTES
--------------------------------------------------- ----------
D:\ORADATA\EYGLE\DATAFILE\O1_MF_USERS_2G8OJYYS_.DBF 5242880

SQL> host dir D:\ORADATA\EYGLE\DATAFILE\O1_MF_USERS_2G8OJYYS_.DBF
驱动器 D 中的卷是 PRIVAT
卷的序列号是 94B0-FD3B

D:\ORADATA\EYGLE\DATAFILE 的目录

2007-03-22 17:41 5,251,072 O1_MF_USERS_2G8OJYYS_.DBF
1 个文件 5,251,072 字节
0 个目录 1,635,913,728 可用字节
SQL> select 5251072 -5242880 diff from dual;
DIFF
----------
8192

可以通过Linux和Windows平台来进行一个小测试实验,这两个平台都是Little Endian的系统:

SQL> select * from v$transportable_platform;

PLATFORM_ID PLATFORM_NAME ENDIAN_FORMAT
----------- ---------------------------------------- --------------
1 Solaris[tm] OE (32-bit) Big
2 Solaris[tm] OE (64-bit) Big
7 Microsoft Windows IA (32-bit) Little
10 Linux IA (32-bit) Little
............
17 rows selected.

首先在Linux下Oracle 9204中创建一个测试表空间:

[oracle@jumper oracle]$ cd oradata/eygle
[oracle@jumper eygle]$ sqlplus "/ as sysdba"
Connected to:
Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production
With the Partitioning option
JServer Release 9.2.0.4.0 - Production

SQL> create tablespace eyglee datafile size 10M;
Tablespace created.

创建测试用户并创建一个测试表:

SQL> create user eyglee identified by eyglee default tablespace eyglee;
User created.

SQL> grant connect,resource to eyglee;
Grant succeeded.

SQL> connect eyglee/eyglee
Connected.
SQL> create table eyglee as select * from dict;
Table created.

SQL> select count(*) from eyglee;
COUNT(*)
----------
477

将表空间设置为只读:

SQL> connect / as sysdba
Connected.

SQL> alter tablespace eyglee read only;
Tablespace altered.

SQL> select file_name from dba_data_files where tablespace_name='EYGLEE';
FILE_NAME
------------------------------------------------------------
/opt/oracle/oradata/eygle/o1_mf_eyglee_309yc9gr_.dbf

压缩文件以方便传输:

[oracle@jumper eygle]$ tar -cvf eyglee.tar o1_mf_eyglee_309yc9gr_.dbf
o1_mf_eyglee_309yc9gr_.dbf
[oracle@jumper eygle]$ gzip eyglee.tar

导出表空间:

[oracle@jumper eygle]$ exp \'/ as sysdba\' tablespaces=eyglee transport_tablespace=y file=trans_eyglee.dmp

Export: Release 9.2.0.4.0 - Production on Sat Mar 24 18:17:32 2007
Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.

Connected to: Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production
With the Partitioning option
JServer Release 9.2.0.4.0 - Production
Export done in ZHS16GBK character set and AL16UTF16 NCHAR character set
Note: table data (rows) will not be exported
About to export transportable tablespace metadata...
For tablespace EYGLEE ...
. exporting cluster definitions
. exporting table definitions
. . exporting table EYGLEE
. exporting referential integrity constraints
. exporting triggers
. end transportable tablespace metadata export
Export terminated successfully without warnings.

[oracle@jumper eygle]$ ll *eyglee*
-rw-r--r-- 1 oracle dba 32985 Mar 24 18:14 eyglee.tar.gz
-rw-r----- 1 oracle dba 10493952 Mar 24 18:13 o1_mf_eyglee_309yc9gr_.dbf
-rw-r--r-- 1 oracle dba 16384 Mar 24 18:17 trans_eyglee.dmp

传输文件到Windows平台:

D:\oradata\EYGLE\DATAFILE>dir *eyglee*
D:\oradata\EYGLE\DATAFILE 的目录

2007-03-24 18:21 32,985 eyglee.tar.gz
2007-03-24 18:21 16,384 trans_eyglee.dmp

D:\oradata\EYGLE\DATAFILE>gzip -d eyglee.tar.gz
D:\oradata\EYGLE\DATAFILE>tar -xvf eyglee.tar
tar: blocksize = 20
x o1_mf_eyglee_309yc9gr_.dbf, 10493952 bytes, 20496 tape blocks

在Windows上创建新用户:

SQL> create user eyglee identified by eyglee;
用户已创建。

SQL> grant connect ,resource to eyglee;
授权成功。

如果此时导入会出现ORA-00600错误:

D:\oradata\EYGLE\DATAFILE>imp '/ as sysdba' tablespaces=eyglee transport_tablespace=y file=trans_eyglee.dmp datafiles=d:\oradata\EYGLE\DATAFILE\o1_mf_eyglee_309yc9gr_.dbf

Import: Release 10.2.0.1.0 - Production on 星期六 3月 24 18:59:23 2007
Copyright (c) 1982, 2005, Oracle. All rights reserved.

连接到: Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options

经由常规路径由 EXPORT:V09.02.00 创建的导出文件
即将导入可传输的表空间元数据...
已经完成 ZHS16GBK 字符集和 AL16UTF16 NCHAR 字符集中的导入
. 正在将 SYS 的对象导入到 SYS
. 正在将 SYS 的对象导入到 SYS
IMP-00017: 由于 ORACLE 错误 600, 以下语句失败:
"BEGIN sys.dbms_plugts.beginImpTablespace('EYGLEE',9,'SYS',1,0,8192,1,1899"
"6106462,1,2147483645,8,128,8,0,1,0,8,1407686520,1,1,18996106397,NULL,0,0,NU"
"LL,NULL); END;"
IMP-00003: 遇到 ORACLE 错误 600
ORA-00600: 内部错误代码, 参数: [krhcvt_filhdr_v10_01], [], [], [], [], [], [], []
ORA-06512: 在 "SYS.DBMS_PLUGTS", line 1801
ORA-06512: 在 line 1
IMP-00000: 未成功终止导入

其中"参数: [krhcvt_filhdr_v10_01]"提示指文件头无法正确识别。
可以通过对这个文件进行一个特殊操作,为文件更换一个Windows下数据文件的文件头,则数据文件就应该能够被数据库识别。以下是这个"小手术"操作的过程。
首先提取一个Windows数据文件头:

D:\oradata\EYGLE\DATAFILE>dd if=O1_MF_USERS_2G8OJYYS_.DBF of=header.dbf bs=8192 count=1
1+0 records in
1+0 records out

然后去除Linux下的数据文件头:

D:\oradata\EYGLE\DATAFILE>dd if=o1_mf_eyglee_309yc9gr_.dbf of=eyglee.dbf bs=8192 skip=1
1280+0 records in
1280+0 records out

最后将这两个文件合二为一:

D:\oradata\EYGLE\DATAFILE>copy /b header.dbf+eyglee.dbf eygleee.dbf
header.dbf
eyglee.dbf

已复制 1 个文件。

关于在linux下如何分割和合并二进制文件,可以参看笔者的另一篇文章

http://czmmiao.iteye.com/blog/1266577

现在拥有的新文件eygleee.dbf就具有了一个Windows平台的文件头以及Linux下的"文件身"。

至此这个文件就能够被Windows上的Oracle识别了,可以执行导入操作:

D:\oradata\EYGLE\DATAFILE>imp '/ as sysdba' tablespaces=eyglee transport_tablespace=y file=trans_eyglee.dmp datafiles=d:\oradata\EYGLE\DATAFILE\eygleee.dbf

Import: Release 10.2.0.1.0 - Production on 星期六 3月 24 19:22:13 2007
Copyright (c) 1982, 2005, Oracle. All rights reserved.

连接到: Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options

经由常规路径由 EXPORT:V09.02.00 创建的导出文件
即将导入可传输的表空间元数据...
已经完成 ZHS16GBK 字符集和 AL16UTF16 NCHAR 字符集中的导入
. 正在将 SYS 的对象导入到 SYS
. 正在将 SYS 的对象导入到 SYS
. 正在将 EYGLEE 的对象导入到 EYGLEE
. . 正在导入表 "EYGLEE"
成功终止导入, 没有出现警告。

此时数据已经能够被正确识别:

SQL> connect eyglee/eyglee
已连接。
SQL> select count(*) from eyglee;

COUNT(*)
----------
477

最后将表空间更改为读写模式,可以进行正常的数据操作:

SQL> connect / as sysdba
已连接。
SQL> alter tablespace eyglee read write;
表空间已更改。
SQL> connect eyglee/eyglee
已连接。
SQL> insert into eyglee select * from eyglee;
已创建477行。
SQL> insert into eyglee select * from eyglee;
已创建954行。
SQL> insert into eyglee select * from eyglee;
已创建1908行。
SQL> commit;
提交完成。
SQL> select count(*) from eyglee;
COUNT(*)
----------
3816

通过这个实验,还可以得出另外一个结论,Oracle 9i的数据文件可以通过表空间传输迁移到Oracle 10g中使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值