暂无图片
暂无图片
3
暂无图片
暂无图片
暂无图片

oracle数据块研究及坏块处理方法

原创 _ 云和恩墨 2022-10-28
1735

一、测试环境

sys@orcl> select file_name from dba_data_files;

FILE_NAME
---------------------------------------------

/u01/app/oracle/oradata/ORCL/system01.dbf
/u01/app/oracle/oradata/ORCL/sysaux01.dbf
/u01/app/oracle/oradata/ORCL/users01.dbf
/u01/app/oracle/oradata/ORCL/undotbs01.dbf

sys@orcl> create tablespace t1 datafile '/u01/app/oracle/oradata/ORCL/t1.dbf' size 10M autoextend off;

Tablespace created.


sys@orcl> create user cy identified by cy account unlock;

User created.

sys@orcl> grant dba to cy;

Grant succeeded.


sys@orcl> alter user cy default tablespace t1;

User altered.

sys@orcl> conn cy/cy
Connected.

cy@orcl> create table t1 as select * from scott.emp;

Table created.

cy@orcl> alter system checkpoint;

System altered.
cy@orcl> set linesize 1000

cy@orcl> select  rowid,a.*,dbms_rowid.rowid_relative_fno(rowid) file#,dbms_rowid.rowid_block_number(rowid) block# from t1 a;

ROWID                   EMPNO ENAME                JOB                       MGR HIREDATE                   SAL       COMM     DEPTNO      FILE#     BLOCK#

------------------ ---------- -------------------- ------------------ ---------- ------------------- ---------- ---------- ---------- ---------- ----------

AAASAsAAFAAAACDAAA       7369 SMITH                CLERK                    7902 1980-12-17 00:00:00        800                    20          5        131
AAASAsAAFAAAACDAAB       7499 ALLEN                SALESMAN                 7698 1981-02-20 00:00:00       1600        300         30          5        131
AAASAsAAFAAAACDAAC       7521 WARD                 SALESMAN                 7698 1981-02-22 00:00:00       1250        500         30          5        131
AAASAsAAFAAAACDAAD       7566 JONES                MANAGER                  7839 1981-04-02 00:00:00       2975                    20          5        131
AAASAsAAFAAAACDAAE       7654 MARTIN               SALESMAN                 7698 1981-09-28 00:00:00       1250       1400         30          5        131
AAASAsAAFAAAACDAAF       7698 BLAKE                MANAGER                  7839 1981-05-01 00:00:00       2850                    30          5        131
AAASAsAAFAAAACDAAG       7782 CLARK                MANAGER                  7839 1981-06-09 00:00:00       2450                    10          5        131
AAASAsAAFAAAACDAAH       7788 SCOTT                ANALYST                  7566 1987-04-19 00:00:00       3000                    20          5        131
AAASAsAAFAAAACDAAI       7839 KING                 PRESIDENT                     1981-11-17 00:00:00       5000                    10          5        131
AAASAsAAFAAAACDAAJ       7844 TURNER               SALESMAN                 7698 1981-09-08 00:00:00       1500          0         30          5        131
AAASAsAAFAAAACDAAK       7876 ADAMS                CLERK                    7788 1987-05-23 00:00:00       1100                    20          5        131
AAASAsAAFAAAACDAAL       7900 JAMES                CLERK                    7698 1981-12-03 00:00:00        950                    30          5        131
AAASAsAAFAAAACDAAM       7902 FORD                 ANALYST                  7566 1981-12-03 00:00:00       3000                    20          5        131
AAASAsAAFAAAACDAAN       7934 MILLER               CLERK                    7782 1982-01-23 00:00:00       1300                    10          5        131

14 rows selected.
SELECT ROWID,
       DBMS_ROWID.ROWID_OBJECT(ROWID) AS OBJECT,
       DBMS_ROWID.ROWID_RELATIVE_FNO(ROWID) AS FILENUM,
       DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID) AS BLOCK,
       DBMS_ROWID.ROWID_ROW_NUMBER(ROWID) AS ROWN
  FROM T1;

cy@orcl> select object_id from dba_objects where object_name='T1';
 OBJECT_ID
 ----------------------------
 73772

说明:
rowid是指向块中特定行的指针,ROWID可用于提取转储特定块所需的文件和块号,对数据进行索引时,
索引块包含每行的行ID,以便更快地访问(执行计划中能看到),当常规访问方法失败时,ROWID也可用于从块中提取数据

1.1 、rowid结构:
AAASAsAAFAAAACDAAN-->AAASAs(data object number) AAF(relative file number)  AAAACD(block number )  AAN(row number)
						32bit           10bit             22bit                   16bit

说明:

数据库对象数量不能超过2^32
相对文件号不能超过2^10
单个数据文件可以管理的块数2^22
单个块行数不能超过2^16

cy@orcl> select rowid,dump(rowid,1016) from t1;

ROWID              DUMP(ROWID,1016)

------------------ ----------------------------------------

AAASAsAAFAAAACDAAA Typ=69 Len=10: 0,1,20,2c,1,40,0,83,0,0 --> [00000000 000000001 00100000 00101100]  [00000001 01][000000 00000000 10000011] [00000000 00000000]
   73772				  5             131                           0
AAASAsAAFAAAACDAAB Typ=69 Len=10: 0,1,20,2c,1,40,0,83,0,1           
AAASAsAAFAAAACDAAC Typ=69 Len=10: 0,1,20,2c,1,40,0,83,0,2
AAASAsAAFAAAACDAAD Typ=69 Len=10: 0,1,20,2c,1,40,0,83,0,3
AAASAsAAFAAAACDAAE Typ=69 Len=10: 0,1,20,2c,1,40,0,83,0,4
AAASAsAAFAAAACDAAF Typ=69 Len=10: 0,1,20,2c,1,40,0,83,0,5
AAASAsAAFAAAACDAAG Typ=69 Len=10: 0,1,20,2c,1,40,0,83,0,6
AAASAsAAFAAAACDAAH Typ=69 Len=10: 0,1,20,2c,1,40,0,83,0,7
AAASAsAAFAAAACDAAI Typ=69 Len=10: 0,1,20,2c,1,40,0,83,0,8
AAASAsAAFAAAACDAAJ Typ=69 Len=10: 0,1,20,2c,1,40,0,83,0,9
AAASAsAAFAAAACDAAK Typ=69 Len=10: 0,1,20,2c,1,40,0,83,0,a
AAASAsAAFAAAACDAAL Typ=69 Len=10: 0,1,20,2c,1,40,0,83,0,b
AAASAsAAFAAAACDAAM Typ=69 Len=10: 0,1,20,2c,1,40,0,83,0,c
AAASAsAAFAAAACDAAN Typ=69 Len=10: 0,1,20,2c,1,40,0,83,0,d

14 rows selected.
1.2、dump 数据块

方法一

cy@orcl> alter system dump datafile 5 block 131;

System altered.

cy@orcl> select * from v$diag_info;

   INST_ID NAME

---------- --------------------------------------------------

VALUE
         0

         1 Default Trace File

/u01/app/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_84806.trc
         0

12 rows selected.
cy@orcl> select file_id,file_name,bytes from dba_data_files;

   FILE_ID FILE_NAME                                          BYTES
     1 /u01/app/oracle/oradata/ORCL/system01.dbf     4257218560
     3 /u01/app/oracle/oradata/ORCL/sysaux01.dbf      671088640
     4 /u01/app/oracle/oradata/ORCL/undotbs01.dbf    3795845120
     7 /u01/app/oracle/oradata/ORCL/users01.dbf         5242880
     5 /u01/app/oracle/oradata/ORCL/t1.dbf             10485760

方法2:

[oracle@19c01:/home/oracle/bbed]$dd  if=/u01/app/oracle/oradata/ORCL/t1.dbf bs=8k skip=130 count=1 |od -xv >file.out
3+0 records in
3+0 records out
24576 bytes (25 kB) copied, 6.2261e-05 s, 395 MB/s

dd命令是从磁盘读取数据,所以dump前需要做一个checkpoint。

二、数据块结构

2.1、结构
BBED> set dba 5,131
        DBA             0x01400083 (20971651 5,131)

BBED> map /v
 File: /u01/app/oracle/oradata/ORCL/t1.dbf (5)

 Block: 131                                   Dba:0x01400083
------------------------------------------------------------

 KTB Data Block (Table/Cluster)

 struct kcbh, 20 bytes                      @0               
    ub1 type_kcbh                           @0                                 --类型
    ub1 frmt_kcbh                           @1
    ub2 wrp2_kcbh                           @2
    ub4 rdba_kcbh                           @4
    ub4 bas_kcbh                            @8
    ub2 wrp_kcbh                            @12
    ub1 seq_kcbh                            @14
    ub1 flg_kcbh                            @15
    ub2 chkval_kcbh                         @16
    ub2 spare3_kcbh                         @18

BBED> p kcbh
struct kcbh, 20 bytes                       @0
   ub1 type_kcbh                            @0        0x06                   --数据块
   ub1 frmt_kcbh                            @1        0xa2                   --in Oracle8, Oracle8i and Oracle9i this is 0x02
   ub2 wrp2_kcbh                            @2        0x0000                 --未使用
   ub4 rdba_kcbh                            @4        0x01400083             --relative data block address -->01400083-->[0001010000][000000000010000011]-->131
   ub4 bas_kcbh                             @8        0x02b73cbc   --SCN base -->45563068
   ub2 wrp_kcbh                             @12       0x0000                 --SCN wrap
   ub1 seq_kcbh                             @14       0x02      --seq#,对于同一个SCN,每次对数据块的改变而增加,这玩意就站1位,最大也就255
   ub1 flg_kcbh                             @15       0x04 (KCBHFCKV)        --flag 0x01 新数据块  0x02 延迟logging  0x04 check value 0x08 临时数据块
   ub2 chkval_kcbh                          @16       0xc874                 --块校验
   ub2 spare3_kcbh                          @18       0x0000                 --未使用

结构说明

type:
01:undo 段头
02:undo 数据块
03:保留的undo 头
04:保留的undo 数据块
05:数据段头 (temp,index,data 等等)   
06:KTB managed data block (with ITL)
07: 临时表的数据块(没有 ITL)
08: sort key
09: sort run
10: 段自由列表
11: 数据文件头

flag:
#define KCBHFNEW 0x01 /* new block - zeroed data area     */
#define KCBHFDLC 0x02 /* Delayed Logging Change advance SCN/seq */
#define KCBHFCKV 0x04 /* ChecK Value saved-block xor's to zero */
#define KCBHFTMP 0x08 /* Temporary block                       */
seq_kcbh:如果在同一SCN上有254个更改,则在块的下一个更改上强制新的SCN分配。255表示坏块
BBED> set offset 8
        OFFSET          8

BBED> d
 File: /u01/app/oracle/oradata/ORCL/t1.dbf (5)

 Block: 131              Offsets:    8 to  519           Dba:0x01400083
------------------------------------------------------------------------

 bc3cb702 00000204 74c80000 01000000 2c200100 ba3cb702 00800000 03003200

bas_kcbh:0x02b73cbc

0x02b73cbc + 0x06 + 0x02-->3cbc0602
2.2、块结构:
Start dump data blocks tsn: 6 file#:5 minblk 131 maxblk 131
Block dump from cache:
Dump of buffer cache at level 3 for pdb=0 tsn=6 rdba=20971651
BH (0x8e3e5f50) file#: 5 rdba: 0x01400083 (5/131) class: 1 ba: 0x8e1c8000
  set: 6 pool: 3 bsz: 8192 bsi: 0 sflg: 2 pwc: 0,19
  dbwrid: 0 obj: 73772 objn: 73772 tsn: [0/6] afn: 5 hint: f
  hash: [0x8ffebfa0,0x6f207238] lru: [0x8e3e5ed0,0x8efeb060]
  ckptq: [NULL] fileq: [NULL]
  objq: [0x8efeb088,0x65181510] objaq: [0x8efeb098,0x65181500]
  st: XCURRENT md: NULL fpin: 'kdswh11: kdst_fetch' fscn: 0x2b73d04 tch: 1
  flags: only_sequential_access
  LRBA: [0x0.0.0] LSCN: [0x0] HSCN: [0x0] HSUB: [65535]
  Printing buffer operation history (latest change first):
  cnt: 6
         buffer tsn: 6 rdba: 0x01400083 (5/131)
         scn: 0x2b73cbc seq: 0x02 flg: 0x04 tail: 0x3cbc0602
         frmt: 0x02 chkval: 0xc874 type: 0x06=trans data

说明

Rdba:	相对块地址  20971651(这是十进制) -->[000101][0000000000000010000011]--> 5 131
Scn:	SCN号 0x2b73cbc(这是16进制) -->45563068
Seq:	Sequence number:0x02   每次对数据块的改变而增加,这玩意就站1位,最大也就255,如果在同一SCN上有254个更改,则有必要在块的下一个更改上强制新的SCN分配。
SEQ -> 0         /* non-logged changes - do not advance seq# */
SEQ -> (UB1MAXVAL-1)/* maximum possible sequence number      */ 2^8-1=254
SEQ -> (UB1MAXVAL) /* seq# to indicate a block is corrupt,equal to FF*/ 块错误,标记为255
Flg:	Flag (defined in kcbh.h)
Tail:	一致性数据,用于验证块的开头和结尾是否一致相同版本(由SCNBase的低位两个字节加上块类型加上SCN序列号组成
Frmt:	8i以前是2,现在变a2
Chkval:	  DB_BLOCK_CHECKSUM = TRUE的时候用
Type:	块类型(data, index, kcb.h中定义) 偏移20,不是偏移0那个
3.3、块头:
Block header dump:  0x01400083
 Object id on Block? Y
 seg/obj: 0x1202c  csc:  0x0000000002b73cba  itc: 3  flg: E  typ: 1 - DATA
     brn: 0  bdba: 0x1400080 ver: 0x01 opc: 0
     inc: 0  exflg: 0

 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
0x01   0xffff.000.00000000  0x00000000.0000.00  C---    0  scn  0x0000000002b73cba
0x02   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000
0x03   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000
Seg/Obj:	Seg/Obj ID   0x1202c-->73772 下文 偏移量24
Csc:	    最后一次区块清理时的SCN  偏移28
Itc:	    itl槽数量  偏移36 
Flg:	    0 = on the freelist(空闲列表)   E:指用的是ASSM(自动段空间管理) 
Typ:	    1 = DATA; 2 = INDEX
Fsl:	    ITL TX freelist slot
Fnx:	    空闲列表下一个块,串一串
Itl:	    Interested transaction list index (ITLs determined by INITRANS and MAXTRANS)
Xid:	    由und的段号+undo的槽号+undo槽号的覆盖次数三部分组成
Uba:	    Undo address (UndoDBA.SeqNo.RecordNo) undo块地址+seq+记录号
Flg:	    C = Committed; U = Commit Upper Bound; T = Active at CSC;B = Rollback of this UBA gives before image of the ITL.
Lck:	    当前事务影响行数
Scn/Fsc:	Scn = SCN of commited TX; Fsc = Free space credit (bytes)
BBED> p ktbbh
struct ktbbh, 96 bytes                      @20
   ub1 ktbbhtyp                             @20       0x01 (KDDBTDATA)
   union ktbbhsid, 4 bytes                  @24
      ub4 ktbbhsg1                          @24       0x0001202c
      ub4 ktbbhod1                          @24       0x0001202c
   struct ktbbhcsc, 8 bytes                 @28
      ub4 kscnbas                           @28       0x02b73cba
      ub2 kscnwrp                           @32       0x8000
      ub2 kscnwrp2                          @34       0x0000
   sb2 ktbbhict                             @36       3
   ub1 ktbbhflg                             @38       0x32 (NONE)
   ub1 ktbbhfsl                             @39       0x00
   ub4 ktbbhfnx                             @40       0x01400080
   struct ktbbhitl[0], 24 bytes             @44
      struct ktbitxid, 8 bytes              @44
         ub2 kxidusn                        @44       0xffff
         ub2 kxidslt                        @46       0x0000
         ub4 kxidsqn                        @48       0x00000000
      struct ktbituba, 8 bytes              @52
         ub4 kubadba                        @52       0x00000000
         ub2 kubaseq                        @56       0x0000
         ub1 kubarec                        @58       0x00
      ub2 ktbitflg                          @60       0x8000 (KTBFCOM)
      union _ktbitun, 2 bytes               @62
         sb2 _ktbitfsc                      @62      -32768
         ub2 _ktbitwrp                      @62       0x8000
      ub4 ktbitbas                          @64       0x02b73cba
   struct ktbbhitl[1], 24 bytes             @68
      struct ktbitxid, 8 bytes              @68
         ub2 kxidusn                        @68       0x0000
         ub2 kxidslt                        @70       0x0000
         ub4 kxidsqn                        @72       0x00000000
      struct ktbituba, 8 bytes              @76
         ub4 kubadba                        @76       0x00000000
         ub2 kubaseq                        @80       0x0000
         ub1 kubarec                        @82       0x00
      ub2 ktbitflg                          @84       0x0000 (NONE)
      union _ktbitun, 2 bytes               @86
         sb2 _ktbitfsc                      @86       0
         ub2 _ktbitwrp                      @86       0x0000
      ub4 ktbitbas                          @88       0x00000000
   struct ktbbhitl[2], 24 bytes             @92
      struct ktbitxid, 8 bytes              @92
         ub2 kxidusn                        @92       0x0000
         ub2 kxidslt                        @94       0x0000
         ub4 kxidsqn                        @96       0x00000000
      struct ktbituba, 8 bytes              @100
         ub4 kubadba                        @100      0x00000000
         ub2 kubaseq                        @104      0x0000
         ub1 kubarec                        @106      0x00
      ub2 ktbitflg                          @108      0x0000 (NONE)
      union _ktbitun, 2 bytes               @110
         sb2 _ktbitfsc                      @110      0
         ub2 _ktbitwrp                      @110      0x0000
      ub4 ktbitbas                          @112      0x00000000
3.4、用户数据头
data_block_dump,data header at 0x8e1c807c
===============

tsiz: 0x1f80
hsiz: 0x2e
pbl: 0x8e1c807c
     76543210
flag=--------
ntab=1
nrow=14
frre=-1
fsbo=0x2e
fseo=0x1d49
avsp=0x1d1b
tosp=0x1d1b
0xe:pti[0]      nrow=14 offs=0
0x12:pri[0]     offs=0x1f5a
0x14:pri[1]     offs=0x1f2f
0x16:pri[2]     offs=0x1f04
0x18:pri[3]     offs=0x1edb
0x1a:pri[4]     offs=0x1eae
0x1c:pri[5]     offs=0x1e85
0x1e:pri[6]     offs=0x1e5c
0x20:pri[7]     offs=0x1e34
0x22:pri[8]     offs=0x1e0e
0x24:pri[9]     offs=0x1de3
0x26:pri[10]    offs=0x1dbd
0x28:pri[11]    offs=0x1d97
0x2a:pri[12]    offs=0x1d70
0x2c:pri[13]    offs=0x1d49
Tsiz:	Total data area size  0x1f80-->8064不到8192
Hsiz:	Data header size      0x2e  -->46
Pbl:	Pointer to buffer holding the block --这是说在内存的地址吧
Bdba:	Block relative data block address (RDBA)
Flag:	N = pctfree hit(clusters); F = do not put on free list; K = flushable cluster keys
Ntab:	Number of tables (>1 in clusters)
Nrow:	Number of ROWS
Frre:	First free row index entry; -1 = you have to add one 第一个自由行索引条目
Fsbo:	Free space begin offset 2e 
Fseo:	Free space end offset 1d49 这两句意思是说可以从偏移量1d49写到2e,倒着存你不能倒着说么
Avsp:	Available space in the block 还有7451可以用
Tosp:	Total available space when all TXs commit 事务槽空闲出来还能写多少
Nrow:	Number of rows for first table
BBED> p kdbh
struct kdbh, 14 bytes                       @124
   ub1 kdbhflag                             @124      0x00 (NONE)
   sb1 kdbhntab                             @125      1
   sb2 kdbhnrow                             @126      14
   sb2 kdbhfrre                             @128     -1
   sb2 kdbhfsbo                             @130      46
   sb2 kdbhfseo                             @132      7497
   sb2 kdbhavsp                             @134      7451
   sb2 kdbhtosp                             @136      7451
3.5、数据行
block_row_dump:
tab 0, row 0, @0x1f5a  -->8026
tl: 38 fb: --H-FL-- lb: 0x0  cc: 8
col  0: [ 3]  c2 4a 46                               
col  1: [ 5]  53 4d 49 54 48
col  2: [ 5]  43 4c 45 52 4b
col  3: [ 3]  c2 50 03
col  4: [ 7]  77 b5 02 16 01 01 01
col  5: [ 2]  c2 09
col  6: *NULL*
col  7: [ 2]  c1 15
tab 0, row 1, @0x1f2f  -->7983
tl: 43 fb: --H-FL-- lb: 0x0  cc: 8
col  0: [ 3]  c2 4b 64
col  1: [ 5]  41 4c 4c 45 4e
col  2: [ 8]  53 41 4c 45 53 4d 41 4e
col  3: [ 3]  c2 4d 63
col  4: [ 7]  77 b5 02 14 01 01 01
col  5: [ 2]  c2 11
col  6: [ 2]  c2 04
col  7: [ 2]  c1 1f
Tab:	Table, row, offset
Lb:	Lock byte: ITL entry that has this row locked
Cc:	Number of columns in this ROW piece
Fb:	Flag byte H = head of row piece; K = Cluster key; C = Cluster table member; D = Deleted row;F = First data piece; L = last data piece; P = First column continues from previous
            piece; N = Last column continues in next piece
Tl:	Row size (number of bytes plus data)
Col:	Column data
BBED> p kdbr
sb2 kdbr[0]                                 @142      8026
sb2 kdbr[1]                                 @144      7983
sb2 kdbr[2]                                 @146      7940
sb2 kdbr[3]                                 @148      7899
sb2 kdbr[4]                                 @150      7854
sb2 kdbr[5]                                 @152      7813
sb2 kdbr[6]                                 @154      7772
sb2 kdbr[7]                                 @156      7732
sb2 kdbr[8]                                 @158      7694
sb2 kdbr[9]                                 @160      7651
sb2 kdbr[10]                                @162      7613
sb2 kdbr[11]                                @164      7575
sb2 kdbr[12]                                @166      7536
sb2 kdbr[13]                                @168      7497

BBED> p *kdbr[0]

rowdata[529]
------------

ub1 rowdata[529]                            @8150     0x2c

BBED> x /rnccntnnn   

rowdata[529]                                @8150    
------------

flag@8150: 0x2c (KDRHFL, KDRHFF, KDRHFH)
lock@8151: 0x00
cols@8152:    8

col    0[3] @8153: 7369 
col    1[5] @8157: SMITH
col    2[5] @8163: CLERK
col    3[3] @8169: 7902 
col    4[7] @8173: 1981-02-22 00:00:00 
col    5[2] @8181: 800 
col    6[0] @8184: *NULL*
col    7[2] @8185: 20 

BBED> x /r

rowdata[529]                                @8150    
------------

flag@8150: 0x2c (KDRHFL, KDRHFF, KDRHFH)
lock@8151: 0x00
cols@8152:    8

col    0[3] @8153:  0xc2  0x4a  0x46 
col    1[5] @8157:  0x53  0x4d  0x49  0x54  0x48 
col    2[5] @8163:  0x43  0x4c  0x45  0x52  0x4b 
col    3[3] @8169:  0xc2  0x50  0x03 
col    4[7] @8173:  0x77  0xb5  0x02  0x16  0x01  0x01  0x01 
col    5[2] @8181:  0xc2  0x09 
col    6[0] @8184: *NULL*
col    7[2] @8185:  0xc1  0x15
3.6、ASCII对照表
  20    , 2c    8 38    D 44    P 50    \ 5c    h 68    t 74
! 21    - 2d    9 39    E 45    Q 51    ] 5d    i 69    u 75
" 22    . 2e    : 3a    F 46    R 52    ^ 5e    j 6a    v 76
# 23    / 2f    ; 3b    G 47    S 53    _ 5f    k 6b    w 77
$ 24    0 30    < 3c    H 48    T 54    ` 60    l 6c    x 78
% 25    1 31    = 3d    I 49    U 55    a 61    m 6d    y 79
& 26    2 32    > 3e    J 4a    V 56    b 62    n 6e    z 7a
' 27    3 33    ? 3f    K 4b    W 57    c 63    o 6f    { 7b
( 28    4 34    @ 40    L 4c    X 58    d 64    p 70    | 7c
) 29    5 35    A 41    M 4d    Y 59    e 65    q 71    } 7d
* 2a    6 36    B 42    N 4e    Z 5a    f 66    r 72    ~ 7e
+ 2b    7 37    C 43    O 4f    [ 5b    g 67    s 73    ^? 7f

三、关于块损坏

3.1、块检查

​ 1、与硬盘做交互的时候需要做一致性检查,检查块版本、dba地址
​ 2、一致性检查如下项:

  • 块头SCNBase 和seq --bas_kcbh偏移量8,seq_kcbh偏移量14
  • 块尾SCNBase和seq --tailchk 偏移量8188 由SCNBase的低位两个字节加上块类型加上SCN序列号组成
  • 块类型 --偏移0就是
Tail:	Consistency data used to verify that the beginning and the end of the block are
of the same version (Consists of lower order two bytes of SCNBase plus block Type plus SCN Seq number.)
 SCNBase     type   seq      
0x2b73cbc  0x06   0x02      -->                 0x3cbc0602

案例:

ORA-600 (4519): Cache layer block type is incorrect
ORA-600 (4136): Check rollback segment block
ORA-600 (4154): Check rollback segment block
3.2、坏块类型:

介质坏块:从磁盘读取的无意义数据
软坏块:数据库系统检测到不一致后标记为坏块
seq的最大值为UB1MAXVAL-1(FF-1=255-1=254),因此当为FF就表示为软坏块。

3.3、ORA-1578

发现坏块的时候报出,报出的时候指出文件号和块号。

通常,ORA-1578错误是硬件问题造成的。如果ORA-1578错误总是返回相同的参数,则很可能是物理损坏的块。
如果参数每次都发生变化,则可能存在硬件问题,应检查内存和页面空间,并检查I/O子系统是否存在坏控制器。
获得十进制块号后,可以使用UNIX dd命令尝试从磁盘转储块。如果出现读取错误,这是硬件故障。此外,可以尝试转储该块几次,看看是否总能获得相同的数据。是对I/O子系统或坏控制器的检查。

3.4损坏的表中提取数据

(1) 使用可以跳过损坏块的特殊事件。这是迄今为止提取表数据的最简单的办法
(2) 使用 ROWID 范围扫描围绕损坏的块进行选择
(3) 有各种打捞程序/PLSQL 脚本

3.5、ORA-600
  • ORA-600[3374],[a],[b],[c],[d]
    写磁盘的时候检查出错误,在内存损坏,检查dba,type,version和inc#

  • ORA-600[kcbzpb_1],[d],[kind],[chk]
    当块在内存中损坏时发出信号。唯一导致的原因是内存中的存储破坏了头部或尾部。

    • kcbzpb_1: 命名内部错误,引用源代码模块名称
    • d : 块号
    • kind : 损坏类型
    • chk : 校验和标志
  • The ORA-600[3339] error comes with ORA-1578 and means either disk corruption or in-memory corruption after read.

3.6、如何处理:

检查alert日志和主机日志。使用诊断工具确定损坏类型。使用pacth查看什么问题。多检查几次确定是否依旧损坏。恢复数据。

始终尝试找出错误是否是永久性的。多次运行analyze命令,或者在可能的情况下执行关机和启动,然后重试以执行先前失败的操作。
找出是否还有更多的损坏。如果遇到一个,可能还有其他损坏的块。为此,使用DBVERIFY等工具。在尝试恢复数据之前,请执行块转储作为证据,以确定损坏的实际原因。使用UNIX dd和od-x对坏块进行十六进制转储。
考虑执行重做日志转储以检查对块所做的所有更改,以便您可以发现何时发生损坏。
注意:请记住,当遇到块损坏时,建议在验证硬件后执行介质恢复。
可能出现多种类型的硬件故障:

  • I/O硬件或固件错误

  • 操作系统I/O或缓存问题

  • 内存或分页问题

  • 磁盘修复实用程序

3.7、DBVERIFY

只能检查数据文件,不能检查redo。检查块一致性。数据库运行时不应使用DBVERIFY,因为缓存中的块可能会重新损坏。

Block Checking: DBA = 29360495, Block Type = KTB-managed data block
data header at 0x7f8c98f4c064
kdbchk: the amount of space used is not equal to block size
        used=613 fsc=41 avsp=7475 dtu=8129 dtl=8088 (s3=0, typ=6)
Page 367 failed with check code 6110
DBVERIFY - Verification complete
Total Pages Examined         : 640
Total Pages Processed (Data) : 75
Total Pages Failing   (Data) : 1
Total Pages Processed (Index): 17
Total Pages Failing   (Index): 0
Total Pages Processed (Other): 479
Total Pages Processed (Seg)  : 0
Total Pages Failing   (Seg)  : 0
Total Pages Empty            : 69
Total Pages Marked Corrupt   : 0
Total Pages Influx           : 0
Total Pages Encrypted        : 0
Highest block SCN            : 2275467 (0.2275467)

Influx:半一致状态,会重新检查,表示一开始检查head和tail不一致,后面一致。因为dbwr正在处理。如果还不一致则是坏块。
DBVERIFY仅检查逻辑损坏;也就是说,它使用kcb.h仅检查header/footer信息。因此,在高水位线以上可能发生损坏。

3.8、Analyze命令
  • 做逻辑块检查
  • 不标记软损坏,只是报告
  • 表示里面有数据或索引
  • 对于分区表,Oracle服务器还验证该行是否属于正确的分区。如果行未正确排序,则将rowid插入到invalid_rows表中。
SQL> analyze table xxx validate structure cascade;
SQL> analyze index xxx validate structure;
SQL> analyze cluster xxx validate structure;
SQL> analyze table xxx partition (p1) validate structure into invalid_rows; 

一个简单的select语句(select*from

)执行全表扫描,这意味着它读取所有数据块,直到表的高水位线。可以使用它来快速检查当前表数据中的损坏情况。

3.8、诊断事件
event = "10231 trace name context forever, level 10"  全表扫描跳过坏块
event = "10233 trace name context forever, level 10"  索引范围扫描跳过损坏的数据或索引块

event = "10232 trace name context forever, level 10"  dump坏块到trace文件
event = "10210 trace name context forever, level 10"  强制表数据块逻辑块检查,检查出后标记为软坏块

event = "10211 trace name context forever, level 10"  强制索引块逻辑块检查,检查出后标记为软坏块
event = "10212 trace name context forever, level 10"  强制聚簇块逻辑块检查,检查出后标记为软坏块

event = "xxx trace name context forever, level 10"

这三个事件允许潜在的损坏一出现就被发现,并发出错误信号;
但是,性能会受到影响,因为检查块时会复制这些块。请注意,所有未通过验证检查的块都立即标记为“软损坏”,这意味着块中的数据丢失
这些事件在资源方面是昂贵的;确保在不需要时将其关闭。事件10231和事件10233仅跳过软损坏块。

3.9、db_block_checking

可以会话级或者系统级,替代10210、10211、10212,默认false
db_block_checking的设置覆盖事件10210、10211和10212的任何设置。
如果db_block_checksum设置为true,则DBWn和直接计算校验和,并在将其写入磁盘时将其存储在每个数据块的缓存头中。
当随后读取块时,将重新计算校验和,并使用该计算值检查存储值

3.10、exp组件

exp可以用于检查数据库的逻辑一致性
执行全表扫描检索所有数据
exp不能发现高水位以上坏块,不能发现索引、空闲或临时区

如果只需要检查数据的一致性,则在执行导出时不必创建转储文件。在UNIX系统上,使用/dev/null作为文件名;
对于OpenVM,使用NULL:,对于Windows NT,使用NUL。执行此操作时,导出实用程序读取所有数据,但将其写入空设备。
这是检查逻辑一致性和检测物理损坏(在使用的块中)和逻辑损坏(数据字典问题)的好方法。

exp system/manager file=/dev/null full=y

只读取高水位以下的用户数据,部分数据字典,那么不能检查system表空间

3.11、介质恢复

找出包含损坏块的绝对数据文件号,然后查询V$DATAFILE或DBA_data_FILES以检索文件名。
确保在恢复数据文件的备份之前解决了所有硬件问题。如果磁盘坏了,并且您在另一个磁盘上有足够的空间,则始终可以将备份放在好的磁盘上,
将数据文件重命名到新位置,然后进行恢复。此外,恢复后,您可能需要检查恢复的数据文件是否损坏。如果没有热备份,则必须返回还原完整冷备份

3.12、块介质恢复(BMR)
rman>blockrecover datafile 5 block 132;

BMR使用现有的恢复机制将重做流中的更改应用于从适当备份恢复的块版本。必须使用恢复管理器(RMAN)执行BMR。用于媒体恢复的现有SQL接口不支持BMR。RMAN从可用备份中恢复单个数据块,并与Oracle server进程协调以恢复这些数据块。如果维护了备份集存储库,RMAN还可以帮助选择块的正确备份作为介质恢复的起点。
RMAN使用BLOCKRECOVER命令支持BMR。当用户遇到块损坏时,错误消息或跟踪文件将指示哪个块导致问题。然后,DBA可以使用损坏的块地址调用此命令,以仅恢复所讨论的块,从而节省大量停机时间和数据不可用性。

3.13、损坏对象
  • index:删除重建
  • 回滚段:下个会话覆盖
  • 表:块中数据丢失
    • 删除重建导入
    • 设置10231跳过坏块export,删除重建导入
    • 用sql把数据推到新建的表
3.14、确定对象名称
select segment_name, segment_type, relative_fno  from   dba_extents  where  file_id = 5  and   2 between block_id and block_id + blocks - 1;
如果有唯一索引,hint rowid做范围扫描

建表
create table temp as select * from tab_name  where  1 = 2;

创建rowid
function rowid_create
(rowid_type   IN number, object_number IN number
,relative_fno IN number, block_number  IN number
,row_number   IN number) return rowid;
插入数据
insert into temp select * from tab_name  where  rowid < DBMS_ROWID.ROWID_CREATE(1,2168,5,3,0);
insert into temp select * from tab_name  where  rowid > DBMS_ROWID.ROWID_CREATE(1,2168,5,1,0);

由于块2已损坏,损坏块之前的最后一个可能的行ID包含块在1,而损坏块之后的第一个行ID则包含在块3。请使用行号0,因为您不知道块中有多少行号

非分区表
select object_id from dba_objects where object_name='T1';
分区表
select obj# from tabpart$ where file#=5 and block#=131;
3.15、dbms_repair包
dbms_repair包可以指示但不修复块损坏,并且可以帮助提取有意义的数据,即使该块尚未被标记为损坏。

将块标记为损坏后,必须跳过整个块。
execute dbms_repair.admin_tables 
  (table_name => 'REPAIR_TABLE',
  table_type => dbms_repair.repair_table,
  action => dbms_repair.create_action);

dbms_repair.check_object (schema_name => 'SYSTEM',
object_name => 'T1',
repair_table_name => 'REPAIR_TABLE',
 corrupt_count => :count);

select object_name, block_id,corrupt_type, marked_corrupt,corrupt_description, repair_description from   repair_table;

使用bbed或者orapatch查看更多信息

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
1人已赞赏
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论