因为业务的需要,经常要将正式库中的表导出导入到测试库中,现将笔者曾经遇到的问题小结如下:
一、数据库系统环境,版本不一致造成的错误
1.NLS_LENGTH_SEMANTICS参数设置不一致
[oracle@dba ~]$ expdp user/pass directory=bak_dir dumpfile=test.dmp tables=test
KUP-11007: conversion error loading table "USER"."TEST"
ORA-12899: value too large for column BANK_NAME (actual: 63, maximum: 60)
KUP-11009: data for row: BANK_NAME : 0X'E4B8ADE59BBDE5B7A5E59586E993B6E8A18CE58C97E4BAACE9'
检查两端服务器的字符集情况,发现一致 查询NLS_CHARACTERSET(数据库字符集),NLS_NCHAR_CHARACTERSET(国家字符集)
SQL> SELECT * FROM V$NLS_PARAMETERS WHERE PARAMETER IN ('NLS_CHARACTERSET', 'NLS_NCHAR_CHARACTERSET');
PARAMETER VALUE
------------------------- --------------------
NLS_CHARACTERSET AL32UTF8
NLS_NCHAR_CHARACTERSET AL16UTF16
在源端数据库
SQL> select * from v$nls_parameters where parameter = 'NLS_LENGTH_SEMANTICS';
PARAMETER VALUE
------------------------- --------------------
NLS_LENGTH_SEMANTICS CHAR(字符)
但是在目标端
SQL> select * from v$nls_parameters where parameter = 'NLS_LENGTH_SEMANTICS';
PARAMETER VALUE
------------------------- --------------------
NLS_LENGTH_SEMANTICS BYTE (字节)
一般认为当时数据库和系统的语言字符集一样时,应该不会出现字符不一致情况,但是事实是我们会往往忽略掉很多oracle细 节的参数。
参数NLS_LENGTH_SEMANTICS的含义在Oracle文档中这样描述:
Syntax: NLS_LENGTH_SEMANTICS = string Range of values: BYTE | CHAR NLS_LENGTH_SEMANTICS enables you to create CHAR and VARCHAR2 columns using either byte or character length semantics. Existing columns are not affected. NCHAR, NVARCHAR2, CLOB, and NCLOB columns are always character-based. You may be required to use byte semantics in order to maintain compatibility with existing applications. NLS_LENGTH_SEMANTICS does not apply to tables in SYS and SYSTEM. The data dictionary always uses byte semantics.
该 初始化参数NLS_LENGTH_SEMANTICS用于指定CHAR列或VARCHAR2列的长度定义方式,默认值为BYTE。由此我们可知,不仅系统和数据 库的语言环境需要一致外,还需要注意VARCHAR2和CHAR列还有额外的定义,及定义字符列为字节长度方式和字符个数方式。
这就很好理解报错ORA-12899错误了,源端字符列存放方式是字符型,也就是说一个汉字只需要一个字符数存放就可以了,如果插入到字符列是 BYTE的,则一个汉字就需要3个字节。
此种情况只能将目标端设置成相同的字符型,然后重启生效
ALTER SYSTEM SETNLS_LENGTH_SEMANTICS=CHAR scope=BOTH;
需特别注意此参数NLS_LENGTH_SEMANTICS 更改后对现有列不受修改影响!!所以在最初搭建数据库时就要设置一样,以免带来 不必要的麻烦!
2.数据库版本不同造成的问题
数据泵导入导出,属于数据元的移动,可以跨版本传输,低版本导入到高版本中默认是兼容。如果由于特殊的需求,必须要从高版本中导入到低版本,则我们只需要在高版本导出时加上版本号就可以解决此类问题。
例如11G导入到10G中
从11G导出时加上要导入到的数据库version:
expdp user/pass directory=bakdir dumpfile=test.dmp tables=test version=10.2.0.4
在10G中导入:
impdp user/pass directory=bakdir dumpfile=test.dmp version=10.2.0.4 table_exists_action=truncate
二、数据库参数设置不当造成的导入导出问题
1.stream_pool设置问题
[oracle@pos ~]$ impdp user/pass directory=bakdir dumpfile=test.dmp remap_schema=posmadm:pospadm table_exists_action=truncate
UDI-31623: operation generated ORACLE error 31623
ORA-31623: a job is not attached to this session via the specified handle
ORA-06512: at "SYS.DBMS_DATAPUMP", line 3326
ORA-06512: at "SYS.DBMS_DATAPUMP", line 4551
ORA-06512: at line 1
报错信息查不到任何有用信息,只有进入trace中查看日志信息
[oracle@dba ~]$ cd $ORACLE_TRACE
[oracle@dba trace]$ tail -100 alert_sid.log 查看告警日志
Errors in file u01/app/oracle/diag/rdbms/pos/pos/trace/pos_ora_13691.trc (incident=12281):
ORA-04031: unable to allocate 56 bytes of shared memory ("streams pool","unknown object","streams pool","fixed allocation callback")
从报错信息中可以看到,streams pool没有值造成错误,为什么数据泵要从streams pool中分配内存呢?
查阅资料我们知道,data pump数据泵在11g中开始用Advanced Queue高级队列来控制其job作业的启动、停止和重启了。
如果streams pool的当前size为0,那么显然无法分配到任何内存;而当前系统中就只设置了AMM特性的memory_target内存参数 ,并没有显式地设置streams_pool_size参数,这就导致了问题的发生。
SQL> select name,isinstance_modifiable from v$system_parameter where name='streams_pool_size';
应该是true的模式
SQL> select * from v$sgainfo; 发现streams pool没有大小,这是因为安装数据库时没有指定大小的原因
Streams Pool Size 0 Yes
SQL> alter system set streams_pool_size =512m scope=spfile;
给streams pool设置大小,重启生效后再次导入就没有问题了
2.导入导出时遇到主外键问题
当要导出具有外键约束的表时,我们需要先将外键约束失效后,再导出导入,再将外键约束生效。
查询user用户下哪些表有外键约束
SQL> select CONSTRAINT_NAME,CONSTRAINT_TYPE,TABLE_NAME,R_CONSTRAINT_NAME from all_constraints where constraint_type='R' and owner='USER';
使外键约束失效
ALTER TABLE tablename DISABLE CONSTRAINT constraint_name;
如果要批量失效外键可以这样写
select 'alter table '||table_name||' disable constraint '||constraint_name||' ;' from all_constraints where constraint_type='R' and owner='USER';
导入完成后生效外键约束
ALTER TABLE tablename enable CONSTRAINT constraint_name ;
目前数据泵导入导出就遇到上述问题,以后会不断补充。




