ORACLE如何检查找出损坏索引(Corrupt Indexes)

栏目: 数据库 · Oracle · 发布时间: 7年前

内容简介:在Oracle数据库中如何找出损坏索引呢? 下面我们人为构造一个案例,将索引块损坏。如下案例所示:上述脚本是创建表空间,创建用户kerry并授权,然后使用kerry账号登录数据库,构造测试数据,在TEST表上创建索引IX_TEST然后使用下面脚本找到索引段数据库文件ID,以及索引段的第一个块的块号。

在Oracle数据库中如何找出损坏索引呢? 下面我们人为构造一个案例,将索引块损坏。如下案例所示:

SQL> create tablespace test_data 
  2  datafile  '/u01/app/oracle/oradata/gsp/test_data_01.dbf' 
  3  size 200M autoextend off
  4  logging
  5  segment space management auto
  6  extent management local;
 
Tablespace created.
 
SQL> create tablespace test_index 
  2  datafile  '/u01/app/oracle/oradata/gsp/test_idx_01.dbf' 
  3  size 200M autoextend off
  4  logging
  5  segment space management auto
  6  extent management local;
 
Tablespace created.
 
 
SQL> create user kerry
  2  identified by 123456
  3  default tablespace test_data;
 
User created.
 
SQL> grant connect to kerry;
SQL> grant resource to kerry;

上述脚本是创建表空间,创建用户kerry并授权,然后使用kerry账号登录数据库,构造测试数据,在TEST表上创建索引IX_TEST

SQL> show user;
USER is "KERRY"
SQL> 
SQL> CREATE TABLE TEST(ID  NUMBER(10), NAME VARCHAR2(64));
 
Table created.
 
SQL> DECLARE I  NUMBER;
  2  BEGIN
  3    FOR I IN 1..1000 LOOP
  4      INSERT INTO TEST VALUES(I, LPAD('T', 60));  
  5     END LOOP;
  6  COMMIT;
  7  END;
  8  /
 
PL/SQL procedure successfully completed.
 
 
SQL> CREATE INDEX IX_TEST ON KERRY.TEST(NAME) TABLESPACE TEST_INDEX;
 
Index created.

然后使用下面脚本找到索引段数据库文件ID,以及索引段的第一个块的块号。

SQL> show user;
USER is "SYS"
SQL> col segment_name for a32;                               
SQL> col header_file for 9999;                               
SQL> col header_block for 9999;                              
SQL> select segment_name                                     
  2   ,header_file                                      
  3   ,header_block                                     
  4   ,blocks                                           
  5  from dba_segments ds                                    
  6  where ds.owner='KERRY' and ds.segment_name='IX_TEST';   
 
SEGMENT_NAME                     HEADER_FILE HEADER_BLOCK     BLOCKS
-------------------------------- ----------- ------------ ----------
IX_TEST                                    8          130         16
 
SQL>

构造坏块的方法有不少(例如BBED等),这里我们使用RMAN下面的命令clear,可以标记数据块为corrupt,标记数据文件8中130号数据块为坏块。

[oracle@DB-Server ~]$ rman target /
 
Recovery Manager: Release 11.2.0.1.0 - Production on Thu Sep 13 17:41:05 2018
 
Copyright (c) 1982, 2009, Oracle and/or its affiliates.  All rights reserved.
 
connected to target database: GSP (DBID=644393201)
 
RMAN> recover datafile 8 block 130 clear;
 
Starting recover at 13-SEP-18
using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=12 device type=DISK
Finished recover at 13-SEP-18
 
RMAN> 

那么我们先来看看使用那些方法验证索引损坏了,测试验证一下看看是否可行。

1:使用ANALYZE分析验证索引结构

[oracle@DB-Server ~]$ sqlplus / as sysdba
 
SQL*Plus: Release 11.2.0.1.0 Production on Thu Sep 13 17:42:03 2018
 
Copyright (c) 1982, 2009, Oracle.  All rights reserved.
 
 
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
 
