自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Oracle 數(shù)據(jù)壞塊的 N 種修復(fù)方式

數(shù)據(jù)庫(kù) Oracle
今天就給大家講講怎么處理數(shù)據(jù)表的壞塊情況!對(duì)于 Oracle 數(shù)據(jù)塊物理?yè)p壞 的情形,通??梢苑譃閮煞N情況:有備份,通過(guò) RMAN 恢復(fù),無(wú)備份,通過(guò) DBMS_REPAIR 修復(fù).

[[438673]]

前言

Oracle 數(shù)據(jù)庫(kù)的運(yùn)行不可避免的會(huì)遇到各種各樣的錯(cuò)誤,就比如數(shù)據(jù)表出現(xiàn)壞塊,此時(shí),你這張表的數(shù)據(jù)就無(wú)法訪問(wèn)了,有什么好的辦法可以恢復(fù)呢?

什么,你沒(méi)有遇到過(guò)?😱

😏 那就祝你不久的將來(lái)遇到,哈哈開個(gè)玩笑~ 玩歸玩,鬧歸鬧,經(jīng)驗(yàn)必須要老到!👍🏻

一、介紹

今天就給大家講講怎么處理數(shù)據(jù)表的壞塊情況!🎉

對(duì)于 Oracle 數(shù)據(jù)塊物理?yè)p壞 的情形,通常可以分為兩種情況:

有備份,通過(guò) RMAN 恢復(fù)

無(wú)備份,通過(guò) DBMS_REPAIR 修復(fù)

1、RMAN

有備份的情況下,這是很理想的情形,我們可以直接通過(guò) RMAN 塊介質(zhì)恢復(fù)(BLOCK MEDIA RECOVERY)功能來(lái)完成受損塊的恢復(fù)。

這里我是不建議恢復(fù)整個(gè)數(shù)據(jù)庫(kù)或者數(shù)據(jù)庫(kù)文件來(lái)修復(fù)這些少量受損的數(shù)據(jù)塊,有點(diǎn)浪費(fèi)時(shí)間。

可參考官方文檔:Block Media Recovery with RMAN

2、DBMS_REPAIR

那如果沒(méi)有任何備份怎么辦? (PS:備份大于一切!)

我們可以使用 Oracle 自帶的 DBMS_REPAIR 包來(lái)實(shí)現(xiàn)修復(fù)。

📢 注意: 使用 DBMS_REPAIR 包來(lái)修復(fù),并非完全恢復(fù),而是標(biāo)記壞塊,然后不對(duì)其進(jìn)行訪問(wèn),這部分被標(biāo)記的數(shù)據(jù)也就丟失了,這是無(wú)法避免的。

可參考MOS文檔:DBMS_REPAIR SCRIPT (Doc ID 556733.1)

二、實(shí)戰(zhàn)環(huán)境準(zhǔn)備

1、環(huán)境安裝可參考我的一鍵安裝腳本:Oracle 數(shù)據(jù)庫(kù)一鍵安裝,從未如此簡(jiǎn)單

  1. cd /Volumes/DBA/voracle/github/single_db 
  2. vagrant up 
  3. vagrant ssh 

2、測(cè)試數(shù)據(jù)準(zhǔn)備

創(chuàng)建表空間:

  1. create tablespace eason datafile '/oradata/orcl/eason.dbf' size 1g autoextend on

創(chuàng)建用戶:

  1. create user eason identified by eason default tablespace eason; 
  2. grant dba to eason; 

創(chuàng)建測(cè)試表:

  1. create table hyj as select * from dba_objects; 

創(chuàng)建表索引:

  1. create index i_hyj on hyj(object_id); 

3、查看表相關(guān)信息

查看表段上的相關(guān)信息:

  1. select segment_name , header_file , header_block,blocks from dba_segments where segment_name ='HYJ';  

查出包含行記錄的數(shù)據(jù)塊:

  1. select distinct dbms_rowid.rowid_block_number(rowid) from eason.hyj order by 1; 
  2.  
  3. DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID) 
  4. ------------------------------------ 
  5.                                 1411 
  6.                                 1412 
  7.                                 1413 
  8.         ... 
  9.         ... 
  10.         ...  
  11.                                 2665 
  12.                                 2666 
  13.                                 2667 
  14.  
  15. 1232 rows selected. 

  1. select * from dba_extents where segment_name='HYJ'

