【轉】基於RMAN實現壞塊介質恢復(blockrecover)

来源:http://www.cnblogs.com/sanlu/archive/2017/01/09/6264764.html
-Advertisement-
Play Games

本文轉自:樂沙彌的世界 對於物理損壞的數據塊,我們可以通過RMAN塊介質恢復(BLOCK MEDIA RECOVERY)功能來完成受損塊的恢復,而不需要恢復整個資料庫或所有文件來修複這些少量受損的數據塊。恢復整個資料庫或數據文件那不是大炮用來打蚊子,有點不值得!但前提條件是你得有一個可用的RMAN備 ...


 

     本文轉自:樂沙彌的世界

 

 

對於物理損壞的數據塊,我們可以通過RMAN塊介質恢復(BLOCK MEDIA RECOVERY)功能來完成受損塊的恢復,而不需要恢復整個資料庫或所有文件來修複這些少量受損的數據塊。恢復整個資料庫或數據文件那不是大炮用來打蚊子,有點不值得!但前提條件是你得有一個可用的RMAN備份存在,因此,無論何時備份就是一切。本文演示了產生壞塊即使用RMAN實現壞塊恢復的全過程。

1、創建演示環境

SQL> select * from v$version where rownum<2;

BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production

--創建用於演示的data file
SQL> create tablespace tbs_tmp datafile '/u02/database/usbo/oradata/tbs_tmp.dbf' size 10m autoextend on;

SQL> conn scott/tiger;

--基於新的數據文件創建對象tb_tmp
SQL> create table tb_tmp tablespace tbs_tmp as select * from dba_objects;

SQL> col file_name format a60
SQL> select file_id,file_name from dba_data_files where tablespace_name='TBS_TMP';

   FILE_ID FILE_NAME
---------- ------------------------------------------------------------
         6 /u02/database/usbo/oradata/tbs_tmp.dbf

--表對象tb_tmp上的信息,包含對應的文件信息,頭部塊,總塊數
SQL> select segment_name , header_file , header_block,blocks      
  2  from dba_segments
  3  where segment_name = 'TB_TMP' and owner='SCOTT';

SEGMENT_NAME                   HEADER_FILE HEADER_BLOCK     BLOCKS
------------------------------ ----------- ------------ ----------
TB_TMP                                   6          130       1152

--首先使用rman備份對應的數據文件
$ $ORACLE_HOME/bin/rman target /
RMAN> backup datafile 6 tag=health;

Starting backup at 2013/08/28 17:03:15
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=24 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=/u02/database/usbo/oradata/tbs_tmp.dbf
channel ORA_DISK_1: starting piece 1 at 2013/08/28 17:03:16
channel ORA_DISK_1: finished piece 1 at 2013/08/28 17:03:17
piece handle=/u02/database/usbo/fr_area/USBO/backupset/2013_08_28/o1_mf_nnndf_HEALTH_91vh6ntb_.bkp tag=HEALTH comment=NONE
channel ORA_DISK_1: backup set complete, elapsed time: 00:00:01
Finished backup at 2013/08/28 17:03:17
RMAN> exit

2、單塊數據塊損壞的恢復處理

--下麵使用了linux自帶的dd命令來損壞單塊數據塊
[oracle@linux1 ~]$ dd of=/u02/database/usbo/oradata/tbs_tmp.dbf bs=8192 conv=notrunc seek=130 <<EOF
> Corrupted block!
> EOF
0+1 records in
0+1 records out
17 bytes (17 B) copied, 0.000184519 seconds, 92.1 kB/s

--清空buffer cache
SQL> alter system flush buffer_cache;

