一、概述

本文将介绍如何模拟坏块,以及出现坏块该如何修复。实验分为以下几个步骤。
1. 表出现坏块
2. 索引出现坏块

二、环境准备

本实验都是在oracle 11G归档模式下进行。

1. 准备相关表

create tablespace tbs01 datafile '/u01/app/oracle/oradata/orcltest/tbs01.dbf' size 100m;
create table scott.t01 tablespace tbs01 as select * from dba_objects where rownum<=100;
create index scott.idx_t01 on scott.t01(object_id) tablespace tbs01;

select rowid, dbms_rowid.rowid_relative_fno(rowid) file_id, dbms_rowid.rowid_block_number(rowid) block_id from scott.t01;

ROWID                 FILE_ID   BLOCK_ID
------------------ ---------- ----------
AAAVpMAAGAAAACDAAA 6 131
AAAVpMAAGAAAACDAAB 6 131
AAAVpMAAGAAAACDAAC 6 131
AAAVpMAAGAAAACDAAD 6 131
AAAVpMAAGAAAACDAAE 6 131
AAAVpMAAGAAAACDAAF 6 131
AAAVpMAAGAAAACDAAG 6 131
...

select segment_name, segment_type, file_id, block_id, blocks from dba_extents where segment_name='IDX_T01';

SEGMENT_NAME    SEGMENT_TYPE          FILE_ID   BLOCK_ID     BLOCKS
--------------- ------------------ ---------- ---------- ----------
IDX_T01 INDEX 6 136 8

2. 全库备份

RMAN> backup database;  // 全库备份

RMAN> list backup;  // 查看备份

List of Backup Sets
===================
BS Key Type LV Size Device Type Elapsed Time Completion Time
------- ---- -- ---------- ----------- ------------ ---------------
19 Full 1.08G DISK 00:01:59 12-MAR-20
BP Key: 19 Status: AVAILABLE Compressed: NO Tag: TAG20200312T150629
Piece Name: /home/oracle/backupdir/ORCLTEST_2750922031_40_1_20200312_1034867190.bkp
List of Datafiles in backup set 19
File LV Type Ckp SCN Ckp Time Name
---- -- ---- ---------- --------- ----
1 Full 1148218 12-MAR-20 /u01/app/oracle/oradata/orcltest/system01.dbf
2 Full 1148218 12-MAR-20 /u01/app/oracle/oradata/orcltest/sysaux01.dbf
3 Full 1148218 12-MAR-20 /u01/app/oracle/oradata/orcltest/undotbs01.dbf
4 Full 1148218 12-MAR-20 /u01/app/oracle/oradata/orcltest/users01.dbf
5 Full 1148218 12-MAR-20 /u01/app/oracle/oradata/orcltest/example01.dbf
6 Full 1148218 12-MAR-20 /u01/app/oracle/oradata/orcltest/tbs01.dbf

三、正式实验

1. 表出现坏块

1.1 模拟坏块
RMAN> blockrecover datafile 6 block 131 clear;  // 将131数据块清空,即相当于产生了坏块

SQL> select * from scott.t01;  // 对表进行查询

