溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

oracle數(shù)據(jù)庫(kù)中如何格式化不屬于任何段的損壞塊

發(fā)布時(shí)間:2021-11-29 10:54:16 來(lái)源:億速云 閱讀:208 作者:柒染 欄目:數(shù)據(jù)庫(kù)

oracle數(shù)據(jù)庫(kù)中如何格式化不屬于任何段的損壞塊,相信很多沒(méi)有經(jīng)驗(yàn)的人對(duì)此束手無(wú)策,為此本文總結(jié)了問(wèn)題出現(xiàn)的原因和解決方法,通過(guò)這篇文章希望你能解決這個(gè)問(wèn)題。

一、問(wèn)題癥狀:

1. Rman 備份失敗,顯示 ORA-19566 錯(cuò)誤,且被報(bào)告的壞塊不屬于任何對(duì)象

2. Dbverify 顯示存在壞塊

3. 壞塊不屬于任何對(duì)象

二、原因分析:

在重新使用和重新格式化壞塊之前,RMAN 和 DBV 仍會(huì)一直報(bào)告壞塊。

三、解決方案:

解決此類(lèi)問(wèn)題的一個(gè)可能的方法如下。請(qǐng)注意,它不能保證問(wèn)題解決,但它已知解決了幾種案例的問(wèn)題。如果在某個(gè)數(shù)據(jù)文件中報(bào)告有很多塊損壞,請(qǐng)?jiān)诘诹教崾据斎? blocknumber 中輸入已經(jīng)報(bào)告的***的壞塊號(hào)碼。

當(dāng)一個(gè)對(duì)象被重新創(chuàng)建,已經(jīng)分配給它(甚至是損壞的塊)的塊將變成空閑空間(free  space)。他們?cè)谀抢锏却匦路峙涞揭粋€(gè)需要額外空間的對(duì)象。一旦它們被重新分配到用于一個(gè)對(duì)象上新的extent,只有當(dāng)任何DML操作使用到這些塊(即使損壞的塊,處在空閑空間,現(xiàn)在需要被分配),他們將在DML操作更改、使用這些塊之前,被重新格式化掉。

需要注意的是extent的簡(jiǎn)單的分配不格式化塊。第7步分配的extent和第8步執(zhí)行DML操作,使用在第七步中分配的塊,這樣的壞塊才被重用和格式化。

在本文檔中,我們嘗試手動(dòng)重新格式化壞塊。

第 1 步 - 確定損壞的數(shù)據(jù)文件

損壞可以被報(bào)告在應(yīng)用層,如DBV和RMAN,或alert.log。

例如,可以在您的RMAN備份過(guò)程中獲得以下信息:

RMAN-03009: failure of backup command on nm4501 channel at 04/29/2005  09:44:41

ORA-19566: exceeded limit of 0 corrupt blocks for file E:\xxxx\test.ORA.

壞塊位于文件 E:\xxxx\test.ORA 中。

第 2 步 - 在受影響的數(shù)據(jù)文件上運(yùn)行 DBV/Rman 驗(yàn)證并檢查壞塊

在報(bào)告壞塊的數(shù)據(jù)文件上運(yùn)行 dbverify。

# dbv userid={system/password} file={full path filename} logfile={output filename}

第 3 步 - 檢查塊是否是某個(gè)對(duì)象的一部分 - 適用于損壞的塊號(hào)小的情況

查詢(xún) dba_extents,確認(rèn)壞塊是否屬于任何對(duì)象。

SQL> select segment_name, segment_type, owner        from dba_extents       where file_id = <Absolute file number>         and <corrupted block number> between block_id             and block_id + blocks -1;

如果塊不屬于任何對(duì)象,查詢(xún)dba_free_space 確認(rèn)壞塊是否屬于數(shù)據(jù)文件的可用空間。

SQL> Select * from dba_free_space where file_id= <Absolute file number>      and <corrupted block number> between block_id and block_id + blocks -1;

第 4 步 - 查找受影響的塊并驗(yàn)證其是否屬于任何段的一種比較好的方法是使用 RMAN,這種方法既好用又便捷。

如果在第 2 步中已經(jīng)運(yùn)行了 rman 驗(yàn)證,請(qǐng)直接轉(zhuǎn)到下面給出的 sqlplus 腳本,以確認(rèn)對(duì)象。

