首页 > 数据库 > Oracle > 记一次业务表数据损坏场景下的灾难挽救案例分析
某次某用户由于存储硬件故障,导致数据库无法正常启动。该故障影响了一个大小为22GB的数据文件,存储损坏后,文件只能读取到 20.4GB ,且无法进行正常恢复。尽管存储层面进行了修复,数据库依然无法启动,导致出现一系列数据损坏及恢复问题。
前期处理步骤,如下表所示:
|
步骤 |
关键点 |
说明 |
|
Step1 |
Undo 段屏蔽及表空间更换 |
在初步诊断后,针对损坏的 undo 段进行了屏蔽,并更换了受影响的 undo 表空间,以避免对数据库其他部分的影响 |
|
Step2 |
坏块修复 |
通过数据库坏块修复工具,定位并修复了损坏的数据块,同时删除了受损坏的数据对象的索引 |
|
Step3 |
设置了部分隐含参数 |
例如一致性校验、undo回滚段、events等 |
|
Step4 |
打开数据库 |
做了一系列调整之后,数据库正常启动 |
|
Step5 |
全库逻辑导出 |
为了确保数据不丢失,开始执行全库的逻辑导出操作。然而,在导出 `XXUSER.XXTAB_OLD` 表时出现了错误,改用exp依然报错 |
在导出 `XXUSER.XXTAB_OLD` 表时, ORA-01555 报错,并提示该表存在损坏的数据块。该表为本次数据恢复的核心表,原表共计约 13 万条数据。以下为错误详情:
1. 使用 `select * from XXUSER.XXTAB_OLD;` 查询数据时,发现表中存在损坏的记录,导致无法完整查询表中的数据。
2. 尝试使用 `create table` 语句创建新表时,系统报错,并提示无法创建。通过限制查询条件为 `rownum` ,可以成功创建新表,但仅能插入最多 79000 条记录。超过 79000 后的记录无法成功插入。
3. 进一步打印所有的 `rowid` 后,发现表中 79000 条记录之后存在损坏的部分数据。但仍有部分记录是完好的,可以被查询。通过以下查询验证损坏与完好的数据:
Select * from XXUSER.XXTAB_OLD where rowid='XXXXXXXX';
查询结果显示, 79000 条记录后存在部分损坏的记录。
为了解决数据损坏问题,采取了以下恢复措施:
1. 创建新表:
使用以下 SQL 语句创建新表:
create table XXUSER.table2024(TEXTID varchar2(500), ROWTEXT varchar2(500));
2. 插入完好数据:
通过原表中所有数据行的 rownum, rowid 插入到 table2024 中:
insert into XXUSER.table2024
select rownum, rowid
from XXUSER.XXTAB_OLD;
commit;
3. 创建新表的表结构:
创建新的表 `XXUSER.XXTAB_NEW2024` ,无数据,该表作为数据恢复的落地表:
CREATE TABLE XXUSER.XXTAB_NEW2024 AS SELECT * FROM XXUSER.XXTAB_OLD WHERE 1=0;
4. 使用存储过程清洗数据:
编写存储过程 `TAB_insert` 来过滤掉损坏的记录,只插入可查询的数据:
CREATE OR REPLACE PROCEDURE TAB_insert
AS
cursor tab_cur is
SELECT TEXTID,ROWTEXT FROM XXUSER.table2024;
begin
for tab_recoder in tab_cur loop
begin
insert into XXUSER.XXTAB_NEW2024 select PART_ID,UNIT_ID,STOCK_ID,PART_NAME,STOCK_NUM,BAD_NUM,GIVE_NUM,IN_PRICE,ACTUAL_PRICE,TOTAL_PRICE,TAX_RATE,TAXES_PRICE,STOCK_PLACE,MIN_STOCK_NUM,MAX_STOCK_NUM,MEMO from XXUSER.XXTAB_OLD where rowid = tab_recoder.ROWTEXT;
commit;
EXCEPTION WHEN others THEN null;
end;
end loop;
end;
/
execute tab_insert();
新表的数据量为 138823 ,故障表的数据量为 138928 ,成功最大程度的恢复数据,只缺失了 105 条记录;
相关 MOS 参考文档, Extract rows from a CORRUPT table creating ROWID from DBA_EXTENTS (Doc ID 422547.1)
1. 硬件故障排查及修复:客户的外置存储硬件故障已经修复,因此数据库故障的根本原因已得到解决。
2. 数据库启动恢复:通过修复坏块、屏蔽损坏的 undo 段和调整表空间,恢复了数据库的正常启动和运行。
3. 数据损坏恢复:通过 `rowid` 抽取和存储过程的方式,成功将完好的数据从损坏的数据表中提取,并恢复到了新的表中。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/30310891/viewspace-3062377/ ,如需转载,请注明出处,否则将追究法律责任。