SQL> analyze index kerry.ix_test validate structure;
analyze index kerry.ix_test validate structure
*
ERROR at line 1:
ORA-01578: ORACLE data block corrupted (file # 8, block # 130)
ORA-01110: data file 8: '/u01/app/oracle/oradata/gsp/test_idx_01.dbf'

ORACLE如何检查找出损坏索引(Corrupt Indexes)

如上截图所示,如果索引损坏(Corrupt Index),那么使用analyze index validate structure就会报错。要检查整个数据库所有的损坏索引(Corrupt Indexes)的话,就可以借助下面脚本:

spool analy_index.sql
SET PAGESIZE 50000;
SELECT
   'ANALYZE INDEX  ' || OWNER || '.' || INDEX_NAME|| ' VALIDATE STRUCTURE;' FROM DBA_INDEXES;
 
spool off;
 
@analy_index.sql

2:使用系统视图v$database_block_corruption查看损坏索引

如下所示,我们使用这个脚本来查看出现坏块的索引,发现这个脚本无法找出坏块索引。

set pagesize 50 linesize 170
col segment_name format a30
col partition_name format a30
SELECT DISTINCT file#, 
       segment_name, 
       segment_type, 
       tablespace_name, 
       partition_name 
FROM   dba_extents a, 
       v$database_block_corruption b 
WHERE  a.file_id = b.file# 
       AND a.block_id <= b.block# 
       AND a.block_id + a.blocks >= b.block#; 

ORACLE如何检查找出损坏索引(Corrupt Indexes)

原因分析如下,视图v$database_block_corruption中有坏块记录,但是我们将索引段的第一个块标记为坏块后,在dba_extents中没有该索引段的记录了。所以这种情况下的索引损坏,这个 SQL 语句根本无法找出坏块索引。  

SQL> SELECT file_id, 
  2         segment_name, 
  3         segment_type 
  4  FROM   dba_extents 
  5  WHERE  file_id = 8 ;
 
no rows selected
 
SQL> SELECT file_id, 
  2         segment_name, 
  3         segment_type 
  4 FROM   dba_extents 
  5  WHERE  owner = 'KERRY';
 
   FILE_ID SEGMENT_NAME                     SEGMENT_TYPE
---------- -------------------------------- ------------------
         7 TEST                             TABLE
         7 TEST                             TABLE
 
SQL> 

因为一个段的第一个区的第一个块是FIRST LEVEL BITMAP BLOCK,第二个块是SECOND LEVEL BITMAP BLOCK,这两个块是用来管理free block的,第三个块是PAGETABLE SEGMENT HEADER,这个块才是segment里的HEADER_BLOCK,再后面的块就是用来记录数据的。关于这些知识,可以参考我博客 ORACLE 关于段的 HEADER_BLOCK 的一点浅析。 我们最上面的例子,是将第一个块构造为坏块,所以导致上面SQL无法查出。 我们重新构造案例,如我们将索引段的数据块构造为坏块,例如下面,将块号148人为构造坏块。那么此时这个脚本就能找出坏块索引了。所以综上述实验可以看出,这个脚本查找坏块索引是有条件的,要看索引段损坏的块是什么类型

SQL> SELECT FILE_ID, 
  2         BLOCK_ID, 
  3         BLOCKS 
FROM   DBA_EXTENTS 
  4    5  WHERE  OWNER ='&OWNER'
  6       AND SEGMENT_NAME = '&TABLE_NAME'; 
Enter value for owner: KERRY
old   5: WHERE  OWNER ='&OWNER'
new   5: WHERE  OWNER ='KERRY'
Enter value for table_name: IX_TEST
old   6:      AND SEGMENT_NAME = '&TABLE_NAME'
new   6:      AND SEGMENT_NAME = 'IX_TEST'
 
   FILE_ID   BLOCK_ID     BLOCKS
---------- ---------- ----------
         8        144          8
         8        152          8
 
SQL> SELECT HEADER_FILE
  2       , HEADER_BLOCK
  3       , BYTES
  4       , BLOCKS
  5       , EXTENTS 
FROM DBA_SEGMENTS 
  6    7  WHERE OWNER='&OWNER' AND SEGMENT_NAME='&SEGMENT_NAME';
Enter value for owner: KERRY
Enter value for segment_name: IX_TEST
old   7: WHERE OWNER='&OWNER' AND SEGMENT_NAME='&SEGMENT_NAME'
new   7: WHERE OWNER='KERRY' AND SEGMENT_NAME='IX_TEST'
 
HEADER_FILE HEADER_BLOCK      BYTES     BLOCKS    EXTENTS
----------- ------------ ---------- ---------- ----------
          8          146     131072         16          2
 
SQL> 

ORACLE如何检查找出损坏索引(Corrupt Indexes)

RMAN> recover datafile 8 block 148 clear;

ORACLE如何检查找出损坏索引(Corrupt Indexes)


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Foundations of PEAR

Foundations of PEAR

Good, Nathan A./ Kent, Allan / Springer-Verlag New York Inc / 2006-11 / $ 50.84

PEAR, the PHP Extension and Application Repository, is a bountiful resource for any PHP developer. Within its confines lie the tools that you need to do your job more quickly and efficiently. You need......一起来看看 《Foundations of PEAR》 这本书的介绍吧!

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具