📢 注意: 這里看到 HEADER_BLOCK 和 BLOCK_ID 不一致,其實(shí)一個(gè) segment 的第一個(gè)區(qū)的第一個(gè)塊是 FIRST LEVEL BITMAP BLOCK,第二個(gè)塊是 SECOND LEVEL BITMAP BLOCK,這兩個(gè)塊是用來(lái)管理 free block 的,第三個(gè)塊是 PAGETABLE SEGMENT HEADER,這個(gè)塊才是 segment 里的 HEADER_BLOCK。

4、RMAN 備份

首先,我們先做一個(gè)全備份,用來(lái)演示 RMAN 修復(fù)壞塊!

  1. run { 
  2. allocate channel c1 device type disk; 
  3. allocate channel c2 device type disk; 
  4. crosscheck backup; 
  5. crosscheck archivelog all
  6. sql"alter system switch logfile"
  7. delete noprompt expired backup; 
  8. delete noprompt obsolete device type disk; 
  9. backup database include current controlfile format '/backup/backlv_%d_%T_%t_%s_%p'
  10. backup archivelog all DELETE INPUT; 
  11. release channel c1; 
  12. release channel c2; 

5、模擬壞塊

破壞 1468、1688、2468 數(shù)據(jù)塊的內(nèi)容:

  1. dd if=/dev/zero of=/oradata/orcl/eason.dbf bs=8192 conv=notrunc seek=1468 count=1 
  2. dd if=/dev/zero of=/oradata/orcl/eason.dbf bs=8192 conv=notrunc seek=1688 count=1 
  3. dd if=/dev/zero of=/oradata/orcl/eason.dbf bs=8192 conv=notrunc seek=2468 count=1 

清除 buffer cache 的內(nèi)容:

  1. alter system flush buffer_cache; 

再次查詢表 hyj,此時(shí)查詢已經(jīng)報(bào)錯(cuò),發(fā)現(xiàn)有壞塊:

  1. select * from eason.hyj; 

 

當(dāng)然,也可以使用 bbed 進(jìn)行壞塊模擬!

6、壞塊檢查

下面再介紹幾種發(fā)現(xiàn)壞塊的方式:

(1)使用 DBV 檢查當(dāng)前文件的壞塊:

  1. dbv file=/oradata/orcl/eason.dbf blocksize=8192; 

使用 DBV檢查,同樣發(fā)現(xiàn)了壞塊!

(2)使用 rman 檢查數(shù)據(jù)庫(kù)壞塊:

  1. ## 檢查對(duì)應(yīng)的數(shù)據(jù)文件 
  2. backup check logical validate datafile 5; 
  3. ## 檢查當(dāng)前數(shù)據(jù)庫(kù) 
  4. backup validate check logical database

結(jié)合 V$DATABASE_BLOCK_CORRUPTION 視圖查看,更加方便:

  1. select * from V$DATABASE_BLOCK_CORRUPTION; 

使用 RMAN 檢查后,同樣發(fā)現(xiàn)了壞塊!

(3)通過(guò)數(shù)據(jù)庫(kù)的告警日志也可以發(fā)現(xiàn)報(bào)錯(cuò):

(4)通過(guò)報(bào)錯(cuò)信息快速查找對(duì)應(yīng)的壞表,依次填寫數(shù)據(jù)文件 ID 5 和 壞塊 ID 1468:

  1. SELECT tablespace_name, segment_type, owner, segment_name 
  2. FROM dba_extents 
  3.         WHERE file_id = &fileid 
  4. and &blockid between block_id AND block_id + blocks - 1; 

實(shí)驗(yàn)環(huán)境準(zhǔn)備完畢,下面開始實(shí)戰(zhàn)!

三、實(shí)戰(zhàn)演示

今天,我打算使用上述介紹的 2 種方式來(lái)演示!

1、RMAN 修復(fù)

由于我們之前已經(jīng)備份了,因此直接使用備份來(lái)恢復(fù)壞塊:

  1. blockrecover datafile 5 block 1468; 

  1. blockrecover datafile 5 block 1688,2468; 

使用同樣的方式,依次修復(fù)壞塊 1688,2468,修復(fù)成功后,查詢已恢復(fù)正常!

再次檢查壞塊情況:

  1. backup validate check logical database
  2. select * from V$DATABASE_BLOCK_CORRUPTION; 

壞塊已經(jīng)都被恢復(fù),并且數(shù)據(jù)沒(méi)有丟失!

2、DBMS_REPAIR 修復(fù)

首先,依然使用 dd 先模擬壞塊:

  1. dd if=/dev/zero of=/oradata/orcl/eason.dbf bs=8192 conv=notrunc seek=3333 count=1 
  2. dd if=/dev/zero of=/oradata/orcl/eason.dbf bs=8192 conv=notrunc seek=3368 count=1 
  3. dd if=/dev/zero of=/oradata/orcl/eason.dbf bs=8192 conv=notrunc seek=4000 count=1 

 

在沒(méi)有備份的前提下,我們就無(wú)法做到無(wú)損修復(fù)壞塊了,需要損失對(duì)應(yīng)壞塊的數(shù)據(jù)。

(1)創(chuàng)建 repair 表,用于記錄需要被修復(fù)的表:

  1. begin 
  2. dbms_repair.admin_tables ( 
  3.      table_name => 'REPAIR_TABLE'
  4.      table_type => dbms_repair.repair_table, 
  5.      action => dbms_repair.create_action, 
  6.      tablespace => 'USERS'); 
  7. end

(2)創(chuàng)建 Orphan Key 表,用于記錄在表塊損壞后那些孤立索引,也就是指向壞塊的那些索引 :

  1. begin 
  2. dbms_repair.admin_tables ( 
  3.      table_name => 'ORPHAN_KEY_TABLE'
  4.      table_type => dbms_repair.orphan_table, 
  5.      action => dbms_repair.create_action, 
  6.      tablespace => 'USERS'); 
  7. end

(3)檢查壞塊,檢測(cè)對(duì)象上受損的情形,并返回受損塊數(shù)為 3:

  1. declare 
  2.   num_corrupt int
  3. begin 
  4.   num_corrupt := 0; 
  5. DBMS_REPAIR.CHECK_OBJECT ( 
  6.   schema_name =>'EASON'
  7.   object_name =>'HYJ'
  8.   repair_table_name =>'REPAIR_TABLE'
  9.   corrupt_count =>num_corrupt); 
  10.   dbms_output.put_line('number corrupt:' || to_char(num_corrupt)); 
  11. end

(4)查看受損的塊信息:

  1. select object_name, block_id, corrupt_type, marked_corrupt, repair_description from repair_table; 

📢 注意: 這里 marked_corrupt 被標(biāo)記為 TRUE,應(yīng)該是系統(tǒng)在執(zhí)行 CHECK_OBJECT 過(guò)程中自動(dòng)完成了FIX_CORRUPT_BLOCKS。如果被標(biāo)記為 FALSE,需要再運(yùn)行 FIX_CORRUPT_BLOCKS 來(lái)完成壞塊的標(biāo)記工作。

(5)修復(fù)被損壞的數(shù)據(jù)塊,這些被損壞的數(shù)據(jù)塊是在執(zhí)行了 check_object 之后生成的:

  1. declare 
  2.   cc number; 
  3. begin 
  4.   dbms_repair.fix_corrupt_blocks(schema_name => 'EASON'
  5.   object_name => 'HYJ'
  6.   fix_count => cc); 
  7.   dbms_output.put_line('Number of blocks fixed: ' || to_char(cc)); 
  8. end

標(biāo)記了 0 個(gè)壞塊,說(shuō)明 CHECK_OBJECT 完成了標(biāo)記工作。

(6)使用 DUMP_ORPHAN_KEYS 過(guò)程將那些指向壞塊的索引鍵值填充到 ORPHAN_KEY_TABLE:

  1. declare 
  2.    cc number; 
  3. begin 
  4.   dbms_repair.dump_orphan_keys 
  5.   ( 
  6.      schema_name => 'EASON'
  7.      object_name => 'I_HYJ',  
  8.      object_type => dbms_repair.index_object, 
  9.      repair_table_name => 'REPAIR_TABLE'
  10.      orphan_table_name=> 'ORPHAN_KEY_TABLE'
  11.      key_count => cc 
  12.   ); 
  13.   dbms_output.put_line('Number of orphan keys: ' || to_char(cc)); 
  14. end

表明 202 條記錄被損壞丟失!

📢 注意: 此處一定要注意 object_name 是索引名,而不是 table_name,這里 dump 的是損壞的索引信息.如果表有多個(gè)索引,需要為每個(gè)索引執(zhí)行 DUMP_ORPHAN_KEYS 操作。

(7)驗(yàn)證對(duì)象是否可以查詢,下面的結(jié)果顯示依舊無(wú)法查詢:

  1. select count(*) from eason.hyj; 

(8)跳過(guò)壞塊:

  1. BEGIN 
  2.   DBMS_REPAIR.SKIP_CORRUPT_BLOCKS ( 
  3.      SCHEMA_NAME => 'EASON'
  4.      OBJECT_NAME => 'HYJ'
  5.      OBJECT_TYPE => dbms_repair.table_object, 
  6.      FLAGS => dbms_repair.skip_flag); 
  7. END

📢 注意: 丟失 202 條記錄,丟失記錄的 rowid 可以在 ORPHAN_KEY_TABLE 表中找到。

(9)重建索引:

  1. alter index eason.I_HYJ rebuild; 

(10)驗(yàn)證結(jié)果

至此,表中數(shù)據(jù)可以順利被訪問(wèn)!

由于壞塊并沒(méi)有消失,而是被標(biāo)記跳過(guò),因此還是可以查看壞塊:

  1. select * from V$DATABASE_BLOCK_CORRUPTION; 

用這種方法可以找回部分?jǐn)?shù)據(jù),也可以找回建了索引的值,但是使用dbv再檢查表空間的數(shù)據(jù)文件時(shí),仍然會(huì)顯示有損壞的數(shù)據(jù)塊。