$ rman target / nocatalog or $ rman target sys/ nocatalog   run { allocate channel d1 type disk; allocate channel d2 type disk; ---------------------------------------------------------------------- --  multiple channels may be allocated for parallelizing purposes --  depends: RMAN - Min ( MAXOPENFILES , FILESPERSET )  --  Defaults: MAXOPENFILES =8, FILESPERSET =64  ---------------------------------------------------------------------- allocate channel dn type disk; backup check logical validate database;

注意:如果RDBMS是小于11g并且處于非歸檔模式下,則數(shù)據(jù)庫(kù)必須處于 mounted 模式

*** 在進(jìn)行進(jìn)一步操作之前,*必須*運(yùn)行并完成 RMAN 命令“backup check logical validate database”。

*** 此命令完成(基于文件)后將會(huì)填充“v$database_block_corruption”視圖。

*** 如果未完成,在接下來(lái)的步驟中您就有可能得到無(wú)效/不完整的信息。

第 5 步 - 以非 SYS 或 SYSTEM(用戶(hù))的用戶(hù)身份創(chuàng)建一個(gè)虛擬表

SQL> connect scott/password

在包含出現(xiàn)壞塊的數(shù)據(jù)文件的表空間中創(chuàng)建虛擬表,并使用 nologging 選項(xiàng),以防止生成 redo記錄:

SQL> create table s (        n number,        c varchar2(4000)      ) nologging tablespace <tablespace name having the corrupt block> ;

不同的存儲(chǔ)參數(shù)可以被用來(lái)適應(yīng)特定的環(huán)境。

我們使用 PCTFREE 99以加快該塊的格式化

確認(rèn)表是被創(chuàng)建在正確的表空間中,通過(guò)查詢(xún) user_segments:

QL> select segment_name,tablespace_name from user_segments       where segment_name='S' ;

請(qǐng)注意,在11gR2中,由于延遲段創(chuàng)建概念,從上面提到的 user_segments 查詢(xún)可能不會(huì)報(bào)告。在這種情況下,查詢(xún) USER_TABLES

SQL> select segment_name,tablespace_name from user_tables where segment_name='S' ;

第 6 步 - 在虛擬表上創(chuàng)建觸發(fā)器,一旦重新使用壞塊,該觸發(fā)器便會(huì)引發(fā)異常

以 sysdba 身份連接,并創(chuàng)建以下觸發(fā)器:

請(qǐng)注意,在出現(xiàn)文件號(hào)提示時(shí),輸入相關(guān)文件號(hào)(v$datafile 中的 rfile# 值)

CREATE OR REPLACE TRIGGER corrupt_trigger    AFTER INSERT ON scott.s    REFERENCING OLD AS p_old NEW AS new_p    FOR EACH ROW  DECLARE    corrupt EXCEPTION;  BEGIN    IF (dbms_rowid.rowid_block_number(:new_p.rowid)=&blocknumber)  and (dbms_rowid.rowid_relative_fno(:new_p.rowid)=&filenumber) THEN       RAISE corrupt;    END IF;  EXCEPTION    WHEN corrupt THEN       RAISE_APPLICATION_ERROR(-20000, 'Corrupt block has been formatted');  END;  /

出現(xiàn)塊編號(hào)提示時(shí),輸入壞塊的塊編號(hào)。

出現(xiàn)文件號(hào)提示時(shí),輸入損壞的數(shù)據(jù)文件的相關(guān)文件號(hào)(v$datafile 中的 rfile# 值)。

第 7 步 - 為受影響的數(shù)據(jù)文件中的表分配空間。

請(qǐng)注意:

1)如果這是一個(gè)ASSM表空間,你可能需要重復(fù)此步驟數(shù)次。也就是說(shuō),創(chuàng)建多個(gè)表和分配多個(gè) extent。

并周期性地查看 dba_extents,以確保空閑空間現(xiàn)在分配給一個(gè)虛擬表。

這是因?yàn)锳SSM將自動(dòng)確定下一個(gè) extent 的大小

2)建議確保數(shù)據(jù)文件 AUTOEXTEND 置為 OFF,以防止其增長(zhǎng)。

首先通過(guò)查詢(xún) dba_free_space 查找 extent 大小

