1、环境
1.1、源库
源库:11g
实例:TESTDB
用户名:TESTDATA
1.2、目标库
目标库:11g
实例:A_TEST
用户名:TESTDATA
2、迁移预检
执行数据迁移的预检测动作,检测内容如下:
2.1、源端表空间名称、数据量检测
select distinct tablespace_name from dba_segments where owner in ('TESTDATA');
select owner, sum(bytes/1024/1024) M from dba_segments where owner in
('TESTDATA') group by owner order by 1;
2.2、目标端用户、表空间、数据量检测
select distinct tablespace_name from dba_data_files order by 1;
select username, default_tablespace from dba_users where username in
('TESTDATA') order by 1;
select owner, sum(bytes/1024/1024) M from dba_segments where owner in
('TESTDATA') group by owner order by 1;
2.3、目标库连接状态检查
如果目标端有数据,需要检查并杀掉连接会话,将对应数据删除
select username, service_name, sid, serial# from v$session where owner in
('TESTDATA') order by 1, 2;
2.4、目标库空间剩余校验
查询数据库表空间大小:
select distinct tablespace_name, maxbytes/1024/1024 M, autoextensible from
dba_data_files order by 1;
如果目标库表空间不够,则根据情况添加数据文件或扩大当前数据文件(测试库使用OMF):
alter tablespace TESTDATA add datafile size 2G autoextend on next 200M;
select file_name,tablespace_name,bytes/1024/1024 M,maxbytes/1024/1024
M,autoextensible from dba_data_files order by 1;
alter database datafile 文件路径/xxx.dbf autoextend on maxsize 32G;
3、填写remap tablespace信息
若发现目标库有不存在的表空间,根据预检查的结果信息并结合实际情况,选择新建表空间或者将源端的表空间通过REMAP参数转为目标库中的表空间,在本例中目标库有TESTDATA、MONDATA等多个表空间,而目标端只有一个RSBDATA表空间,这里选择的使用REMAP参???
remap_tablespace=MONDATA:TESTATA,TESTHIS01:TESTDATA...
目标端新建表空间:
create tablespace xxx datefile size 2G autoextend on next 200M;
4、开始迁移
4.1、目标库创建目录
create or replace directory dir1211 as '/oradata/dump';
4.2、创建DBLINK
create public database link dblink1211 connect to username identified by "xxx"
using
'(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=db1.a_comastar.hfbankpre)(PORT=1521)))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=TESTDB)))’;
本测试环境中使用通用用户tmuser,可以根据个人需要更换;连接串中HOST可以用IP地址也可以用示例中的资源名。
4.3、查看DBLINK是否创建成功
select 1 from dual@dblink1211;
若返回1则创建成功。
附:查看dblink创建语句
1、查看dba_db_links视图
此视图不能查看完整的创建语句,但是可以获得创建语句所需要的信息(dblink名、username、连接串)
2、dbms_metadata .get_ddl
select object_name,object_type from dba_objects where object_name='dblink_name';
SELECT dbms_metadata .get_ddl('DB_LINK','dblink_name','owner') from dual;
4.4、开始迁移
退出SQL
nohup impdp \"/ as sysdba \" network_link=dblink1211 directory=dir1211
schema=TESTdbremap_tablespace=MONDATA:TESTATA,TESTHIS01:TESTDATA...
logfile=dire1211.log &
附:impdp中常用的参数:
schemas=schema_name[,…]
说明:nodefault。导入用户。
tables=[schema_name.]table_name[:partition_name][,…]
说明:nodefault。导入表。
tablespaces=tablespace_name[,…]
说明:nodefault。导入表空间。
REMAP_TABLE=[schema.]old_tablename[.partition]:new_tablename
说明:nodefault。允许导入期间重命名表名。
REMAP_SCHEMA=source_schema:target_schema
说明:nodefault。允许导入期间重命名schema名。
REMAP_TABLESPACE=source_tablespace:target_tablespace
说明:nodefault。允许导入期间重命名表空间名。
TABLE_EXISTS_ACTION=[SKIP | APPEND | TRUNCATE | REPLACE]
说明:default:skip。
4.5、删除DBLINK
迁移成功后登录SQLPLUS删除DBLINK
drop public database link dblink1211;
5、CREATE TABLE
当迁移表格数据时,在创建完成DBLINK后,可以直接在目标库上使用create table语句直接创建需要迁移的表格。
只需要知道源库和目标库的用户名、dblink名和需要迁移的表格名即可,不需要知道表空间名。
5.1、语句
创建dblink的语句没有什么区别,下面主要讲create table语句。
create table new_schema.table_name as select from
old_schema.table_name@dblink_name;
5.3、执行
在创建完成全部create语句后,可以写一个.sql的脚本,格式参考如下:
sqlplus / as sysdba <<EOF
create table . . . ;
.
.
.
exit
EOF
写完脚本后同样可以使用nohup命令放到后台来执行,这里可以指定一个日志文件来记录报错
nohup ./name.sql >name.log &
可以在日志中看到create是否有报错。
5.3、缺点
到目前为止,相对impdp来讲,输出日志除非自己另外再写语句,否则无法了解迁移的数据量和详细日志,也无法直观的查看当前执行到哪一条语句,虽然可以通过编写脚本、语句等方法来解决这一问题,但对于所需迁移的表格数量较大的情况下,效率可能不如impdp的方法。
6、迁移中遇到的问题
6.1、表空间不存在
第一次迁移测试的nohup.out中显示,有几个表迁移失败,原因是几个表空间不存在,这是因为源库中这些表空间可能有表但没有数据,所以select时并没有显示;还是用REMAP参数,然后迁移成功。
6.2、用户被锁
接上个问题,第一次迁移失败后,重新尝试时迁移又失败,经过查看报错确定是TMUSER用户被锁(报错信息忘记截图了,下次有机会补上。。。)
select username,account_status from dba_users where username = 'TMUSER';
alter user TMUSER account unlock;
6.3、ORA-31679
某次dblink导入数据时遇见了ORA-31679错误:
ORA-31679: Table data object xxx has long columns, and longs can not be
loaded/unloaded using a network link
解决方法:dblink无法导入long columns,这里采取的解决方案是用expdp单独把表导出来,然后用impdp导入,注意导入时先在目标库将该表删除,或添加append。
6.4、dblink强制关闭
某次导数过程中,突然发现dblink中连接串配置错误,于是按了CTRL+C,进入import命令行,这里执行STOP_JOB就可以了。如果没有执行KILL_JOB就退出了,可以尝试登录数据库,查看dba_datapump_jobs视图,然后用drop table语句删除相应表。
6.5、ORA-31693,ORA-00001
某次导数过程中报错:
ORA-31693: Table data object “xxx”.“xxx” failed to load/unload and is being
skipped due to error:
ORA-00001: unique constraint (SYS.xxx) violated
解决方法:在impdp语句中加入 DATA_OPTIONS=SKIP_CONSTRAINT_ERRORS参数可以在导入数据的时候,忽略掉违反约束的数据,而使得其他正常的数据顺利的导入。
6.6、ORA-39171,ORA-01653
ORA-39171: Job is experiencing a resumable wait.
ORA-01653: unable to extend table xxx by n in tablespace xxx
解决方法:一般是因为磁盘空间不足,因此表空间无法扩展。先查询磁盘空间是否使用完:df -g/df- Th
确定是磁盘空间不够就需要扩容。
附:Restart Datapump
1、执行 CTRL+C 停止导入任务;
2、在import命令行执行STOP_JOB;
3、磁盘扩容;
4、 找到对应的DATAPUMP_JOB;
SELECT * FROM DBA_DATAPUMP_JOBS;
5、使用attach参数进入交互模式并执行START_JOB
impdp \"/ as sysdba \" attach=SYS_IMPORT_FULL_01
### 6.7、ORA-31631,ORA-39149
接6.6,第二天磁盘问题修复后重新导数,刚开始发现其中一个用户显示表不存在,所以在跑完一遍后单独导了一下这个用户,结果报了以下错误:
ORA-31631: privileges are required
ORA-39149: cannot link privileged user to non-privileged user
我又尝试跑全部用户的,结果还是报这个错误,解决的方法其实很简单,在源库中赋予相应用户exp_full_database权限即可:
GRANT exp_full_database to username;
### 6.8、ORA-06512,ORA-39070
ORA-39002: invalid operation
ORA-39070: Unable to open the log file.
ORA-29283: invalid file operation
ORA-06512: at “SYS.UTL_FILE”, line 475
ORA-29283: invalid file operation
create or replace directory dir1211 as '/oradata/dump';
创建目录的路径/oradata/dump不存在,创建/oradata/dump目录或者查看之前创建目录的路径。
6.9、ORA-01017,ORA-02063
ORA-01017: invalid username/password; logon denied
ORA-02063: preceding line from <link_name>
创建的dblink中使用的用户(源库中)不存在,或者密码不正确。
在源库中查看用户是否存在,如果不存在则创建一个用户并授予dba权限,或者使用system用户。如果存在则重置一下密码后重新创建dblink。