select * from scott.t01
*
ERROR at line 1:
ORA-01578: ORACLE data block corrupted (file # 6, block # 131)
ORA-01110: data file 6: '/u01/app/oracle/oradata/orcltest/tbs01.dbf'

1.2 检测坏块

检测坏块可以使用以下两种方式

a. 使用rman检测坏块
RMAN> backup check logical validate datafile 6;

上面rman检测到的坏块具体信息可以通过v$database_block_corruption查看

b. 使用oracle安装时自带的dbv工具
[oracle@orasingle ~]$ dbv file='/u01/app/oracle/oradata/orcltest/tbs01.dbf'

但是通过dbv工具并不能直观判断到底是什么类型数据块出现了坏块

1.3 坏块修复

RMAN> backup check logical validate datafile 6;  // 检测数据文件的坏块
RMAN> blockrecover corruption list;  // 自动修复检测出的坏块,该命令执行成功的前提是有完整的rman备份

SQL> select * from scott.t01;  // 再查询就没有错误了

2. 索引出现坏块

查看下面sql的执行计划
SQL> select * from scott.t01 where object_id=100;
SQL> select * from table(dbms_xplan.display_cursor(null,null,'TYPICAL PEEKED_BINDS'));

---------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 2 (100)| |
| 1 | TABLE ACCESS BY INDEX ROWID| T01 | 1 | 207 | 2 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | IDX_T01 | 1 | | 1 (0)| 00:00:01 |
---------------------------------------------------------------------------------------

2.1 模拟坏块

RMAN> blockrecover datafile 6 block 139 clear;  // 将139索引块清空,即相当于索引产生了坏块 
可能大家会有疑惑,该索引的块的block_id是136,你为什么要清空139呢?这就涉及到段的管理方式了,136-138这三个块依次是一级位图块,二级位图块,段头。真正存放数据的是从139开始。可以将块dump出来看看块的类型。

SQL> select * from scott.t01 where object_id=100;  // 再来查询该sql

select * from scott.t01 where object_id=100
*
ERROR at line 1:
ORA-01578: ORACLE data block corrupted (file # 6, block # 139)
ORA-01110: data file 6: '/u01/app/oracle/oradata/orcltest/tbs01.dbf'

在这里我们可以看到,这里的报错与前面表上有坏块的报错一模一样,因此当我们查询一张表出现这类报错的时候,可能并不是表有坏块,而可能是这张表上的索引有坏块。

2.2 检查坏块

RMAN> backup check logical validate datafile 6;

同样也可以通过下面的sql确定坏块的段类型。

select owner, segment_name, segment_type from dba_extents where 139 between block_id and block_id+blocks-1 and file_id=6;

2.3 修复坏块

索引的坏块修复有两种方式,第一种就是跟表一样,直接修复数据文件
RMAN> backup check logical validate datafile 6;  // 检测数据文件的坏块
RMAN> blockrecover corruption list;  // 自动修复检测出的坏块

第二种方式就是将索引直接删了重建,原理就是如果索引被删除了,这个段就会被系统回收,该段上所有的块都会被初始化,也就不存在什么坏块了。
select dbms_metadata.get_ddl('INDEX', 'IDX_T01', 'SCOTT') from dual;  // 通过该sql查索引的创建信息
drop index scott.idx_t01;  // 删除索引
CREATE INDEX "SCOTT"."IDX_T01" ON "SCOTT"."T01" ("OBJECT_ID") TABLESPACE "TBS01" online;  // 创建索引

2.4 试试rebuild online

可能你会问,为什么索引删了重建,直接rebuild不更好吗?那么我们再试试索引有坏块了,rebuild是个什么效果

RMAN> blockrecover datafile 6 block 139 clear;

RMAN> backup check logical validate datafile 6;

List of Datafiles
=================
File Status Marked Corrupt Empty Blocks Blocks Examined High SCN
---- ------ -------------- ------------ --------------- ----------
6 FAILED 0 12656 12800 1234071
File Name: /u01/app/oracle/oradata/orcltest/tbs01.dbf
Block Type Blocks Failing Blocks Processed
---------- -------------- ----------------
Data 0 2
Index 1 3
Other 0 139

使用rebuild命令重建索引(注意要使用online的方式,如果不加online就是通过原索引重建索引,会直接报错。)
alter index scott.idx_t01 rebuild online;

RMAN> backup check logical validate datafile 6;  // 可以看到坏块依然存在

select * from scott.t01 where object_id=100;  // 查询没有问题,索引也有效

select * from table(dbms_xplan.display_cursor(null,null,'TYPICAL PEEKED_BINDS'));

---------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 2 (100)| |
| 1 | TABLE ACCESS BY INDEX ROWID| T01 | 1 | 207 | 2 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | IDX_T01 | 1 | | 1 (0)| 00:00:01 |
---------------------------------------------------------------------------------------

所以,如果是索引的坏块,不建议使用rebuild online,一是老的索引在rebuild的过程中仍然存在,sql查询可能会依然报错,而删掉坏的索引,会立刻强迫sql走其它索引或全表,不至于引起sql报错。二是即使rebuild online完成之后,它虽然让重建后的索引能够正常使用,但是坏块依然存在在老的索引段中,系统并没有及时回收这个段,强迫症会觉得不舒服。

四、总结

1. 坏块修复的前提是要有完整的备份,所以一定得为生产环境指定备份策略
2. 表的坏块恢复直接使用rman
3. 索引的坏块恢复可以使用rman,也可通过删除索引再重建的方式修复

如果该主库有dg,那么主库有坏块又该如何修复,dg有坏块又该如何修复,请看“dg坏块修复(二)”

Oracle - 坏块修复(一)的更多相关文章

  1. 【转载】 使用rman进行坏块修复(ORA-01578、ORA-01110)

    [转自]http://blog.itpub.net/21256317/viewspace-1062055/ 使用rman进行坏块修复(ORA-01578.ORA-01110) 2012年的一天,处理的 ...

  2. oracle坏块问题的处理

    一.背景 今天有用户反映数据库连不上了,查看日志发现有数据库坏块. 查看数据库日志,有如下报错: ORA-01578: ORACLE , 93642) ORA-01110: 1: '/oracle/a ...

  3. Oracle--DBV命令行工具用法详解及坏块修复

    一,介绍 DBV(DBVERIFY)是Oracle提供的一个命令行工具,它可以对数据文件物理和逻辑两种一致性检查.但是这个工具不会检查索引记录和数据记录的匹配关系,这种检查必须使用analyze va ...

  4. ORACLE 坏块的模拟和查看

    坏块的模拟和查看使用bbed工具修改数据文件的块,然后使用dbv和rman工具查看坏块. 1.创建数据:根据dbv查看没有坏块Total Pages Marked Corrupt : 0create ...

  5. oracle坏块处理记录

    1. 执行sql:select count(distinct id) from bw_fpzxx ,报错如下: ORA-01578: ORACLE 数据块损坏 (文件号 16, 块号 195428)O ...

  6. [Oracle]坏块处理:确认坏块的对象

    如果已经知道 FILE#,BLOCK#,则 可以通过如下查询来看: SQL> SELECT SEGMENT_TYPE,OWNER||'.'||SEGMENT_NAME FROM DBA_EXTE ...

  7. 使用 DBMS_REPAIR 修复坏块

    对于Oracle数据块物理损坏的情形,在我们有备份的情况下可以直接使用备份来恢复.对于通过备份恢复,Oracel为我们提供了很多种方式,冷备,基于用户管理方式,RMAN方式等等.对于这几种方式我们需要 ...

  8. 无备份时用dbms_repair恢复坏块的方法

    份的情况下可以直接使用备份来恢复. 对于通过备份恢复,Oracel为我们提供了很多种方式,冷备,基于用户管理方式,RMAN方式等等. 对于这几种方式我们需要实现基于数据库以及文件级别的恢复.RMAN同 ...

  9. 13 oracle数据库坏块-逻辑坏块(模拟/修复)

    13 oracle数据库坏块-逻辑坏块 逻辑数据坏块的场景1)oracle bug也可能导致逻辑坏块的产生. 特别是parallel dml. 例如:Bug 5621677 Logical corru ...

随机推荐

  1. StartDT AI Lab | 视觉智能引擎+数据决策引擎——打造商业“智能沙盘”

    众所周知,线上商家可以通过淘宝平台的大量前端“埋点”轻松获取商品的加购率.收藏率.转化率.成交额等大量基础信息,甚至商家能够在更精细的层面,获取商品关键字变化或者上新/爆款带来的流量变化数据,更甚者商 ...

  2. spring cache问题记录

    1.是否可以设置过期时间 timeout ttl 对于单个key设置过期时间 需要自定义CacheManager, 见3中的问题 spring boot 1版本可以重写RedisCacheManage ...

  3. [LC] 46. Permutations

    Given a collection of distinct integers, return all possible permutations. Example: Input: [1,2,3] O ...

  4. [LC] 53. Maximum Subarray

    Given an integer array nums, find the contiguous subarray (containing at least one number) which has ...

  5. 点分治——POJ 1741

    写的第一道点分治的题目,权当认识点分治了. 点分治,就是对每条过某个点的路径进行考虑,若路径不经过此点,则可以对其子树进行考虑. 具体可以看menci的blog:点分治 来看一道例题:POJ 1741 ...

  6. python初认函数

    今日所得 函数基本使用 函数的参数 函数的返回值 # 函数内要想返回给调用者值 必须用关键字return """ 不写return 只写return 写return No ...

  7. mysqli存储过程

    <?php$link = mysqli_connect('localhost','root','','chinatupai');  $sql = "call getEmail('000 ...

  8. c socket 开发测试

    c语言异常 参照他人代码写一个tcp的 socket 开发测试 异常A,在mac osx系统下编译失败,缺库转到debian下. 异常B,include引用文件顺序不对,编译大遍异常 异常C,/usr ...

  9. 链终止法|边合成边测序|Bowtie|TopHat|Cufflinks|RPKM|FASTX-Toolkit|fastaQC|基因芯片|桥式扩增|

    生物信息学 Sanger采用链终止法进行测序 带有荧光基团的ddXTP+其他四种普通的脱氧核苷酸放入同一个培养皿中,例如带有荧光基团的ddATP+普通的脱氧核苷酸A.T.C.G放入同一个培养皿,以此类 ...

  10. 对String类型的认识以及编译器优化

    Java中String不是基本类型,但是有些时候和基本类型差不多,如String b = "tao" ; 可以对变量直接赋值,而不用 new 一个对象(当然也可以用 new). J ...