暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

数据泵导入遇到的问题总结

M小小虾米 2021-08-04
3051

因为业务的需要,经常要将正式库中的表导出导入到测试库中,现将笔者曾经遇到的问题小结如下:

一、数据库系统环境,版本不一致造成的错误

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 ;


目前数据泵导入导出就遇到上述问题,以后会不断补充。






文章转载自M小小虾米,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论