还是继续昨天的任务,今天会把剩下的工作都做完,给个交代。
昨天完成了Data Guard切换,然后Failover备库,导出了元数据信息作为TTS的准备,亮点就在于导入的部分。无需挪动数据文件,这是补充数据字典信息即可。
这个工作的一个重点内容就是如何保证数据字典信息的完整性。
在目标环境11g中需要创建相应的用户,这一点还是很有技巧的。如果采用impdp的形式直接导入用户,这样不妥,因为我们有设置profile,有临时表空间,默认表空间的信息。
比如下面的用户创建语句:
CREATE USER "TEST" IDENTIFIED BY VALUES '5F712A8369686639'
DEFAULT TABLESPACE "TEST_DATA"
TEMPORARY TABLESPACE "TEMP"
PROFILE "PF_TEST" ;
如果直接导入肯定会失败,因为默认表空间不存在,profile还没有创建。
建议的方式就是手工来完成,这样做的好处就是一次审核通过,正式环境直接运行即可。
如果手工创建,这就牵扯到另外一个问题,那就是对比两个库中的用户信息,源库中有100多个用户,目标库11g的环境有默认的数据库用户,需要排除。
可以使用如下的脚本来过滤。
10g环境运行得到一个列表
spool 10g_user.lst
set feedback off
set pages 0
select username from dba_users;
spool off
11g环境运行得到一个列表
spool 11g_user.lst
set feedback off
set pages 0
select username from dba_users;
spool off
然后对比即可。
sort 10g_user.lst |awk '{print $1}'> 10g_users.lst
sort 11g_user.lst |awk '{print $1}'> 11g_users.lst
sdiff 10g_users.lst 11g_users.lst |less
不过还是实践中的对比和感悟,发现其实还有一个小窍门,那就是直接抽段,使用如下的语句即可快速得到一个列表。
select owner from dba_segments group by owner;
100多个用户的数据库环境,上面的语句会查得不到20个用户,逐一排除都绰绰有余。
这样用户列表的任务就搞定了。可以使用如下的语句得到用户的DDL语句,然后在这个基础上改动临时表空间,默认表空间信息。
select dbms_metadata.get_ddl('USER',u.username) ||';'from dba_users u WHERE USERNAME in ('OEM_MON','APP_TE_SDE','GHOSTOL','TE_GAMEUSER','JYCX','OG_SWORD','TEST','OG_GAMEUSER','PERFSTAT');
得到的语句类似下面的形式,我们简称为create_user.sql
CREATE USER "TE_GAMEUSER" IDENTIFIED BY VALUES 'E62AFD5FC9ED1DD2'
TEMPORARY TABLESPACE "TEMP"
PROFILE "PF_TE_GAMEUSER"
这个时候还有几个小问题,profile的信息怎么解决,也是生成DDL,其实也可以换个方法,那就是impdp
先在11g的库中创建一个目录。
CREATE DIRECTORY EXT_DIR AS '/export/home/oracle/HF';
然后导入profile信息即可。
$ impdp \'sys/oracle as sysdba\' dumpfile=full_exclude_tab.dmp logfile=full_ddl.log directory=EXT_DIR include=PROFILE CONTENT=METADATA_ONLY
然后运行create_user.sql语句即可。
这样倒入数据字典的用户信息就准备好了。
我们停止10g的主库,把数据文件都释放出来。
创建一个parfile,类似下面的形式:
tablespaces=USERS,GHOSTOL_DATA,GHOSTOL_INDEX,TEST_DATA,TEST_INDEX,PERFSTAT,STAT_POINT,TEST_MV_DATA,TEST_MV_INDEX,TEST_AUDIT_DATA,JYCX_DATA,OEM_DATA,TEST_INDEX2,TEST_INDEX3,SWDONLINE_DATA,SWDONLINE_INDX,STORELOG_DATA,STORELOG_INDX,OEM_MON_TEST,USERCENTER_DATA
datafiles=/U01/app/oracle/oradata/TEST/stat_point_01.dbf
,/U01/app/oracle/oradata/TEST/TEST_mv_data_01.dbf
,/U01/app/oracle/oradata/TEST/users01.dbf
,/U01/app/oracle/oradata/TEST/ghostol_data01.dbf
,/U01/app/oracle/oradata/TEST/ghostol_index01.dbf
。。。
然后使用如下的方式导入即可。
imp \'sys/oracle as sysdba\' file=exp_tts_TEST.dmp transport_tablespace= y log=imp_tts_TEST.log parfile=datafiles.par
当然也不是一帆风顺,有一个小问题需要注意。那就是默认表空间USERS已存在,我们需要删除已有的USERS表空间,重置默认表空间,比如我们创建一个表空间中转一下。
> create tablespace def_ts datafile '/U03/app/oracle/oradata/TEST/default_ts.dbf' size 10M;
> alter database default tablespace def_ts;
> drop tablespace users including contents and datafiles cascade constraint;
因为涉及的数据文件很多,如果有遗漏,不匹配,需要格外注意。
IMP-00017: following statement failed with ORACLE error 29347:
"BEGIN sys.dbms_plugts.beginImpTablespace('TS_AUDIT',10,'SYS',1,0,8192,1,2"
"28967869732,1,2147483645,8,128,8,0,1,0,8,1434590011,1,33,68705469137,NULL,0"
",0,NULL,NULL); END;"
IMP-00003: ORACLE error 29347 encountered
ORA-29347: Tablespace name validation failed - failed to match tablespace 'TS_AUDIT'
ORA-06512: at "SYS.DBMS_SYS_ERROR", line 86
ORA-06512: at "SYS.DBMS_PLUGTS", line 1876
ORA-06512: at line 1
IMP-00000: Import terminated unsuccessfully
这个问题就是数据文件信息存在,但是导入的tablespaces参数却不完整,就会出现这类问题。
导入的过程很快,可以从日志进度看出。用不了几分钟。
完成之后,一个大工程总算完成了,还有补充的任务就是导入其它的DDL信息,这个可以impdp的形式全库导入即可。也就3分钟就完事了。
impdp \'sys/oracle as sysdba\' dumpfile=full_exclude_tab.dmp logfile=full_ddl_impdp.log directory=EXT_DIR full=Y CONTENT=METADATA_ONLY
Job "SYS"."SYS_IMPORT_FULL_01" completed with 270 error(s) at Wed Sep 28 16:33:35 2016 elapsed 0 00:03:09
看起来整个过程还是非常平滑的,后续的就是问题跟踪和统计信息收集了,这些都可以按照计划来补充,可以在线完成。
然后惊讶的是11g的库迁移完之后,停掉11g的库,重新打开10g的库,竟然还可以打开,这是不是一种更加平滑的数据库升级,降级。
实践总结总是会让人有不一样的感触和所得,不要相信自己的记忆力,为了方便自己,受益更多的人,还是好记星不如烂笔头。技