再将B的数据文件头与A的数据文件内容合并在一起,
就能识别了。
举个9i的例子
1. 找出文件头大小. 以都有的user表空间数据文件查询即可出来。
Linux 平台:
select file_name,bytes from dba_data_files where tablespace_name='USERS';
!ls -l /u01/app/oracle/oradata/orcl2/users01.dbf
SQL> select file_name,bytes from dba_data_files where tablespace_name='USERS';
FILE_NAME
--------------------------------------------------------------------------------
BYTES
----------
/u01/app/oracle/oradata/orcl2/users01.dbf
5242880
SQL> !ls -l /u01/app/oracle/oradata/orcl2/users01.dbf
-rw-r-----. 1 oracle oinstall 5251072 Feb 22 15:31 /u01/app/oracle/oradata/orcl2/users01.dbf
SQL> select 5251072 - 5242880 from dual;
5251072-5242880
---------------
8192 Windows 平台:
SQL> select file_name,bytes from dba_data_files where tablespace_name='USERS';
FILE_NAME
--------------------------------------------------------------------------------
BYTES
----------
C:\ORACLE\ORADATA\XCLDB\USERS01.DBF
5242880
SQL> host dir C:\ORACLE\ORADATA\XCLDB\USERS01.DBF
驱动器 C 中的卷是 OS
卷的序列号是 C8C0-48C4
C:\ORACLE\ORADATA\XCLDB 的目录
2014/02/22 16:06 5,251,072 USERS01.DBF
1 个文件 5,251,072 字节
0 个目录 62,898,417,664 可用字节
SQL> select 5251072 - 5242880 from dual;
5251072-5242880
---------------
8192
8192 字节即为文件头大小. 两边都相同
2. 更改文件头
我自己写了个更新文件头的程序。UNIX/Linux下可以用dd命令。
/*************************************************
Author: xiongchuanliang
Description: 更新Oracle数据文件头
**************************************************/
#include
#include
#include
#define HEADESIZE 8192
#define MAXLEN 200
//将目标端的文件头提取出来
int getDestHeader(const char * fileName,unsigned char *fileHeader);
//用提取出来的文件头替换掉原来的文件头
int updateHeader(const char * fileName,unsigned char *fileHeader);
int main(void)
{
char sourceFile[MAXLEN] = {0};
char headerFile[MAXLEN] = {0};
printf("跨平台表空间传输\n");
printf("同字节序文件的跨平台测试(10g以下)\n");
//"C:\\tmp\\lx\\tbs_trans_01.dbf1"
printf("将从源数据库传到本地临时目录的数据文件路径。\n");
printf("输入源平台数据文件如(C:\\tmp\\lx\\tbs_trans_01.dbf):\n");
scanf ("%199s",sourceFile);
//C:\oracle\oradata\xcldb\USERS01.DBF1
printf("从本地数据文件中任选一个取出文件头,替换源平台原有的文件头。\n");
printf("输入本地数据文件(如C:\\oracle\\oradata\\xcldb\\USERS01.DBF):\n");
scanf ("%199s",headerFile);
unsigned char destHeader[HEADESIZE] = {0};
if( getDestHeader(headerFile,destHeader) == 0)
{
updateHeader(sourceFile,destHeader);
}
return 0;
}
//将目标端的文件头提取出来
int getDestHeader(const char * fileName,unsigned char *fileHeader)
{
if(fileName == NULL) return -1;
//将目标端的文件头提取出来
FILE * fpDest = fopen(fileName,"rb");
if(fpDest== NULL )
{
printf("文件(%s)打开失败!\n",fileName);
return -1;
}
fseek(fpDest,0L,SEEK_SET);
size_t readbyte = fread(fileHeader,1, HEADESIZE,fpDest);
if( readbyte <= 0 )
{
printf("文件头读取失败!\n");
fclose(fpDest);
return -1;
}else if(readbyte != HEADESIZE){
printf("读取出的文件头长度(%d)不够,此事必有蹊跷! 请重新检查。\n",readbyte);
fclose(fpDest);
return -1;
}
printf("文件头大小:%d\n",readbyte);
fclose(fpDest);
return 0;
}
//用提取出来的文件头替换掉原来的文件头
int updateHeader(const char * fileName,unsigned char *fileHeader)
{
FILE * fpSource = fopen(fileName,"rb+");
if(fpSource == NULL )
{
printf("文件(%s)打开失败!\n",fileName);
return -1;
}
fseek(fpSource,0L,SEEK_SET);
size_t writebyte = fwrite(fileHeader,sizeof(fileHeader),1,fpSource);
if( writebyte <= 0 )
{
printf("文件头写入失败!\n");
}else{
printf("已替换到文件%s上.\n",fileName);
printf("文件头替换工作顺利完成!\n");
}
fclose(fpSource);
return 0;
}
编译运行程序,输入相关的文件合路径,执行,就能将数据文件头更新成本地的信息了,
至此,imp时就不会报错了。
3. 其它命令和流程与上面的"非跨平台的正常迁移流程"是一样的,关键点就是文件头处理部份不同。
附11gR2支持的平台列表:
SQL> col PLATFORM_NAME for a40
SELECT * FROM v$transportable_platform;SQL>
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
6 A