一、数据块物理错误: physical bad block,物理性一般指数据块头部不可以访问、数据块校验值不合法 --创建表空间test SQL> select name from v$datafile;
NAME -------------------------------------------------------------------------------- /u01/app/oracle/oradata/DBdb/system01.dbf /u01/app/oracle/oradata/DBdb/sysaux01.dbf /u01/app/oracle/oradata/DBdb/undotbs01.dbf /u01/app/oracle/oradata/DBdb/users01.dbf /u01/app/oracle/oradata/DBdb/example01.dbf
SQL> create tablespace test datafile '/u01/app/oracle/oradata/DBdb/test.dbf' size 10m;
Tablespace created.
--创建表test,使用表空间test SQL> create table scott.test tablespace test as select * from dba_objects where rownum <=100;
Table created.
SQL> col name for a70 SQL> set lines 200 pages 999 SQL> select f.file#, 2 t.name tablespace, 3 f.name, 4 trunc(f.bytes / 1048576, 2) size_mb, 5 to_char(f.creation_time, 'yyyy-mm-dd') creation_time, 6 status 7 from v$datafile f, v$tablespace t 8 where f.ts# = t.ts# 9 order by f.creation_time; FILE# TABLESPACE NAME SIZE_MB CREATION_T STATUS
----- ---------- ------------------------------------------ ---------- ---------- -------
1 SYSTEM /u01/app/oracle/oradata/DBdb/system01.dbf 2800 2013-08-24 SYSTEM
2 SYSAUX /u01/app/oracle/oradata/DBdb/sysaux01.dbf 710 2013-08-24 ONLINE
4 USERS /u01/app/oracle/oradata/DBdb/users01.dbf 3058.75 2013-08-24 ONLINE
3 UNDOTBS1 /u01/app/oracle/oradata/DBdb/undotbs01.dbf 2965 2013-08-24 ONLINE
5 EXAMPLE /u01/app/oracle/oradata/DBdb/example01.dbf 338.75 2017-04-27 ONLINE
6 TEST /u01/app/oracle/oradata/DBdb/test.dbf 10 2018-01-26 ONLINE
6 rows selected.
--test表从数据块128号开始的8个块(128-135),数据文件是6号。 SQL> set lines 200 SQL> col name for a50 SQL> select a.file_id,a.block_id,a.blocks,b.name from dba_extents a,v$datafile b where a.file_id=b.file# and a.owner='SCOTT' and a.segment_name='TEST';
FILE_ID BLOCK_ID BLOCKS NAME ---------- ---------- ---------- -------------------------------------------------- 6 128 8 /u01/app/oracle/oradata/DBdb/test.dbf --test所有的行保存在131和132数据块中 SQL> select distinct dbms_rowid.rowid_block_number(rowid) from scott.test;
DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID) ------------------------------------ 132 131 --改变132数据块的内容 [oracle@wang ~]$ dd of=/u01/app/oracle/oradata/DBdb/test.dbf bs=8192 conv=notrunc seek=132 <<eof
> abcdefghijklmnopqrstuvwxyz
> EOF
0+1 records in
0+1 records out
27 bytes (27 B) copied, 8.484e-05 s, 318 kB/s
[oracle@wang~]$
</eof 二、数据逻辑错误:logical bad block,逻辑性一般是在物理性结构完整的情况下,数据的内容在含义上不正确 --创建range分区表 SQL> create table scott.emp1 (empno number(4),ename varchar2(10),deptno number(2)) partition by range (deptno)
(partition p1 values less than (10) tablespace users,partition p2 values less than (20) tablespace users, partition p3 values less than (30)) tablespace users;
Table created.
SQL> conn scott/tiger;
Connected.
SQL> SQL> select EMPNO,ENAME,DEPTNO from EMP;
EMPNO ENAME DEPTNO ---------- ---------- ---------- 7499 ALLEN 30 7521 WARD 30 7566 JONES 20 7654 MARTIN 30 7698 BLAKE 30 7782 CLARK 10 7788 SCOTT 20 7839 KING 10 7844 TURNER 30 7876 ADAMS 20 7900 JAMES 30
EMPNO ENAME DEPTNO ---------- ---------- ---------- 7902 FORD 20 7934 MILLER 10
13 rows selected. SQL> insert into scott.emp1 select EMPNO,ENAME,DEPTNO from SCOTT.EMP where deptno<30;
7 rows created.
SQL> commit;
Commit
--EMP1表从数据块40576号开始的1024个块(40576+1024=41600)以及从数据块41600号开始的1024个块(41600+1024=42624),数据文件是4号。 SQL> select a.file_id,a.block_id,a.blocks,b.name from dba_extents a,v$datafile b where a.file_id=b.file# and a.owner='SCOTT' and a.segment_name='EMP1';
--deptno是30的记录不能插入emp1表 SQL> insert into scott.emp1 values(1000,'SCOTT',30); insert into scott.emp1 values(1000,'SCOTT',30) * ERROR at line 1: ORA-14400: inserted partition key does not map to any partition
SQL> insert into scott.emp2 values(1000,'SCOTT',30);
1 row created.
SQL> alter table scott.emp1 exchange partition p3 with table scott.emp2 without validation;
Table altered.
SQL> --deptno为30的记录已插入emp1表 SQL> select * from scott.emp1 partition (p3);
EMPNO ENAME DEPTNO ---------- ---------- ---------- 1000 SCOTT 30
SQL> select * from scott.emp1;
EMPNO ENAME DEPTNO ---------- ---------- ---------- 7782 CLARK 10 7839 KING 10 7934 MILLER 10 1000 SCOTT 30 SQL> select * from scott.emp2;
EMPNO ENAME DEPTNO ---------- ---------- ---------- 7566 JONES 20 7788 SCOTT 20 7876 ADAMS 20 7902 FORD 20 三、oracle提供了很多工具用来检查数据块是否损坏,有的可以从物理层面上检查,有的可以从逻辑层面上检测
1.1DBVERIFY工具,数据块的物理错误可以通过DBV命令检查出来 DBVerify - Identify Datafile Block Corruptions DBVERIFY identifies Physical and Logical Intra Block Corruptions by default. Dbverify cannot be run for the whole database in a single command. It does not need a database connection either:
Total Pages Examined : 391520 Total Pages Processed (Data) : 290743 Total Pages Failing (Data) : 0 Total Pages Processed (Index): 12935 Total Pages Failing (Index): 0 Total Pages Processed (Other): 67340 Total Pages Processed (Seg) : 0 Total Pages Failing (Seg) : 0 Total Pages Empty : 20502 Total Pages Marked Corrupt : 0 Total Pages Influx : 0 Total Pages Encrypted : 0 Highest block SCN : 4024489 (0.4024489) [oracle@wang~]$ 1.2 RMAN的backup命令 RMAN - Identify Datafile Block Corruptions
To identify both Physical and Logical Block Corruptions use the "CHECK LOGICAL" option. The next command checks the complete database for both corruptions without actually doing a backup: 添加check logical选项可以检查逻辑坏块;
或者备份数据文件,也可以检查出坏块。
v$database_block_corruption查看backup操作发现的损坏
V$DATABASE_BLOCK_CORRUPTION displays information about database blocks that were corrupted after the last backup. 此视图只显示上次备份后损坏的数据库块的信息。
Recovery Manager: Release 11.2.0.4.0 - Production on Wed Nov 8 23:07:46 2017
Copyright (c) 1982, 2011, Oracle and/or its affiliates. All rights reserved.
connected to target database: DBDB (DBID=3282897732)
RMAN> backup datafile 6;
Starting backup at 08-NOV-17 using target database control file instead of recovery catalog allocated channel: ORA_DISK_1 channel ORA_DISK_1: SID=31 device type=DISK channel ORA_DISK_1: starting full datafile backup set channel ORA_DISK_1: specifying datafile(s) in backup set input datafile file number=00006 name=/u01/app/oracle/oradata/DBdb/test.dbf channel ORA_DISK_1: starting piece 1 at 08-NOV-17 RMAN-00571: =========================================================== RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS =============== RMAN-00571: =========================================================== RMAN-03009: failure of backup command on ORA_DISK_1 channel at 11/08/2017 23:07:52 ORA-19566: exceeded limit of 0 corrupt blocks for file /u01/app/oracle/oradata/DBdb/test.dbf
RMAN>
验证说明;备份test表空间数据文件时报错,备份要求数据块0错误。可以使用视图v$database_block_corruption查看backup操作发现的损坏的块。 V$DATABASE_BLOCK_CORRUPTION displays information about database blocks that were corrupted after the last backup.
查询如下; SQL> select * from v$database_block_corruption;
Starting validate at 26-JAN-18
using channel ORA_DISK_1
channel ORA_DISK_1: starting validation of datafile
channel ORA_DISK_1: specifying datafile(s) for validation
input datafile file number=00006 name=/u01/app/oracle/oradata/DBdb/test.dbf
channel ORA_DISK_1: validation complete, elapsed time: 00:00:01
List of Datafiles
=================
File Status Marked Corrupt Empty Blocks Blocks Examined High SCN
---- ------ -------------- ------------ --------------- ----------
6 FAILED 0 1148 1280 4177988
File Name: /u01/app/oracle/oradata/DBdb/test.dbf Block Type Blocks Failing Blocks Processed
---------- -------------- ----------------
Data 0 1
Index 0 0
Other 1 131
validate found one or more corrupt blocks See trace file /u01/app/oracle/diag/rdbms/dbdb/DBdb/trace/DBdb_ora_32387.trc for details
Finished validate at 26-JAN-18
RMAN> validate check logical datafile 4;
Starting validate at 26-JAN-18
using channel ORA_DISK_1
channel ORA_DISK_1: starting validation of datafile
channel ORA_DISK_1: specifying datafile(s) for validation
input datafile file number=00004 name=/u01/app/oracle/oradata/DBdb/users01.dbf
channel ORA_DISK_1: validation complete, elapsed time: 00:00:45
List of Datafiles
=================
File Status Marked Corrupt Empty Blocks Blocks Examined High SCN
---- ------ -------------- ------------ --------------- ----------
4 OK 0 21386 391549 4178643
File Name: /u01/app/oracle/oradata/DBdb/users01.dbf
Block Type Blocks Failing Blocks Processed
---------- -------------- ----------------
Data 0 241463
Index 0 55618
Other 0 73053
Export: Release 11.2.0.4.0 - Production on Thu Nov 9 00:16:08 2017
Copyright (c) 1982, 2011, Oracle and/or its affiliates. All rights reserved.
Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production With the Partitioning, OLAP, Data Mining and Real Application Testing options Export done in ZHS16GBK character set and AL16UTF16 NCHAR character set
About to export specified users ... . exporting pre-schema procedural objects and actions . exporting foreign function library names for user SCOTT . exporting PUBLIC type synonyms . exporting private type synonyms . exporting object type definitions for user SCOTT About to export SCOTT's objects ... . exporting database links . exporting sequence numbers . exporting cluster definitions . about to export SCOTT's tables via Conventional Path ... . . exporting table BONUS 0 rows exported . . exporting table DEPT 4 rows exported . . exporting table EMP 13 rows exported . . exporting table EMP1 . . exporting partition P1 0 rows exported . . exporting partition P2 3 rows exported . . exporting partition P3 1 rows exported --逻辑错误没检查出来。 . . exporting table EMP2 4 rows exported . . exporting table GRADES 0 rows exported . . exporting table JOBS 13 rows exported . . exporting table STUDENT 0 rows exported . . exporting table TEST EXP-00056: ORACLE error 1578 encountered ORA-01578: ORACLE data block corrupted (file # 6, block # 132) --检测出6号数据文件的132号块损坏 ORA-01110: data file 6: '/u01/app/oracle/oradata/DBdb/test.dbf' . exporting synonyms . exporting views . exporting stored procedures . exporting operators . exporting referential integrity constraints . exporting triggers . exporting indextypes . exporting bitmap, functional and extensible indexes . exporting posttables actions . exporting materialized views . exporting snapshot logs . exporting job queues . exporting refresh groups and children . exporting dimensions . exporting post-schema procedural objects and actions . exporting statistics Export terminated successfully with warnings. 1.4 ANALYZE语句 analyze... validate staructure语句可以分析表和索引的逻辑完整性,所以能够检测出上面例子中分区表的逻辑错误。
SQL> desc repair_table
Name Null? Type
----------------------------------------- -------- -----
OBJECT_ID NOT NULL NUMBER
TABLESPACE_ID NOT NULL NUMBER
RELATIVE_FILE_ID NOT NULL NUMBER
BLOCK_ID NOT NULL NUMBER
CORRUPT_TYPE NOT NULL NUMBER
SCHEMA_NAME NOT NULL VARCHAR2(30)
OBJECT_NAME NOT NULL VARCHAR2(30)
BASEOBJECT_NAME VARCHAR2(30)
PARTITION_NAME VARCHAR2(30)
CORRUPT_DESCRIPTION VARCHAR2(2000)
REPAIR_DESCRIPTION VARCHAR2(200)
MARKED_CORRUPT NOT NULL VARCHAR2(10)
CHECK_TIMESTAMP NOT NULL DATE
FIX_TIMESTAMP DATE
REFORMAT_TIMESTAMP DATE
SQL> select * from repair_table;
no rows selected
--执行check_object存储过程进行检测SCOTT.TEST表 SQL> SET SERVEROUTPUT ON SQL> DECLARE num_corrupt INT; BEGIN num_corrupt :=0; DBMS_REPAIR.CHECK_OBJECT( SCHEMA_NAME =>'SCOTT', OBJECT_NAME =>'TEST', REPAIR_TABLE_NAME =>'REPAIR_TABLE', CORRUPT_COUNT =>num_corrupt); DBMS_OUTPUT.PUT_LINE('number corrupt:' || TO_CHAR(num_corrupt)); END; / number corrupt:1 --有1个块损坏
PL/SQL procedure successfully completed.
SQL> --查询repair_table检查是哪个块出错。
SQL> col REPAIR_DESCRIPTION for a50 SQL> col SCHEMA_NAME for a10 SQL> col OBJECT_NAME for a10 SQL>select OBJECT_ID,
TABLESPACE_ID,
RELATIVE_FILE_ID,
BLOCK_ID,
CORRUPT_TYPE,
SCHEMA_NAME,
OBJECT_NAME,
REPAIR_DESCRIPTION
from repair_table;
OBJECT_ID TABLESPACE_ID RELATIVE_FILE_ID BLOCK_ID CORRUPT_TYPE SCHEMA_NAM OBJECT_NAM REPAIR_DESCRIPTION ---------- ------------- ---------------- ---------- ------------ ---------- ---------- ------------------------------ 90090 7 6 132 6148 SCOTT TEST mark block software
SYS> truncate tablerepair_table; Table truncated. SQL> select * from repair_table;
no rows selected ---接着检查scott.emp1的逻辑坏块,检测发现检查不来 SQL> SET SERVEROUTPUT ON SQL> DECLARE
num_corrupt INT;
BEGIN
num_corrupt := 0;
DBMS_REPAIR.CHECK_OBJECT(SCHEMA_NAME => 'SCOTT',
OBJECT_NAME => 'EMP1',
REPAIR_TABLE_NAME => 'REPAIR_TABLE',
CORRUPT_COUNT => num_corrupt);
DBMS_OUTPUT.PUT_LINE('number corrupt:' || TO_CHAR(num_corrupt));
END;
/ number corrupt:0
PL/SQL procedure successfully completed.
SQL> --检查表repair_table SQL> select * from repair_table;
no rows selected 注意:DBMS_REPAIR包只能检查表或者索引上的数据块错误(物理坏块),如果是段的头部发生错误是无法检测出来
例如,如下: --查出test表段头部在130号数据块。 SQL> select tablespace_id,header_file,header_block from sys_dba_segs where owner='SCOTT' and segment_name='TEST';
TABLESPACE_ID HEADER_FILE HEADER_BLOCK ------------- ----------- ------------ 7 6 130 --破坏130号数据块。 [oracle@wang ~]$ dd of=/u01/app/oracle/oradata/DBdb/test.dbf bs=8192 conv=notrunc seek=130 <<EOF<eof > abcdefghijklmnopqrstuvwxyz > EOF 0+1 records in 0+1 records out 29 bytes (29 B) copied, 0.00015142 s, 192 kB/s [oracle@wang ~]$
SQL> SET SERVEROUTPUT ON SQL> DECLARE num_corrupt INT; BEGIN num_corrupt :=0; DBMS_REPAIR.CHECK_OBJECT( SCHEMA_NAME =>'SCOTT', OBJECT_NAME =>'TEST', REPAIR_TABLE_NAME =>'REPAIR_TABLE', CORRUPT_COUNT =>num_corrupt); DBMS_OUTPUT.PUT_LINE('number corrupt:' || TO_CHAR(num_corrupt)); END; /