上一篇
凌晨2:15,手机警报突然炸响,客户生产库的定时数据迁移任务爆红了——"ORA-31693: Table data object 'USER_DATA.TRANS_RECORDS' failed to load/unload and being skipped",揉着惺忪睡眼连上VPN,我知道今晚的睡眠又泡汤了。
远程登录到客户环境后,发现这是在使用Oracle Data Pump执行schema迁移时出现的错误,日志里明晃晃地写着:
ORA-31693: Table data object "USER_DATA.TRANS_RECORDS" failed to load/unload and is being skipped ORA-02354: error in exporting/importing data ORA-01578: ORACLE data block corrupted (file # 12, block # 34421)
客户的DBA已经尝试了三次重跑任务,每次都在同一张表卡住,更麻烦的是,这张TRANS_RECORDS表存放着近三个月的交易流水,业务部门明早还要用它生成报表。
第一斧:确认损坏范围
先用RMAN验证数据文件完整性:
RMAN> VALIDATE DATAFILE 12 BLOCK 34421;
果然返回了物理坏块信息,但好消息是仅这一个块有问题。
第二斧:抢救数据
由于是物理损坏,决定先用DBMS_REPAIR跳过坏块:
BEGIN DBMS_REPAIR.SKIP_CORRUPT_BLOCKS( schema_name => 'USER_DATA', object_name => 'TRANS_RECORDS', object_type => DBMS_REPAIR.TABLE_OBJECT); END; /
第三斧:特殊导出
改用传统EXPDP配合参数跳过坏块导出:
expdp system/password tables=USER_DATA.TRANS_RECORDS dumpfile=trans_records.dmp logfile=exp_trans.log flashback_time=systimestamp exclude=statistics data_options=skip_constraint_errors
当常规方法行不通时,我们采取了组合拳:
分段导出
通过QUERY参数分批导出完好数据:
expdp system/password tables=USER_DATA.TRANS_RECORDS query=\"WHERE transaction_date<TO_DATE('2025-06-01','YYYY-MM-DD')\"
使用外部表中转
对于损坏时间段的数据,创建外部表指向CSV临时文件:
CREATE TABLE temp_recovery ORGANIZATION EXTERNAL ( TYPE ORACLE_LOADER DEFAULT DIRECTORY data_dir ACCESS PARAMETERS ( RECORDS DELIMITED BY NEWLINE FIELDS TERMINATED BY ',' ) LOCATION ('bad_records.csv') ) AS SELECT * FROM TRANS_RECORDS WHERE transaction_date BETWEEN TO_DATE('2025-06-01','YYYY-MM-DD') AND TO_DATE('2025-07-15','YYYY-MM-DD');
最终缝合
在目标库先用NOLOGGING模式创建表结构,再禁用约束分批导入:
impdp system/password table_exists_action=append transform=disable_archive_logging:y data_options=skip_constraint_errors
RMAN VALIDATE
检查块完整性 DBMS_METADATA.GET_DDL
备份表结构 凌晨5:30,当业务人员确认报表能正常生成时,咖啡已经喝到第三杯,这种ORA-31693错误就像数据库的"阑尾炎",不致命但疼起来真要命,好在经过这次实战,我们的应急手册里又多了几页干货。
本文由 封煦 于2025-07-31发表在【云服务器提供商】,文中图片由(封煦)上传,本平台仅提供信息存储服务;作者观点、意见不代表本站立场,如有侵权,请联系我们删除;若有图片侵权,请您准备原始证明材料和公证书后联系我方删除!
本文链接:https://vps.7tqx.com/wenda/492508.html
发表评论