SQL> Select BYTES from dba_free_space where file_id=<file no> and <corrupt block no> between block_id and block_id + blocks -1;  BYTES ---------------- ---------- ---------- ---------- ---------- ------------  65536

在本例中,它的大小是 64K。因此,按照以下方法分配 extent:

SQL> alter table scott.s  allocate extent (DATAFILE 'E:\xxxx\test.ORA' SIZE 64K);

如果在這個(gè)數(shù)據(jù)文件中有多個(gè)64K的空閑 extent,則可能需要使用這個(gè)循環(huán):

BEGIN for i in 1..1000000 loop EXECUTE IMMEDIATE 'alter table scott.s allocate extent (DATAFILE '||'''E:\xxxx\test.ORA''' ||'SIZE 64K) '; end loop; end ; /

繼續(xù)分配空間直到壞塊成為 scott.s 的一部分 &mdash; 使用以下查詢(xún)進(jìn)行檢查:

SQL> select segment_name, segment_type, owner        from dba_extents        where file_id = <Absolute file number>         and <corrupt block number> between block_id              and block_id + blocks -1 ;

第 8 步 - 向虛擬表中插入數(shù)據(jù)以格式化塊

示例代碼(取決于表空間的大小,循環(huán)的次數(shù)可能發(fā)生變化):

BEGIN  FOR i IN 1..1000000000 LOOP  INSERT /*+ APPEND */ INTO scott.s select i, lpad('REFORMAT',3092, 'R') from dual;  commit ;  END LOOP;  END;

或者

BEGIN   FOR i IN 1..1000000000 LOOP     INSERT INTO scott.s VALUES(i,'x');   END LOOP; END; /

或使用以下包含 2 個(gè)循環(huán)的代碼:

Begin   FOR i IN 1..1000000000 loop     for j IN 1..1000 loop       Insert into scott.s VALUES(i,'x');     end loop;     commit;   END LOOP; END;

每向表中插入一行就會(huì)觸發(fā)觸發(fā)器,且一旦向壞塊中插入***行數(shù)據(jù),就會(huì)產(chǎn)成 ORA-20000 異常。

第 9 步 - 通過(guò)運(yùn)行 DBV 和 Rman 備份確定數(shù)據(jù)文件中的壞塊情況

運(yùn)行 dbverify 或 RMAN 在損壞的數(shù)據(jù)文件(或整個(gè)數(shù)據(jù)庫(kù))上再次驗(yàn)證。它不會(huì)顯示塊損壞。

確保你做兩次手動(dòng)日志切換或檢查點(diǎn),使得在內(nèi)存中的信息寫(xiě)入到磁盤(pán)。

RMAN 備份不會(huì)報(bào)告此塊上的任何錯(cuò)誤。

運(yùn)行真實(shí)的備份操作之前,你可以在數(shù)據(jù)文件上重新運(yùn)行 RMAN validate 命令,并檢查 v$database_block_corruption  不再顯示塊被標(biāo)記為損壞。

對(duì)于數(shù)據(jù)庫(kù)版本 <=10gR2

Rman> Backup validate check logical datafile <fileno>,<fileno> ;

對(duì)于數(shù)據(jù)庫(kù)版本>=11gR1

Rman> Backup validate check logical datafile <fileno> ;

Rman> validate datafile <fileno> block <blockno reported corrupt>, <blockno reported corrupt> ;

一旦完成

SQL> SELECT * FROM V $ DATABASE_BLOCK_CORRUPTION;

第 10 步 - 刪除第 4 步中創(chuàng)建的虛擬表

SQL> DROP TABLE scott.s ;

如果版本為 10gr1 及以上,同時(shí)使用purge選項(xiàng)以清空回收站

第 11 步 &ndash; 執(zhí)行手動(dòng)日志切換和檢查點(diǎn)

執(zhí)行兩次日志切換和檢查點(diǎn),以便將在內(nèi)存中格式化的塊寫(xiě)入到磁盤(pán)并使 dbverify 不再報(bào)告錯(cuò)誤

SQL>Alter system switch logfile ; --> Do this couple of time  SQL>Alter system checkpoint ;

第 12 步 - 刪除第 6 步中創(chuàng)建的觸發(fā)器

SQL> DROP triggercorrupt_trigger ;

看完上述內(nèi)容,你們掌握oracle數(shù)據(jù)庫(kù)中如何格式化不屬于任何段的損壞塊的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI