国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > 綜合 > 正文

如何使用DBMS_REPAIR檢測和修補數據壞塊

2024-07-21 02:42:59
字體:
來源:轉載
供稿:網友
這篇論壇文章(賽迪網技術社區)主要介紹了使用DBMS_REPAIR檢測和修補數據壞塊的具體方法,詳細內容請參考下文。

Oracle提供了許多方法檢測和修補數據庫中的數據壞塊,而DBMS_REPAIR package就是其中之一。

對任何可能導致數據丟失的損壞,我們都要仔細的分析,以求理解所要涉及的數據。就修補壞塊本身來說, 它可能會丟失數據,也可能會導致數據在邏輯上不一致;因此在進行修補壞塊之前,必須仔細權衡使用DBMS_REPAIR的得失。

DBMS_REPAIR package 僅僅對transaction層和data層的壞塊(即通常所說的由軟件引起的壞塊)起作用,對物理上損壞的塊,在它被讀到緩沖區中時就已被標識出來了,而DBMS_REPAIR會忽略所有被標識為壞了的塊。

在DBMS_REPAIR package 初始版本中,“修補壞塊”的功能僅僅是“將塊標識為由軟件引起的壞塊”

使用DBMS_REPAIR package的注意事項:

1、 DB_BLOCK_CHECKING和DB_BLOCK_CHECKSUM要設置為FALSE.

2、 在使用DBMS_REPAIR之前,有壞塊的文件應做一個備份。

下面我們就通過一個例子來說明DBMS_REPAIR package是如何檢測和修補壞塊的。

例如,Table T1(結構如下)中存在一個壞塊:

SQL> desc t1

Name Null? Type

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

COL1 NOT NULL NUMBER(38)

COL2 CHAR(512)

用Analyze命令對Table t1進行分析后,會得到如下錯誤提示:

SQL> analyze table t1 validate structure;

analyze table t1 validate structure

*

ERROR at line 1:

ORA-01498: block check failure

在Analyze產生的trace文件中,可以知道壞塊中包含3條記錄的數據(nrows = 3),

Trace文件中主要的內容如下:

Dump file /export/home/oracle/PRoduct/8.1.5

/admin/V815/udump/v815_ora_2835.trc

Oracle8 Enterprise Edition Release 8.1.5.0.0

With the Partitioning option

*** 1998.12.16.15.53.02.000

*** session ID:(7.6) 1998.12.16.15.53.02.000

kdbchk: row locked by non-existent transaction

table=0 slot=0

lockid=32 ktbbhitc=1

Block header dump: 0x01800003

Object id on Block? Y

seg/obj: 0xb6d csc: 0x00.1cf5f itc: 1 flg: - typ: 1 - DATA

fsl: 0 fnx: 0x0 ver: 0x01

Itl Xid Uba Flag Lck Scn/Fsc

0x01 xid: 0x0002.011.00000121 uba: 0x008018fb.0345.0d --U- 3 fsc

0x0000.0001cf60

data_block_dump

===============

tsiz: 0x7b8

hsiz: 0x18

pbl: 0x28088044

bdba: 0x01800003

flag=-----------

ntab=1

nrow=3

frre=-1

fsbo=0x18

fSEO=0x19d

avsp=0x185

tosp=0x185

0xe:pti[0] nrow=3 offs=0

0x12:pri[0] offs=0x5ff

0x14:pri[1] offs=0x3a6

0x16:pri[2] offs=0x19d

block_row_dump:

(注:其余的省略)

end_of_block_dump

一、首先使用DBMS_REPAIR.ADMIN_TABLES來建立repair table和orphan key table,

并且為repair table和orphan key tables提供管理功能

SQL> @adminCreate

SQL> connect sys/

Connected.

SQL>

SQL> -- Repair Table

SQL>

SQL> declare

2 begin

3 -- create repair table

4 dbms_repair.admin_tables (

5 -- table_name => 'REPAIR_TABLE',

6 table_type => dbms_repair.repair_table,

7 action => dbms_repair.create_action,

8 tablespace => 'USERS'); -- 如果是使用SYS用戶的缺省表空間,該項就不用指定

9 end;

10 /

PL/SQL procedure successfully completed.

我們查詢dba_objects,可以看到如下結果:

SQL> select owner, object_name, object_type

2 from dba_objects

3 where object_name like '%REPAIR_TABLE';

OWNER OBJECT_NAME OBJECT_TYPE

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

SYS DBA_REPAIR_TABLE VIEW

SYS REPAIR_TABLE TABLE

SQL>

SQL> -- Orphan Key Table

SQL>

SQL> declare

2 begin

3 -- Create orphan key table

4 dbms_repair.admin_tables (

5 table_type => dbms_repair.orphan_table,

6 action => dbms_repair.create_action,

7 tablespace => 'USERS'); -- 如果是使用SYS用戶的缺省表空間,該項就不用指定

8 end;

9 /

PL/SQL procedure successfully completed.

我們查詢dba_objects,可以看到如下結果:

SQL> select owner, object_name, object_type

2 from dba_objects

3 where object_name like '%ORPHAN_KEY_TABLE';

OWNER OBJECT_NAME OBJECT_TYPE

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

SYS DBA_ORPHAN_KEY_TABLE VIEW

SYS ORPHAN_KEY_TABLE TABLE

二、使用DBMS_REPAIR.CHECK_OBJECT進行檢測

CHECK_OBJECT procedure檢查指定的object,并且將關于損壞和修補的指導信息裝入Repair Table。它將效驗指定object中所有塊的一致性。而在此之前已標識的塊就會被跳過。

SQL> @checkObject

SQL> set serveroutput on

SQL>

SQL> declare

2 rpr_count int;

3 begin

4 rpr_count := 0;

5 dbms_repair.check_object (

6 schema_name => 'SYSTEM',

7 object_name => 'T1',

8 repair_table_name => 'REPAIR_TABLE',

9 corrupt_count => rpr_count);

10 dbms_output.put_line('repair count: ' || to_char(rpr_count));

11 end;

12 /

repair count: 1

PL/SQL procedure successfully completed.

repair_table的結構如下:

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

我們可以從repair_table中查詢壞塊的情況:

SQL> select object_name, block_id, corrupt_type, marked_corrupt,

2 corrupt_description, repair_description

3 from repair_table;

OBJECT_NAME BLOCK_ID CORRUPT_TYPE MARKED_COR

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

CORRUPT_DESCRIPTION

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

REPAIR_DESCRIPTION

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

T1 3 1 FALSE

kdbchk: row locked by non-existent transaction

table=0 slot=0

lockid=32 ktbbhitc=1

mark block software corrupt

三、從壞塊中進行數據抽取

從repair_table中可以知道file 6的block 3 壞了,但注意此時這個塊還沒有被標識為壞塊,因此要在這個時候將任何有意義的數據趕快抽取出來。一旦該塊被標識為壞塊,整個塊就會被跳過。

1、 通過ALTER SYSTEM DUMP或trace中來獲取塊中包含的記錄數 (nrows = 3).

2、 查詢損壞的object,盡量抽取盡可能多的信息。

下面的查詢可以用來從壞塊中搶救數據。

建立一個臨時表(temp_t1)以方便數據的插入:

SQL> create table temp_t1 as

2 select * from system.t1

3 where dbms_rowid.rowid_block_number(rowid) = 3

4 and dbms_rowid.rowid_to_absolute_fno (rowid, 'SYSTEM','T1') = 6;

Table created.

SQL> select col1 from temp_t1;

COL1

----------

2

3

四、使用DBMS_REPAIR.FIX_CORRUPT_BLOCKS來標識壞塊

FIX_CORRUPT_BLOCKS procedure用來根據repair table中的信息修正指定objects中的壞塊。當這個塊被標識為壞了以后,做全表掃描將引起ORA-1578錯。

SQL> declare

2 fix_count int;

3 begin

4 fix_count := 0;

5 dbms_repair.fix_corrupt_blocks (

6 schema_name => 'SYSTEM',

7 object_name => 'T1',

8 object_type => dbms_repair.table_object,

9 repair_table_name => 'REPAIR_TABLE',

10 fix_count => fix_count);

11 dbms_output.put_line('fix count: ' || to_char(fix_count));

12 end;

13 /

fix count: 1

PL/SQL procedure successfully completed.

查詢repair_table可以看到block 3已經被標識:

SQL> select object_name, block_id, marked_corrupt

2 from repair_table;

OBJECT_NAME BLOCK_ID MARKED_COR

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

T1 3 TRUE

這時再對table t1做全表掃描,ORA-1578將會出現。

SQL> select * from system.t1;

select * from system.t1

*

ERROR at line 1:

ORA-01578: ORACLE data block corrupted (file # 6, block # 3)

ORA-01110: data file 6: '/tmp/ts_corrupt.dbf'

五、使用DBMS_REPAIR.DUMP_ORPHAN_KEYS來修補相關的index

DUMP_ORPHAN_KEYS將會顯示指向數據壞塊中記錄的index entries

下列查詢顯示與壞塊相關的index。

SQL> select index_name from dba_indexes

2 where table_name in (select distinct object_name from repair_table);

INDEX_NAME

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

T1_PK

SQL> @dumpOrphanKeys

SQL> set serveroutput on

SQL>

SQL> declare

2 key_count int;

3 begin

4 key_count := 0;

5 dbms_repair.dump_orphan_keys (

6 schema_name => 'SYSTEM',

7 object_name => 'T1_PK',

8 object_type => dbms_repair.index_object,

9 repair_table_name => 'REPAIR_TABLE',

10 orphan_table_name => 'ORPHAN_KEY_TABLE',

11 key_count => key_count);

12 dbms_output.put_line('orphan key count: ' || to_char(key_count));

13 end;

14 /

orphan key count: 3

PL/SQL procedure successfully completed.

orphan_key_table的結構如下:

SQL> desc orphan_key_table

Name Null? Type

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

SCHEMA_NAME NOT NULL VARCHAR2(30)

INDEX_NAME NOT NULL VARCHAR2(30)

IPART_NAME VARCHAR2(30)

INDEX_ID NOT NULL NUMBER

TABLE_NAME NOT NULL VARCHAR2(30)

PART_NAME VARCHAR2(30)

TABLE_ID NOT NULL NUMBER

KEYROWID NOT NULL ROWID

KEY NOT NULL ROWID

DUMP_TIMESTAMP NOT NULL DATE

下列查詢顯示t1_pk index中有3個index entries與壞塊有關:

SQL> select index_name, count(*) from orphan_key_table

2 group by index_name;

INDEX_NAME COUNT(*)

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

T1_PK 3

在orphan_key_table 中的Index entry意味著該index應該重建,以保證一個table的指針和它的index指針返回同樣的結果集合。

六、使用DBMS_REPAIR.SKIP_CORRUPT_BLOCKS來跳過壞塊

SKIP_CORRUPT_BLOCKS用來決定在對指定object的index和table做搜索時是否跳過壞塊。

如果index和table不同步,那么一個‘SET TRANSACTION READ ONLY'的transaction可能會出現不一致的情況,例如一個查詢僅僅指向index,而它的子查詢卻同時指向index和table。 如果table的block已經被標識為壞了,那么這兩個查詢將會返回不同的結果。

建議:如果SKIP_CORRUPT_BLOCKS被enable,那么必須重建orphan_key_table中確定的所有indexes(或所有與該object相關的indexes,如果在DUMP_ORPHAN_KEYS被忽略的情況下)。

SQL> @skipCorruptBlocks

SQL> declare

2 begin

3 dbms_repair.skip_corrupt_blocks (

4 schema_name => 'SYSTEM',

5 object_name => 'T1',

6 object_type => dbms_repair.table_object,

7 flags => dbms_repair.skip_flag);

8 end;

9 /

PL/SQL procedure successfully completed.

下列查詢顯示跳過壞塊已經enable。

SQL> select table_name, skip_corrupt from dba_tables

2 where table_name = 'T1';

TABLE_NAME SKIP_COR

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

T1 ENABLED

壞塊中的記錄被跳過后,全表掃描不再顯示錯誤。

SQL> select * from system.t1;

COL1 COL2

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

4 dddd

5 eeee

注意此時pk index還沒有被修正。不能往t1 table中插入數據

SQL> insert into system.t1 values (1,'aaaa');

insert into system.t1 values (1,'aaaa')

*

SQL> select * from system.t1 where col1 = 1;

no rows selected

七、使用DBMS_REPAIR.REBUILD_FREELISTS重建freelists

REBUILD_FREELISTS重建指定object的freelists。

SQL> declare

2 begin

3 dbms_repair.rebuild_freelists (

4 schema_name => 'SYSTEM',

5 object_name => 'T1',

6 object_type => dbms_repair.table_object);

7 end;

8 /

PL/SQL procedure successfully completed.

八、重建Index

在orphan_key_table中確定的每一個index都必須重建,以保證查詢結果的一致。

SQL> alter index system.t1_pk rebuild online;

Index altered.

重建index后,就能往t1 table中插入數據。

SQL> insert into system.t1 values (1, 'aaaa');

1 row created.

SQL> select * from system.t1;

COL1 COL2

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

4 dddd

5 eeee

1 aaaa

以上的insert語句只是提供一個簡單的例子。如果我們真能知道丟失的數據內容,那當然是最好的。臨時表(temp_t1)應該用來存放所有從壞塊中抽取的記錄。

到此時table T1已經可以被再用,但同時數據也有丟失。一般來說,在使用DBMS_REPAIR package之前,應認真考慮數據的丟失問題,因為從index segment和table dump中采集信息非常復雜,同時邏輯上的不一致也可能被引入。要記?。涸贒BMS_REPAIR package 初始版本中,“修補壞塊”的功能僅僅是“將塊標識為由軟件引起的壞塊”而已。

在進行上述操作前,必須先閱讀〈Oracle8i Administrator's Guide〉中“Detecting and Repairing Data Block Corruption"章節,同時對風險進行評估。所有操作最好是在Oracle工程師的指導下進行。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 吕梁市| 彩票| 维西| 阿克苏市| 广东省| 巴里| 西充县| 三台县| 鸡西市| 田东县| 西城区| 太仆寺旗| 乐山市| 启东市| 河池市| 云龙县| 东方市| 蛟河市| 城市| 铜梁县| 迁安市| 都昌县| 安塞县| 南阳市| 寿阳县| 仪陇县| 青铜峡市| 天等县| 衡阳市| 潼关县| 元谋县| 黔西| 固阳县| 建水县| 莆田市| 唐海县| 苏尼特左旗| 吉安县| 太康县| 富川| 灵台县|