这是老白在10多年前处理过的一个案例,一个医院的用户的存储宕机,重启后数据库出现了很多坏块。有一些业务出现了报错,其中一个是十分关键的业务,影响了医院的门诊收费。同时由于备份的磁带存在问题,用户无法使用磁带恢复数据。客户在离老白2小时车程的中,接到客户的电话后,立即开车前往中山。
*** ACTION NAME:() 2010-09-02 01:01:23.024
*** MODULE NAME:(ichargeaday-new.exe) 2010-09-02 01:01:23.024
*** SERVICE NAME:(his.zsszyy) 2010-09-02 01:01:23.024
*** SESSION ID:(331.1099) 2010-09-02 01:01:23.024
row 03cfa6d5.15continuation at
file# 15 block# 1025749 slot 22 notfound
上面的信息我们可以看到FILE 15,BLOCK 1025749的SLOT 22出问题了,在同一个TRACE文件中继续查找,可以找到相关SQL及执行计划:
------------------------------------------------------------+-----------------------+
|Operation | Name | Rows | Bytes | Cost |
------------------------------------------------------------+-----------------------+
|SELECT STATEMENT | | | | 30 |
| HASH GROUP BY | | 1 | 184 | 30 |
| HASH JOIN OUTER | | 1 | 184 | 29 |
| NESTED LOOPS | | 1 | 162 | 9 |
| NESTED LOOPS | | 1 | 85 | 5 |
| NESTED LOOPS | | 1 | 73 | 4 |
| TABLE ACCESS BY INDEX ROWID | PATS_IN_HOSPITAL | 1 | 36 | 2 |
| INDEX UNIQUE SCAN | PK_PATS_IN_HOSPITAL | 1 | | 1 |
| TABLE ACCESS BY INDEX ROWID | PAT_MASTER_INDEX | 1 | 37 | 2 |
| INDEX UNIQUE SCAN | PK_PAT_MASTER_INDEX | 1 | | 1 |
| TABLE ACCESS BY INDEX ROWID | BED_REC | 2081 | 24K | 1 |
| INDEX UNIQUE SCAN | PK_BED_REC | 1 | | 0 |
| TABLE ACCESS BY INDEX ROWID | INP_BILL_DETAIL | 1 | 77 | 4 |
| INDEX RANGE SCAN | IND_2_INP_BILL_DETAIL | 14 | | 2 |
| TABLE ACCESS FULL | NATION_CHARGE_ITEM_DICT| 8259 | 177K | 19 |
------------------------------------------------------------+-----------------------+
HIS业务恢复后,后面几个小问题就可以比较从容的去解决了。通过表分析语句,我们对出现报错的所有表都做了分析:
ANALYZE TABLEINP_BILL_DETAIL VALIDATE STRUCTURE CASCACE ONLINE;
LOCK TABLE<TABLE_NAME> IN EXCLUSIVE MODE;
SELECT COUNT(*) FROM<TABLE_NAME>;
SELECT *+ FULL(TAB1)*/ COUNT(*) FROM <TABLE_NAME> TAB1;
上面的方法主要是为了检查一下索引和表数据是否一致,如果这两个查询结果不一致,那么说明主键是存在问题的,这种情况处理起来比较麻烦一些,需要删除主键约束以及相关索引,然后重建主键和索引,如果数据中存在了问题,主键相关字段的唯一性存在了问题,那么就更麻烦了,这种情况就需要找到重复的数据,并且手工删除重复的记录。
查找重复主键的方法可以通过两个方法
方法1:在删除主键后重新添加主键的时候,使用exception into<exception table name>子句,这样存在主键重复的记录的ROWID就会被记录到EXCEPTION TABLE中了
方法2:
select <主键字段>,count(*) from <table name> group by <主键字段> having count(*)>1