這時(shí)需要把表的數(shù)據(jù)全部導(dǎo)出,再重建表或者表空間,然后再把找回的數(shù)據(jù)導(dǎo)入數(shù)據(jù)庫(kù),推薦用 expdp/impdp 命令做,可以徹底消除 dbv 檢查到的壞塊。

寫在最后

備份大于一切,也是最后的防線,所以請(qǐng)大家一定要做好備份!886

責(zé)任編輯:姜華 來(lái)源: Lucifer三思而后行
相關(guān)推薦

2010-10-13 11:19:11

MySQL數(shù)據(jù)文件

2010-06-13 17:35:17

MySQL數(shù)據(jù)表

2009-03-17 13:59:26

ORA-01578壞塊Oracle

2022-03-18 09:42:54

JavaString

2023-03-06 09:20:33

CSS顏色混合

2010-04-07 18:26:43

Oracle數(shù)據(jù)庫(kù)

2011-03-14 13:33:32

Oracle數(shù)據(jù)庫(kù)啟動(dòng)

2011-02-28 13:31:17

Oracle數(shù)據(jù)庫(kù)

2011-04-12 15:44:08

Oracle數(shù)據(jù)庫(kù)

2025-04-27 08:05:00

Linux時(shí)間同步

2023-06-16 15:17:21

sprint工具

2010-04-06 10:52:06

Oracle數(shù)據(jù)庫(kù)

2010-04-15 15:52:12

Oracle數(shù)據(jù)庫(kù)

2010-04-19 16:08:31

Oracle數(shù)據(jù)庫(kù)

2010-10-26 14:06:43

oracle連接遠(yuǎn)程數(shù)

2010-06-17 09:39:07

Ubuntu Grub

2018-07-09 14:52:05

2021-07-26 08:31:17

算法

2010-06-13 12:59:15

Ubuntu xp G

2010-06-12 11:26:21

Grub Rescue
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)