ORACLE检查找出损坏索引(Corrupt Indexes)的方法详解

索引

索引与表一样,也属于段(segment)的一种。里面存放了用户的数据,跟表一样需要占用磁盘空间。索引是一种允许直接访问数据表中某一数据行的树型结构,为了提高查询效率而引入,是一个独立于表的对象,可以存放在与表不同的表空间中。索引记录中存有索引关键字和指向表中数据的指针(地址)。对索引进行的I/O操作比对表进行操作要少很多。索引一旦被建立就将被Oracle系统自动维护,查询语句中不用指定使用哪个索引.

从物理上说,索引通常可以分为:分区和非分区索引、常规B树索引、位图(bitmap)索引、翻转(reverse)索引等。其中,B树索引属于最常见的索引。

引言

本文主要给大家介绍了关于ORACLE检查找损坏索引(Corrupt Indexes)的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧

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

如上截图所示,如果索引损坏(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#; 

原因分析如下,视图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> 

RMAN> recover datafile 8 block 148 clear;

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我们的支持。

(0)

相关推荐

  • Oracle数据库不同损坏级别的恢复教程

    前言 在 DBA 的日常工作中不可避免存在着数据库的损坏,本文将主要介绍 Oracle 数据库遇到不同损坏级别下的应该采用的恢复方法,供读者在遇到此类情景时,能的找到适合自己的恢复方法,提高工作效率. 数据块损坏的恢复 当数据文件中仅有少量的数据块发生了介质损坏时,我们可以利用RMAN对其进行数据块一级的恢复.数据块级的局部恢复可以大大缩短恢复时间,甚至缩短到其他恢复方式的千分之几.此外,在数据块存在损坏而进行的恢复中,系统可以处于运行状态,这个数据文件也可以处于联机应用状态,无须将其设置为脱机

  • Oracle数据块损坏之10231内部事件不完全恢复

    什么是块损坏: 所谓损坏的数据块,是指块没有采用可识别的 Oracle 格式,或者其内容在内部不一致.通常情况下,损坏是由硬件故障或操作系统问题引起的.Oracle 数据库将损坏的块标识为"逻辑损坏"或"介质损坏".如果是逻辑损坏,则是 Oracle 内部错误.Oracle 数据库检测到不一致之后,就将逻辑损坏的块标记为损坏.如果是介质损坏,则是块格式不正确:从磁盘读取的块不包含有意义的信息.实验:某个分区数据块损坏,不完全恢复此分区表数据.  背景:数据库没有有效

  • ORACLE 数据库RMAN备份恢复

    机器A: select instance_name from v$instance; select name from v$database; select name from v$datafile; 查询日志模式: archive log list; shutdown immediate; startup mount; 把日志改为归档模式: alter database archivelog; alter database open; alter system archive log curr

  • Oracle误删除表数据后的数据恢复详解

    Oracle误删除表数据后的恢复详解   测试环境: SYSTEM:IBM AIX 5L                         Oracle Version:10gR2 1. undo_retention参数的查询与修改 使用show parameter undo命令查看当前的数据库参数undo_retention设置. 显示如下: SQL> show parameter undo NAME                                 TYPE        VAL

  • Oracle数据库数据丢失恢复的几种方法总结

    根据oracle数据库的特点和提供的工具,主要方法有以下几种方法: 利用逻辑备份使用import工具丢失数据的表 利用物理备份来通过还原数据文件并进行不完全恢复 利用dbms_logmnr包从redo log文件中恢复 利用flashback特性恢复数据 前提 为了方便使用方法的介绍,上述恢复方法都将基于以下场景进行:系统管理员在前一天晚上11点用export对数据库做了全库逻辑备份,然后对所有数据文件进行了热备份.第二天上午10点,系统管理员在修改表TFUNDASSET的数据时,由于修改语句的

  • oracle如何恢复被覆盖的存储过程

    如果你不小心覆盖了之前的存储过程,那得赶紧闪回,时长越长闪回的可能性越小.原理很简单,存储过程的定义就是数据字典,修改数据字典跟修改普通表的数据没有区别,此时会把修改前的内容放到undo中,我们可以根据这一点来进行闪回,所以我说要尽快,要不然找不回来了.下面我们来做一个实验: 1.在用户TEST下14:31下建立存储过程 复制代码 代码如下: create or replace procedure GG_TEST as l_cnt number; begin for i in 1 .. 1000

  • oracle冷备份恢复和oracle异机恢复使用方法

    一.冷备份1. 冷备份发生在数据库已经正常关闭的情况下,在进行冷备份之前通常要知道需要进行备份文件的名称以及路径 复制代码 代码如下: SQL>select name from v$datefile;SQL>select name from v$controlfile;SQL>select member from v$logfile; 2.冷备份所需备份的文件包括以下几种:所有数据文件.所有控制文件.所有联机REDO LOG 文件3.冷备份的步骤①正常关闭要备份的实例(instance)

  • [Oracle] 解析在没有备份的情况下undo损坏怎么办

    如果Oracle在运行中很不幸遇到undo损坏,当然最好的方法是完全恢复,不过如果没有备份,可以采用一种非常规的手段(利用Oracle的隐藏参数),如果此时undo包含未提交的事务,会造成一点点的数据丢失(一般都是可忍受的),如果没有未提交的事务,则不会有数据丢失.其主要步骤有: 1. 修改undo表空间管理为手动:2. 设置隐藏参数(_offline_rollback_segments或_corrupted_rollback_segments)标识受影响的回滚段,使Oracle忽略其上的未提交

  • oracle drop table(表)数据恢复方法

    复制代码 代码如下: --查看数据库回收站 select object_name,original_name,partition_name,type,ts_name,createtime,droptime from recyclebin; --恢复  FLASHBACK TABLE 表名 TO BEFORE DROP; 此举 可以恢复表结构,同时 数据也恢复了 必须9i或10g以上版本支持,flashback无法恢复全文索引

  • ORACLE检查找出损坏索引(Corrupt Indexes)的方法详解

    索引 索引与表一样,也属于段(segment)的一种.里面存放了用户的数据,跟表一样需要占用磁盘空间.索引是一种允许直接访问数据表中某一数据行的树型结构,为了提高查询效率而引入,是一个独立于表的对象,可以存放在与表不同的表空间中.索引记录中存有索引关键字和指向表中数据的指针(地址).对索引进行的I/O操作比对表进行操作要少很多.索引一旦被建立就将被Oracle系统自动维护,查询语句中不用指定使用哪个索引. 从物理上说,索引通常可以分为:分区和非分区索引.常规B树索引.位图(bitmap)索引.翻

  • 利用chrome浏览器进行js调试并找出元素绑定的点击事件详解

    前言 大家有没有遇到这样的一个问题,我们在分析一些大型电子商务平台的Web前端脚本时,想找到一个元素绑定的点击事件,并不是那么容易,因为有些前端脚本封装的比较隐蔽,甚至有些加密脚本,用传统的查找元素ID.或者页面源码方法去找,可能最后徒劳无功.下面我来介绍利用chrome浏览器来查找元素绑定的事件. Chrome开发工具中最有用的面板Sources.Sources面板几乎是最常用到的Chrome功能面板,也是解决一般问题的主要功能面板.通常只要是开发遇到了js报错或者其他代码问题,在审视一遍代码

  • 解决Oracle删除重复数据只留一条的方法详解

    查询及删除重复记录的SQL语句1.查找表中多余的重复记录,重复记录是根据单个字段(Id)来判断select * from 表 where  Id in (select Id from 表 group by Id having count(Id) > 1) 2.删除表中多余的重复记录,重复记录是根据单个字段(Id)来判断,只留有rowid最小的记录DELETE from 表 WHERE (id) IN ( SELECT id FROM 表 GROUP BY id HAVING COUNT(id)

  • 利用Pandas索引和选取数据方法详解

    目录 1. 导入数据集 2. 列选择 3. 行选择 数字Index 字符串Index 4. 行+列选择,找到元素 获取北汽2019年11月的销量 获取前5个品牌从2019年10月到12月的销量 5. 条件选择 6. 查找元素位置 在已知列中查找 在整个DataFrame中查找 我们将使用2019年全国新能源汽车的销量数据作为演示数据,数据保存在一个csv文件中,读者可以在GitHub仓库下载到 https://github.com/pythonlibrary/practice-pandas-sk

  • C#比较二个数组并找出相同或不同元素的方法

    本文实例讲述了C#比较二个数组并找出相同或不同元素的方法.分享给大家供大家参考,具体如下: string[] arr1 = new[] { "1", "2", "3", "4", "5" }; string[] arr2 = new[] { "1", "3", "5" }; var sameArr = arr1.Intersect(arr2).To

  • jQuery找出网页上最高元素的方法

    本文实例讲述了jQuery找出网页上最高元素的方法.分享给大家供大家参考.具体如下: 这段JS代码通过jQuery遍历网页上的元素,找出其中最高的元素 $(document).ready(function() { var maxHeight = -1; $('.features').each(function() { maxHeight = maxHeight > $(this).height() ? maxHeight : $(this).height(); }); $('.features'

  • JavaScript通过this变量快速找出用户选中radio按钮的方法

    本文实例讲述了JavaScript通过this变量快速找出用户选中radio按钮的方法.分享给大家供大家参考.具体分析如下: 下面的JS代码通过this变量结合radio按钮的onchange事件快速找出用户选择的哪一个radio按钮 <script> function favAnimal(button) { alert('You like '+button.value+'s.'); } </script> <input type="radio" name

  • 找出nginx配置文件的所在位置的方法详解

    对于一台陌生的服务器或安装太久忘了位置,怎么才能简单快速的找到配置文件的位置呢?要找出配置文件的位置,需要先找出nginx可执行文件的路径 , 这里有几种方法: 1.如果程序在运行中 ps -ef | grep nginx # ps -ef | grep nginx root 29514... 对于一台陌生的服务器或安装太久忘了位置,怎么才能简单快速的找到配置文件的位置呢? 要找出配置文件的位置,需要先找出nginx可执行文件的路径 , 这里有几种方法: 1.如果程序在运行中 ps -ef |

  • Linux 查看端口的占用情况并找出并杀死占用进程的方法

    1 lsof查看端口的占用情况 1.1 命令使用示例 # 命令为 lsof -i [root@onepiece ~]# lsof -i # 将会显示 命令 + 进程ID + 进程所属用户, 以及监听的协议.状态等信息 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME dhclient 728 root 6u IPv4 11262 0t0 UDP *:bootpc ntpd 839 ntp 16u IPv4 13671 0t0 UDP *:ntp

  • oracle sql语言模糊查询--通配符like的使用教程详解

    oracle在Where子句中,可以对datetime.char.varchar字段类型的列用Like子句配合通配符选取那些"很像..."的数据记录,以下是可使用的通配符: %   零或者多个字符 _    单一任何字符(下划线) \     特殊字符 oracle10g以上支持正则表达式的函数主要有下面四个: 1,REGEXP_LIKE :与LIKE的功能相似 2,REGEXP_INSTR :与INSTR的功能相似 3,REGEXP_SUBSTR :与SUBSTR的功能相似 4,RE

随机推荐