暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

一个ora-600 [kdsgrp1]故障的处理案例

白鳝的洞穴 2020-01-17
1751

    这是老白在10多年前处理过的一个案例,一个医院的用户的存储宕机,重启后数据库出现了很多坏块。有一些业务出现了报错,其中一个是十分关键的业务,影响了医院的门诊收费。同时由于备份的磁带存在问题,用户无法使用磁带恢复数据。客户在离老白2小时车程的中,接到客户的电话后,立即开车前往中山。

到达现场后,经检查发现,ALERT LOG文件中存在大量ora-600 [kdsgrp1],找到相关TRACE文件,打开就能看到以下的信息:

*** 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 1025749SLOT 22出问题了,在同一个TRACE文件中继续查找,可以找到相关SQL及执行计划:

select owner,segment_name from dba_extents where file_id=15 andblock_id<=1025749 and (block_id+blocks)>=1025749

------------------------------------------------------------+-----------------------+ 

|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 | 

------------------------------------------------------------+-----------------------+ 

们可以发现对INP_BILL_DETAIL表的访问时使用了IND2_INP_BILL_DETAIL这个索引。那么我们下一步要做的就是删除这个索引,重建一下(对于这个ORA-600错误,需要重建该索引,而不是ALTER INDEX ... REBUILD,重建索引可能是无效的)。幸运的是重建后这个错误就应该消失了。


    HIS业务恢复后,后面几个小问题就可以比较从容的去解决了。通过表分析语句,我们对出现报错的所有表都做了分析:

ANALYZE TABLEINP_BILL_DETAIL VALIDATE STRUCTURE CASCACE ONLINE


在做表分析的适合,有些表报ORA-1499错误,这个情况就是还有其他索引页存在问题,如果不重建,只要访问到那些索引的时候就会报类似的问题。有些表的主键存在问题,于是我们采取下面的方法对该表进行检查,查看主键对应的数据是否存在问题:

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


通过这个办法我们解决了主键冲突的问题。为了确保数据库中其他表没有这个问题,我们对所有的业务表都做了一遍分析,又发现了一两张存在问题的表。最后又使用rman 对所有数据文件做了一个validate,查看数据文件中是否还存在某些坏块。这也是对于存储宕机后数据库检查的常规做法。幸运的是,除了这个问题,数据库基本正常。于是这次因为存储宕机,备份损坏的的紧急处置告一段落。对于十分关键的业务系统,备份是运维底线,确保备份集的可用也是运维人员必须关注的事情,不过在我们周边,又有多少人真正能保证自己的备份集是可用的呢?

 


最后修改时间:2020-01-17 09:34:55
文章转载自 白鳝的洞穴,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论