一、數據塊物理錯誤: 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錯誤??梢允褂靡晥Dv$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; /