Email: service@parnassusdata.com 7 x 24 online support!

    You are here

    • You are here:
    • Home > Blogs > PDSERVICE's blog > dbms_rowidパッケージを使用して、破損しているブロックのデータを読み飛ばす方法(R8.0以降)

dbms_rowidパッケージを使用して、破損しているブロックのデータを読み飛ばす方法(R8.0以降)

dbms_rowidパッケージを使用して、破損しているブロックのデータを読み飛ばす方法(R8.0以降)

ORACLEデータベース によくあるエラ の解決策

プロのOracle Databaseの復旧サービスを提供
携帯番号: +86 13764045638 メール:service@parnassusdata.com

 
[概要]
dbms_rowidパッケージを使用して、破損ブロックのデータを読み飛ばす方法


[対象リリース]
Oracle8 Database Release(8.0) 以降のバージョン


[対象プラットフォーム]
すべてのプラットフォーム


[詳細]
破損ブロックを含む表において、破損ブロックのデータをrowid指定で
読み飛ばし、正常なブロックのデータのみを取り出す手順を、以下に
記述します。

SQL> select count(*) from test;
select count(*) from test
                     *
1行でエラーが発生しました。
ORA-01578: ファイル番号 5,ブロック番号
73156でOracleデータ・ブロックに障害が発生しました。
ORA-01110: データ・ファイル 5 :
/home2/ora8174/app/oracle/oradata/ora8174/users01.dbf


例: file=5 blocknum=73156 をSKIPしたい場合

  1. 破損しているオブジェクトを特定して下さい。
     ** file_idは、ORA-1110と共に出力されている番号(絶対ファイル番号)を
        使用してください。

    例)
     SQL> SELECT tablespace_name, relative_fno,
          segment_type, owner, segment_name, partition_name
          FROM dba_extents
          WHERE file_id = 5
          AND 73156 between block_id and block_id + blocks -1 ;

	  TABLESPACE_NAME                RELATIVE_FNO SEGMENT_TYPE
	  ------------------------------ ------------ ------------------
	  OWNER
	  ------------------------------
	  SEGMENT_NAME
	  ---------------------------------------------------------------
	  PARTITION_NAME
	  ------------------------------
	  USERS                                     5 TABLE
	  SCOTT
          TEST

  2. data_object_idを特定して下さい。
    
    例)
     SQL> SELECT data_object_id
	  FROM dba_objects
	  WHERE object_name = 'TEST'
	  AND owner = 'SCOTT';

   ** 1の結果が、パーティションに属するブロックであった場合には、
      以下のSELECT文をご使用下さい。

    例) SCOTT.TEST表のパーティション SALES_Q3のブロックであった場合

     SQL> SELECT data_object_id
          FROM dba_objects
          WHERE object_name = 'TEST'
          AND owner = 'SCOTT'
          AND subobject_name = 'SALES_Q3';
	
          DATA_OBJECT_ID
          --------------
                  173599

   3. 破損ブロック内の先頭のrowidを、以下のプロシージャで確認します。

      dbms_rowid.rowid_create(1, data_object_id,relative_fno,block_id,0)

    例)
      SQL> select dbms_rowid.rowid_create(1,173599,5,73156,0) from dual;

	   DBMS_ROWID.ROWID_C
           ------------------
           AAAqYfAAFAAAR3EAAA

    ** 第3引数 relative_fnoには、手順1で確認した相対ファイル番号(relative_fno)
        を使用してください。

   4. 破損ブロックの次のブロックに格納された 先頭のrowidを、以下の
      プロシージャで 確認します。
      dbms_rowid.rowid_create(1, data_object_id, relative_fno, block_id + 1, 0)

    例)
      SQL> select dbms_rowid.rowid_create(1,173599,5,73157,0) from dual;
     
           DBMS_ROWID.ROWID_C
           ------------------
           AAAqYfAAFAAAR3FAAA

    ** 第3引数 relative_fnoには、手順1で確認した相対ファイル番号(relative_fno)
        を使用してください。

   5. 破損ブロックの先頭rowidよりも 前のrowidを保持するデータを
      一時的な表に格納します。

    例)
      SQL> CREATE TABLE TEST_TEMP AS
	   SELECT /*+ ROWID(A) */ * FROM SCOTT.TEST A
	   WHERE rowid < 'AAAqYfAAFAAAR3EAAA';

     ** 1の結果が、パーティションに属するブロックで、かつ 問題の
        パーティションのデータから、破損ブロック以外のデータを
        抽出されたい場合には 以下のSQL文を実行して下さい。

      SQL> CREATE TABLE TEST_TEMP AS
           SELECT /*+ ROWID(A) */ * 
           FROM SCOTT.TEST PARTITION (SALES_Q3) A
           WHERE rowid < 'AAAqYfAAFAAAR3EAAA';

   6. 破損ブロックの最後のrowidよりも 後のrowid(破損ブロックの次の
      ブロックの先頭rowid)を保持するデータを、一時的な表に格納します。

    例)
      SQL> INSERT INTO TEST_TEMP 
           SELECT /*+ ROWID(A) */ * FROM SCOTT.TEST A
           WHERE rowid >= 'AAAqYfAAFAAAR3FAAA';

      SQL> commit;
 
     ** 1の結果が、パーティションに属するブロックで、かつ 問題の
        パーティションのデータのみから、破損ブロック以外のデータを
        抽出されたい場合には 以下のSQL文を実行して下さい。

      SQL> INSERT INTO TEST_TEMP 
           SELECT /*+ ROWID(A) */ * 
           FROM SCOTT.TEST PARTITION (SALES_Q3) A
           WHERE rowid >= 'AAAqYfAAFAAAR3FAAA';