再次
重拾老本行,很久没干这种活了,这次赶上某省网络分析系统的数据迁移,遭遇问题无数,过程各种心酸,还好最终顺利完成,记之。
一、背景
1、源数据库10.2.0.1,LINUX Redhat AS5.5,没有归档,实际数据量大概4T多点,应用用户3个,表空间3个,原主机除了本地盘上的root根目录没有一点点多于空间;
新目标数据库10.2.0.5,AIX 6100-06,空间足够;
2、时间紧,由于催的太急,又是节前(赶着回家过节哈 ),到了之后算上建库准备、建表空间,导数据的时间只有3天;
3、之前没有任何准备,现场实施组除了应用启停,基本未参与任何过程,第一次碰上这样的数据迁移。
二、割接前准备
到了地方就马不停蹄做各种准备
1、收集各种原库的信息
2、修改新主机系统参数,ulimit和uproc,注:AIX6已经自动开启AIO,无需手动管理了
3、建主机用户建组,
oracle没安装,用原来的10.2.0.5tar包直接解压,修改环境变量
4、将已经mapping到主机上的存储,进行卷管理划分,两边同步了下vg信息,测试了下HACMP的配置和切换
5、DBCA建库
问题1:网络环境比较复杂,AIX没法图形化。
解决:碰到的第一个小问题,好解决,IBM官网上下个VNC包,可以下rpm的包直接rpm安装,也可以下source包smit install安装,现在版本是3.3.3r2。
安装完之后,启动使用和linux的vnc没有任何区别
6、库建完,建数据库用户
7、建数据库表空间,总共建了6个T的表空间,建表空间大概都用了十几个小时。。
写了脚本放在后台自动跑,本来没什么问题,不过还是有点小问题
问题2:我用户root用户写的脚本,脚本中su - oracle中去加数据文件,用nohup执行,每次用户session退出,脚本执行也自动停止了,退出之前jobs查看都是正常的
解决:改到oracle下去执行可以,原因没深究,不过耽误了几个小时时间。
问题3:建了几个文件之后,突然想到建库的时候db_files
木有改,表空间辣么大,表文件辣么多,再次吐了
解决:先修改了db_files scope=spfile,又通过trace重建了下control file,把maxdatafiles改大,后来查了下9i之后controlefile不重建也可以,maxdatafiles会自动扩展,待测试一下。
8、做了一些impdp、expdp的测试,没有考虑改源库为归档,用rman跨平台恢复,因为跨平台之前没测试,也不知道会不会出现什么bug,一旦出现问题,没有补救时间。
(1)在新库通过dblink做impdp测试,省去exdpp过程,不产生dmp,直接从源库进目标库,因为原库主机没空间,主要想用这种方式。
(2)在新库通过@tns做expdp测试,坑爹的发现expdp出来的dmp文件还在源主机上。这个原因查了下,expdp只支持server端,和exp确实不一样,不过后来回头想想,用expdp+dblink参数应该也可以得到想要的结果。
(3)源库expdp、新库impdp
问题4:源库expdp、新库@tns做expdp、都会报
ORA-39006: internal error
ORA-39213: Metadata processing is not available
impdp @dblink都会报另外一个错(没记下来)
解决:当时碰到这个问题,心拔凉拔凉的啊,这要都不行,我还搞p啊,一开始还以为是新库装的有问题,后来根据oerr ora 39213的提示在源库上exec dbms_metadata_util.load_stylesheets就恢复了。
9、用exp/imp的rows=n参数把对象全部导了一遍,用expdp/impdp的content=meta_only参数也可以,后来导数据都用content=DATA_ONLY的参数
三、数据割接过程
系统不是非常重要,比较直接了当,直接申请了2天的停机时间,各种准备完成。
(一)割接时准备
1、停完应用后,杀了下进程,并重启下数据库,停监听,修改监听端口为1522,这里“歘歘歘”连续给我俩当头棒
问题5:停库的时候没去等,直接shutdown abort,结果数据库重启之后就会不断报如下错,然后就自动shutdown了。。
ORA-00600: internal error code, arguments: [kturbleurec1], [], [], [], [], [], [], []
ORA-00600: internal error code, arguments: [4198], [9], [], [], [], [], [], []
SMON: ignoring slave err,downgrading to serial rollback
Tue Sep 25 18:52:35 2012
Errors in file /opt/oracle/admin/cqoas/bdump/cqoas_smon_20699.trc:
ORA-00600: internal error code, arguments: [4137], [], [], [], [], [], [], []
Tue Sep 25 18:52:36 2012
ORACLE Instance cqoas (pid = 15) - Error 600 encountered while recovering transaction (23, 25).
Tue Sep 25 18:52:36 2012
Errors in file /opt/oracle/admin/cqoas/bdump/cqoas_smon_20699.trc:
ORA-00600: internal error code, arguments: [4137], [], [], [], [], [], [], []
ORA-00600: internal error code, arguments: [4198], [9], [], [], [], [], [], []
SMON: ignoring slave err,downgrading to serial rollback
Tue Sep 25 18:52:35 2012
Errors in file /opt/oracle/admin/cqoas/bdump/cqoas_smon_20699.trc:
ORA-00600: internal error code, arguments: [4137], [], [], [], [], [], [], []
Tue Sep 25 18:52:36 2012
ORACLE Instance cqoas (pid = 15) - Error 600 encountered while recovering transaction (23, 25).
Tue Sep 25 18:52:36 2012
Errors in file /opt/oracle/admin/cqoas/bdump/cqoas_smon_20699.trc:
ORA-00600: internal error code, arguments: [4137], [], [], [], [], [], [], []
解决:查了一下,undo段有坏块,用了*._allow_resetlogs_corruption=true、*._corrupted_rollback_segments=(_SYSSMU10$)两个隐藏参数和pfile起库解决。
问题6:修改listener.ora的监听端口为1522,并使用静态注册,启动后数据库注册不进去
解决:需要设置local_listener参数,网上也搜到了,不过没在意,修改监听端口oracle文档写的很清楚了,时间长都忘了,还咨询了下宝大师。
(二)数据割接过程
哇咔咔,终于可以导数据了,不过最苦逼的过程也随之开始了
3个用户A,B,C,A用户总共400G数据;B用户800G,其中两张表各有300个G;C用户3T多,有8张上百G的大表;这些大表都是分区表。
1、用户A数据量不大,而且表都比较小,所以直接用impdp @dblink去导A用户
,但时间用了近10个小时
2、在导A用户的过程中,将B、C用户中的非百G大表,用ultraedit拖了一堆脚本,大概一个脚本20张表(小表的话一次就多点,几十G的大表就一个两个的,而且impdp的tables参数有字符串长限制),每次起个7,8个impdp任务,基本上在A导完的同时,这些小表也都导完了。
这时挺乐观的,但是忘了一件事情,这些导完的表总量还不到整个库数据量的1/3。
3、因为网络带宽是千M的,最快的时候才30MB/S,源库的磁盘也不是很忙,感觉没有充分利用,从目标主机新挂了一个nfs到了原主机上,找了C用户的一张大表C1,使用expdp去导出C1的分区,因为表和分区都比较大,所以是”一张表导出多次,一次导出多个分区“的方式来导出,并且使用dmp文件名%U+PARALLEL参数可以并行操作,但是这里碰到了些问题。
问题7:导出过程中,发现部分分区会报错
ORA-31693: Table data object "TCQHW"."VOI_TOP_WEEK":"VOICE_TIME_WEEK_201227" failed to load/unload and is being skipped due to error:
ORA-00001: unique constraint (SYSTEM.SYS_C0030764) violated
ORA-06512: at "SYS.KUPF$FILE", line 2580
ORA-06512: at line 1
. . exported "TCQHW"."VOI_TOP_WEEK":"VOICE_TIME_WEEK_201227" 8.703 GB 93050225 rows
ORA-00001: unique constraint (SYSTEM.SYS_C0030764) violated
ORA-06512: at "SYS.KUPF$FILE", line 2580
ORA-06512: at line 1
. . exported "TCQHW"."VOI_TOP_WEEK":"VOICE_TIME_WEEK_201227" 8.703 GB 93050225 rows
解决:当时看到报错的时候,就查了下SYSTEM.SYS_C0030764是expdpjob(SYS_EXPORT_TABLE_XX)自己的索引,nndx,我猜应该是并发时oracle的bug,后来对这几个报错的分区重新单独导出了一下就又好了。
问题8:expdp和impdp使用的directory参数在使用nfs的时候
解决:这个应该不算是问题,就是麻烦,因为新主机和旧主机的oracle用户组uid和gid不一样,而expdp/impdp读写dmp文件是需要directory参数的,所以即使并发了多个导出任务,也要等所有的导出任务都结束之后,再去修改文件系统属主进行导入,太麻烦了,exp/imp没有directory概念,只要dmp文件改属主就可以,后来干脆放弃了这种方式了。
4、剩下大概还有九张几百G以上的大表,原来想用impdp @dblink按分区导,结果发现ORA-39203: Partition selection is not supported over a network link,分区不支持dblink直接导入,用nfs的expdp和impdp又太麻烦,这时候将剩下的表分开,把5张稍小的全表impdp @dblink,其他的3/400G的4张表使用insert into select @dblink where 条件=分区。这里犯了几个错误,耽误了我很多时间。
问题9:impdp的问题,在对
几张大表进行单表impdp的时候,我加了个PARALLEL参数,事实证明在对单表导入的时候,这个参数没用,数据库里明显可以看到只有一个worker在工作,其他的都在空闲等待;到了后来,所有impdp的worker的session都变成了wait for unread message on broadcast channel,感觉hang住了,几乎5个impdp同时出现了这种情况,当时也在跑好几个insert into select @dblink的任务,不知道和系统性能有没有啥关系,我cancel了一个impdp的job,倒是每个impdp的job都有一个worker恢复了正常的等待事件,比如sequential read,但是感觉没有在做事情,因为v$session_longops和trace都没有明显的活动。
解决:直接使用impdp的kill_job,并且杀了相应的ora_dm进程,取消了任务,当时几个job都跑了7、8个小时以上,当时做出这个决定,我还是下了很大决心的。事后查有说这是bug,哎。
5、等于最后的9张2个多T的大表都是并发使用insert into select @dblink where 条件=分区来编辑的,还是ultraedit拖了一堆脚本来跑
问题10:没写commit,只在每个脚本结束的时候写了一个exit
解决:当时只是突然想到没写commit,也没多想,也没测试,就随便检查了一下一个分区没数据,就把已跑的数据都truncate的,脚本加了commit,然后重跑,事后测试是其实不写commit,这种也可以提交的。
问题11:insert 并发太多了之后几乎全部insert session都出现了大量的log buffer space等待
解决:将表改为nologging,使用hint /*+ APPEND */,log buffer space就没有了,但是带来另外一个问题。
问题12:/*+ APPEND */方式插入不能并发,ORA-02049: timeout: distributed transaction waiting for lock
解决:那就不用并发了,对于一张表,即使不同分区,也只能一个分区一个分区单线程跑。
6、/*+ APPEND */不能并发会产生极少redo,直接insert可以并发但会产生大量redo,后来根据时间,又将数据多和分区多的又调整了能并发,数据不多的分区少的就用/*+ APPEND */,最终终于搞定了。
问题13:表不能收集统计信息,报错
ORA-20005: object statistics are locked (stattype = ALL)
ORA-06512: at "SYS.DBMS_STATS", line 13056
ORA-06512: at "SYS.DBMS_STATS", line 13076
ORA-06512: at line 2
ORA-06512: at "SYS.DBMS_STATS", line 13056
ORA-06512: at "SYS.DBMS_STATS", line 13076
ORA-06512: at line 2
解决:exec DBMS_STATS.UNLOCK_TABLE_STATS('<user name>','<table name>');
or exec DBMS_STATS.UNLOCK_schema_STATS('<user name>');
or impdp的时候不要导入统计信息EXCLUDE=TABLE_STATISTICS
四、总结
照例还要来个小结
1、这次问题碰到太多,主要原因是准备不足,可以说在这之前没有任何准备;现场项目组压根没这意识,数据没做任何清理,也没有梳理哪些是静态表,哪些是历史数据,虽然说这次也没时间提前导,但是准备还是要有的;我也是临时被通知过去,也基本没做任何准备;有时候做决策的人脑袋一发热,就会给事情带来很多麻烦。
2、问题多了自然也有好处,基本上把impdp/expdp搞熟了。
3、根据实际情况要不断调整策略,方法很多种,都有不同的适用条件,这次体现的很明显。
4、impdp @dblink出现hang住之后都有点小绝望,后来还是果断放弃了”沉淀成本“。
5、整个过程写的波澜不惊,其实那40多个小时各种问题带来的冲击是巨大的,包括时间的紧迫感,不过事后回过头去看,是次不错的经历。