--查詢表對相 tb_tmp,收到ORA-01578
SQL> select count(*) from tb_tmp;
select count(*) from tb_tmp
*
ERROR at line 1:
ORA-01578: ORACLE data block corrupted (file # 6, block # 130)
ORA-01110: data file 6: '/u02/database/usbo/oradata/tbs_tmp.dbf'

--查詢視圖v$database_block_corruption,提示有壞塊,註意該視圖可能不會返回任何數據,如無返回,先執行backup validate
SQL> select * from v$database_block_corruption;

     FILE#     BLOCK#     BLOCKS CORRUPTION_CHANGE# CORRUPTIO
---------- ---------- ---------- ------------------ ---------
         6        129          1                  0 CORRUPT

--也可以使用dbv工具來校驗壞塊,參考: http://blog.csdn.net/robinson_0612/article/details/6530890   

--下麵使用blockrecover來恢復壞塊      
RMAN> blockrecover datafile 6 block 130;

Starting recover at 2013/08/28 17:22:25
using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=24 device type=DISK

channel ORA_DISK_1: restoring block(s)
channel ORA_DISK_1: specifying block(s) to restore from backup set
restoring blocks of datafile 00006
channel ORA_DISK_1: reading from backup piece /u02/database/usbo/fr_area/USBO/backupset/2013_08_28/o1_mf_nnndf_HEALTH_91vh6ntb_.bkp
channel ORA_DISK_1: piece handle=/u02/database/usbo/fr_area/USBO/backupset/2013_08_28/o1_mf_nnndf_HEALTH_91vh6ntb_.bkp tag=HEALTH
channel ORA_DISK_1: restored block(s) from backup piece 1
channel ORA_DISK_1: block restore complete, elapsed time: 00:00:01

starting media recovery
media recovery complete, elapsed time: 00:00:03

Finished recover at 2013/08/28 17:22:31

--再次查詢表tb_emp正常
SQL> select count(*) from tb_tmp;

  COUNT(*)
----------
     72449

3、多塊數據塊損壞的恢復處理

--下麵使用linux dd命令對不連續塊損壞
[oracle@linux1 ~]$ dd of=/u02/database/usbo/oradata/tbs_tmp.dbf bs=8192 conv=notrunc seek=133 <<EOF
> New corrupted block!
> EOF
0+1 records in
0+1 records out
21 bytes (21 B) copied, 0.000182835 seconds, 115 kB/s
[oracle@linux1 ~]$ dd of=/u02/database/usbo/oradata/tbs_tmp.dbf bs=8192 conv=notrunc seek=143 <<EOF 
> New corrupted block!
> EOF
0+1 records in
0+1 records out
21 bytes (21 B) copied, 0.000115527 seconds, 182 kB/s
[oracle@linux1 ~]$ dd of=/u02/database/usbo/oradata/tbs_tmp.dbf bs=8192 conv=notrunc seek=153 <<EOF 
> New corrupted block!
> EOF
0+1 records in
0+1 records out
21 bytes (21 B) copied, 0.000335781 seconds, 62.5 kB/s

SQL> alter system flush buffer_cache;

--下麵提示塊133被損壞,註意我們損壞了多塊數據塊,但查詢時,從塊號最小的開始提示,如133被修複後還有壞塊則繼續提示133之後的壞塊
SQL> select count(*) from scott.tb_tmp;
select count(*) from scott.tb_tmp
*
ERROR at line 1:
ORA-01578: ORACLE data block corrupted (file # 6, block # 133)
ORA-01110: data file 6: '/u02/database/usbo/oradata/tbs_tmp.dbf'

--查詢視圖v$database_block_corruption無任何記錄
SQL> select * from v$database_block_corruption;

no rows selected

--下麵使用backup validate來校驗數據文件
RMAN> backup validate datafile 6;

Starting backup at 2013/08/29 09:42:04
using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=22 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=/u02/database/usbo/oradata/tbs_tmp.dbf
channel ORA_DISK_1: backup set complete, elapsed time: 00:00:01
List of Datafiles
=================
File Status Marked Corrupt Empty Blocks Blocks Examined High SCN
---- ------ -------------- ------------ --------------- ----------
6    FAILED 0              223          1408            838489       --欄位Status為FAILED
  File Name: /u02/database/usbo/oradata/tbs_tmp.dbf
  Block Type Blocks Failing Blocks Processed
  ---------- -------------- ----------------
  Data       0              1029            
  Index      0              0               
  Other      3              156             --有3個Blocks Failing

validate found one or more corrupt blocks
See trace file /u02/database/usbo/diag/rdbms/usbo/usbo/trace/usbo_ora_27874.trc for details
Finished backup at 2013/08/29 09:42:06

--再次查詢v$database_block_corruption,表明有3個損壞的塊
SQL> select * from v$database_block_corruption;

     FILE#     BLOCK#     BLOCKS CORRUPTION_CHANGE# CORRUPTIO
---------- ---------- ---------- ------------------ ---------
         6        153          1                  0 CORRUPT
         6        143          1                  0 CORRUPT
         6        133          1                  0 CORRUPT

--下麵直接使用blockrecover corruption list來恢復,如下所有剛剛被校驗的壞塊都會被恢復
RMAN> blockrecover corruption list;  

Starting recover at 2013/08/29 10:05:24
using channel ORA_DISK_1

channel ORA_DISK_1: restoring block(s)
channel ORA_DISK_1: specifying block(s) to restore from backup set
restoring blocks of datafile 00006
channel ORA_DISK_1: reading from backup piece /u02/database/usbo/fr_area/USBO/backupset/2013_08_28/o1_mf_nnndf_HEALTH_91vh6ntb_.bkp
channel ORA_DISK_1: piece handle=/u02/database/usbo/fr_area/USBO/backupset/2013_08_28/o1_mf_nnndf_HEALTH_91vh6ntb_.bkp tag=HEALTH
channel ORA_DISK_1: restored block(s) from backup piece 1
channel ORA_DISK_1: block restore complete, elapsed time: 00:00:01

starting media recovery
media recovery complete, elapsed time: 00:00:03

Finished recover at 2013/08/29 10:05:28

--校驗結果
SQL> select count(*) from scott.tb_tmp;

  COUNT(*)
----------
     72449

4、壞塊的對象定位與影響

--下麵我們查詢塊號為163上的對象
SQL> select dbms_rowid.rowid_object(rowid) object_id,dbms_rowid.rowid_relative_fno(rowid) file_id,
  2  dbms_rowid.rowid_block_number(rowid) block_id,owner,object_name,object_id
  3  from scott.tb_tmp where dbms_rowid.rowid_block_number(rowid)=163 and rownum<=2;

 OBJECT_ID    FILE_ID   BLOCK_ID OWNER        OBJECT_NAME                     OBJECT_ID
---------- ---------- ---------- ------------ ------------------------------ ----------
     74555          6        163 SYS          GV_$QUEUEING_MTH                     2439
     74555          6        163 PUBLIC       GV$QUEUEING_MTH                      2440

--使用上面的方法,我們損塊塊163,173,此處不再列出

a、對於壞塊對象無法進行聚合彙總等操作     
SQL> select count(*) from scott.tb_tmp;
select count(*) from scott.tb_tmp
*
ERROR at line 1:
ORA-01578: ORACLE data block corrupted (file # 6, block # 163)
ORA-01110: data file 6: '/u02/database/usbo/oradata/tbs_tmp.dbf'

b、對於壞塊上的記錄無法被查詢
--我們使用基於之前查詢到的OBJECT_ID來查詢
SQL> select owner,object_name,object_id from scott.tb_tmp where object_id in(2439,2440);
select owner,object_name,object_id from scott.tb_tmp where object_id in(2439,2440)
                                              *
ERROR at line 1:
ORA-01578: ORACLE data block corrupted (file # 6, block # 163)
ORA-01110: data file 6: '/u02/database/usbo/oradata/tbs_tmp.dbf'

--如下麵的查詢,位於損壞塊上的數據無法被查詢到,但對於未損壞的依舊可以查詢。下麵的查詢時塊161上的對象
SQL> select owner,object_name,object_id from scott.tb_tmp 
  2  where dbms_rowid.rowid_block_number(rowid)=161 and rownum<3;

OWNER                          OBJECT_NAME                     OBJECT_ID
------------------------------ ------------------------------ ----------
PUBLIC                         GV$RECOVERY_LOG                      2285
SYS                            GV_$ARCHIVE_GAP                      2286

--Author : Robinson Cheng
--Blog   : http://blog.csdn.net/robinson_0612
     
c、定位受損塊所對應的對象
SQL> run get_obj_name_from_corrupt_block
  1  SELECT tablespace_name,
  2         segment_type,
  3         owner,
  4         segment_name,
  5         partition_name
  6    FROM dba_extents
  7*  WHERE file_id = &file_id AND &block_id BETWEEN block_id AND block_id + blocks - 1
Enter value for file_id: 6
Enter value for block_id: 133
old   7:  WHERE file_id = &file_id AND &block_id BETWEEN block_id AND block_id + blocks - 1
new   7:  WHERE file_id = 6 AND 133 BETWEEN block_id AND block_id + blocks - 1

TABLESPACE_NAME                SEGMENT_TYPE       OWNER          SEGMENT_NAME      PARTITION_NAME
------------------------------ ------------------ -------------- ----------------- -----------------
TBS_TMP                        TABLE              SCOTT          TB_TMP 

d、對於損壞的數據文件,預設情況下,不能對其進行備份,如下
RMAN> backup datafile 6 tag='corruption';                                                    
                                                                                                      
Starting backup at 2013/08/29 10:37:32                                                       
using channel ORA_DISK_1                                                                     
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=/u02/database/usbo/oradata/tbs_tmp.dbf                 
channel ORA_DISK_1: starting piece 1 at 2013/08/29 10:37:32                                  
RMAN-00571: ===========================================================                      
RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============                      
RMAN-00571: ===========================================================                      
RMAN-03009: failure of backup command on ORA_DISK_1 channel at 08/29/2013 10:37:33           
ORA-19566: exceeded limit of 0 corrupt blocks for file /u02/database/usbo/oradata/tbs_tmp.dbf 

--需要設定允許損壞塊的數量之後才能進行備份
RMAN> run{
2> set maxcorrupt for datafile 6 to 2;
3> backup datafile 6 tag='corruption';
4> }

executing command: SET MAX CORRUPT

Starting backup at 2013/08/29 10:41:24
using channel ORA_DISK_1
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=/u02/database/usbo/oradata/tbs_tmp.dbf
channel ORA_DISK_1: starting piece 1 at 2013/08/29 10:41:25
channel ORA_DISK_1: finished piece 1 at 2013/08/29 10:41:26
piece handle=/u02/database/usbo/fr_area/USBO/backupset/2013_08_29/o1_mf_nnndf_CORRUPTION_91xf6o18_.bkp tag=CORRUPTION comment=NONE
channel ORA_DISK_1: backup set complete, elapsed time: 00:00:01
Finished backup at 2013/08/29 10:41:26       

--查看備份信息如下,應在修複壞塊後重新備份以避免由於保留策略導致先前可用的備份被aged out
RMAN> list backup summary;

List of Backups
===============
Key     TY LV S Device Type Completion Time     #Pieces #Copies Compressed Tag
------- -- -- - ----------- ------------------- ------- ------- ---------- ---
1       B  F  A DISK        2013/08/28 17:03:17 1       1       NO         HEALTH
3       B  F  A DISK        2013/08/29 10:41:25 1       1       NO         CORRUPTION

5、後記

a、對於受損的數據塊,僅僅壞塊上的數據無法被查詢或讀取,其餘正常塊的數據依舊可以使用。
b、對於受損的表對象進行聚合等相關運算時收到錯誤提示,因為壞塊上的數據無法被統計。如果你聚合的是索引列,索引未損壞的情形則可正常返回。
c、可以基於RMAN可用的備份文件實現塊介質恢復,其數據文件無需offline,開銷最小,影響最小。
d、對於多個數據塊的損壞,先執行backup validate校驗資料庫或相應的數據文件以便標記受損的壞塊後,填充v$database_block_corruption以及後續恢復。
e、對於使用backup validate 校驗後的情形,壞塊恢復時可以直接使用blockrecover corruption list一次性恢復所有的壞塊。
f、預設情況下,存在壞塊的數據文件無法成功備份,也會導致自動備份腳本失敗。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 記憶體分配機制Slab Allocation 本文參考博客:https://my.oschina.net/bieber/blog/505458 Memcached的記憶體分配是以slabs為單位的,會根據初始chunk大小、增長因數、存儲數據的大小實際劃分出多個不同的slabs class,slab c ...
  • 大綱簡介 安裝前,先簡單介紹一下memcached。 memcached是一個免費、開源、高性能的分散式緩存。設計memcached的初衷是為了加快web應用程式,減少DB負載。 安裝要求:支持大多數linux和基於BSD的系統,官方沒有給出windows版本,但是網上有memcached for ...
  • 本篇將去探索twemproxy源碼的主幹流程,想來對於想要開始啃這份優秀源碼生肉的童鞋會有不小的幫助。這裡我們首先要找到 twemproxy正確的打開方式——twemproxy的文件結構,接著介紹twemproxy程式代碼框架,最後介紹twemproxy程式的主幹流程。主幹流程是本章節的重中之重。這 ...
  • 本文出處:http://www.cnblogs.com/wy123/p/6262800.html 在考慮重編譯T-SQL(或者存儲過程)的時候,有兩種方式可以實現強制重編譯(前提是忽略導致重編譯的其他因素的情況下,比如重建索引,更新統計信息等等), 一是基於WITH RECOMPILE的存儲過程級別 ...
  • 寫在前面 在QQ群,微信群,論壇中經常幫助使用SQL Server資料庫的朋友解決問題,但是有一些最常見最基本的問題,每天都有人問,回答多了也不想再解答了,索性把這些問題整理一下,再有人問到直接發鏈接。 一時想法而寫這篇文章,問題可能不全面,後續會一直更新。 基礎問題收集 資源下載 描述:XX版本數 ...
  • 一、HBase的特點是什麼 1.HBase一個分散式的基於列式存儲的資料庫,基於hadoop的hdfs存儲,zookeeper進行管理。 2.HBase適合存儲半結構化或非結構化數據,對於數據結構欄位不夠確定或者雜亂無章很難按一個概念去抽取的數據。 3.HBase為null的記錄不會被存儲. 4.基 ...
  • twemproxy背景 在業務量劇增的今天,單台高速緩存伺服器已經無法滿足業務的需求, 而相較於大容量SSD數據存儲方案,緩存具備速度和成本優勢,但也存在數據安全性的挑戰。為此搭建一個高速緩存伺服器集群來進行分散式存儲是十分必要的。 目前主流的高速緩存伺服器是redis和memchache。而twe ...
  • 本文將介紹閃回原理,給出筆者的實戰經驗,並對現存的閃回工具作比較。 DBA或開發人員,有時會誤刪或者誤更新數據,如果是線上環境並且影響較大,就需要能快速回滾。傳統恢復方法是利用備份重搭實例,再應用去除錯誤sql後的binlog來恢複數據。此法費時費力,甚至需要停機維護,並不適合快速回滾。也有團隊利用 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...