最近、いくつかのデータブロックの破損に取り組んでおり、その内容を確認するためにいくつかのデータブロックをダンプする必要がありました。ずっと前に書いた、これを行う方法を示した紙をはがす必要がありました。以下はその論文の一部です:
テーブルに属するブロックをダンプするには、そのブロックのファイル番号とブロック番号を知っている必要があります。ファイル番号とブロックをすでに知っている場合は、すべて設定されています。ファイル番号とブロックがわからない場合は、DBA_EXTENTSにその情報を照会できます。どのファイルとブロックがテーブルを保持しているかがわかったので、テーブルのサンプルブロックをダンプしましょう。これは次のように行われます:
ORA9ISQL>システムダンプデータファイル3ブロック10を変更します;
コード>
システムが変更されました。
次のコマンドを使用して、ブロックの範囲をダンプできます。
ORA9I SQL> alter system dump datafile 3 block min 10 block max 12;
コード>
システムが変更されました。
1つのブロックをダンプする内容を見てみましょう。
ダンプデータブロックの開始tsn:3 file#:3 minblk 10 maxblk 10
buffer tsn:3 rdba:0x00c0000a(3/10)
scn:0x0000.00046911 seq:0x02 flg:0x04 tail :0x69110602
frmt:0x02 chkval:0x579dタイプ:0x06 =transデータ
ブロックヘッダーダンプ:0x00c0000a
ブロック上のオブジェクトID? Y
seg / obj:0x6d9c csc:0x00.46911 itc:2 flg:O typ:1-DATA
fsl:0 fnx:0x0 ver:0x01
コード>
Itl Xid Uba Flag Lck Scn / Fsc
0x01 xid:0x0005.02f.0000010c uba:0x00806f10.00ca.28 C --- 0 scn 0x0000.00046900
0x02 xid:0x0003.01c。 00000101 uba:0x00800033.0099.04 C --- 0 scn 0x0000.00046906
これはデータブロックダンプの始まりです。最初の行は、ファイル#3をダンプし、ブロック#10(minblk)で開始し、ブロック#10(maxblk)で終了することを示しています。複数のデータブロックをダンプした場合、これらの値は範囲を表します。相対データブロックアドレス(rdba)は0x00c0000aです。 rdbaの詳細については、このペーパーの後のセクションを参照してください。この行の最後で、括弧内にrdbaがファイル#3、ブロック#10(3/10)に対応していることがわかります。
3行目は、データブロックのSCNを示しています。この場合、SCNは0x0000.00046911です。データブロックのテールは、SCN(6911)の最後の2バイトに、タイプ(06)とシーケンス(02)が追加されたもので構成されています。テールの分解がこれらの3つの値と一致しない場合、システムはブロックに一貫性がなく、回復する必要があることを認識します。このテール値はブロックダンプの最初に表示されますが、データブロックの最後に物理的に保存されます。
ブロックタイプは4行目に表示されます。有効なタイプのいくつかは、次の表に対応しています。
タイプ意味
0x02元に戻すブロック
0x06テーブルまたはインデックスデータブロック
0x0e元に戻すセグメントヘッダー
0x10データセグメントヘッダーブロック
0x17ビットマップデータセグメントヘッダーコード>
「ブロック上のオブジェクトID?」行は、このオブジェクトがSYS.OBJ$にあるかどうかを示します。 Oracle 6以降、これは常に「Y」である必要があります。次の行を見ると、seg / obj値はセグメントのオブジェクトID(16進数)を示しています。この例では、これは0x6d9cです。 16進数の「6D9C」は10進数で「28060」です。次のクエリで、これがテーブルであることを確認できます。
ORA9I SQL> select owner、object_name from dba_objects
2 where object_id =28060;
コード>
OWNER OBJECT_NAME
---------- ------------------------------
PEASLAND EMP
期待通り、これが私たちのテーブルです。
csc値は、クリーンアウトシステム変更番号です。この値は、このブロックでブロックのクリーンアウトがいつ実行されたかを示します。うまくいけば、それはデータブロックのSCNと一致します。 itc値は、関心のあるトランザクションリストの数です。この場合、このブロックに関係する2つのトランザクションがあります。これらの関心のあるトランザクションは、例の最後に表示されます。これら2つのトランザクションのトランザクションID(Xid)を確認できます。これらのトランザクションIDは、トランザクションの処理に使用されるロールバックセグメントに対応しています。
フラグ(flg)は「-」または「O」のいずれかであり、このブロックがフリーリストにあるかどうかを示すために使用されます。ブロックがフリーリストにある場合、フラグは「0」になります。フリーリストにない場合、フラグは「-」になります。問題のブロックはフリーリストにあります。
ええと、それはかなり多くの情報であり、私たちは実際にはあまり多くのダンプを見ていません。データブロックダンプの次のセクションを見てみましょう。
data_block_dump
===============
tsiz:0x1fa0
hsiz:0x2e
pbl:0x024d015c
bdba: 0x00c0000a
flag =-------------
ntab =1
nrow =14
frre =9
fsbo =0x2e
fseo =0x1b18
avsp =0x1d8a
tosp =0x1d8a
0xe:pti [0] nrow =14 offs =0
0x12:pri [0] offs =0x1c30
0x14:pri [1] offs =0x1f4f
0x16:pri [2] offs =0x1f24
0x18:pri [3] offs =0x1efb
0x1a:pri [4] offs =0x1ece
0x1c:pri [5] offs =0x1ea5
0x1e:pri [6] offs =0x1e7c
0x20:pri [7] offs =0x1e54
0x22:pri [8] offs =0x1e2e
0x24:pri [9] sfll =13
0x26:pri [10] offs =0x1ca4
0x28:pri [11] offs =0x1cf1
0x2a:pri [12 ] offs =0x1b18
0x2c:pri [13] sfll =-1
tsiz値は、データ用にブロック内で使用可能なスペースの量を示します。ここでは、「1fa0」を取得します。これは、8,096バイトの使用可能な部屋に相当します。残りの8,192バイトのブロックは、ブロックヘッダーなどのオーバーヘッドに使用されます。
ntab値は、このブロックに格納されているテーブルの数を示します。このブロックがクラスターに属していない限り、この値は「1」になります。 nrow値は、このブロックに格納されているデータの行数を示します。データブロックには14行のデータがあります。
アドレス「0xe」から開始して、各行へのディレクトリを取得します。最初の行(インデックスエントリゼロ)は、ブロック「0x1c30」へのオフセットアドレスから始まることがわかります。各ブロックの行はここから続きます。このようにして、行をすばやく見つけることができます。 ROWIDは基本的に、一意の行へのポインタであることに注意してください。 Oracle 8以降では、ROWIDの形式はO.F.B.R(またはobjectno、relativefno、blockno、rowno)です。したがって、システムが特定のファイル内の特定のブロックをすばやく指す場合、行番号はこのディレクトリ内のスロットを指します。次に、ディレクトリはブロック内の特定の場所を指します。これがその行の始まりです。
データブロックへのロードマップができたので、トレースファイルの残りの部分を見て、ブロック内の実際のデータ行を確認しましょう。
block_row_dump:
>
tab 0、row 0、@ 0x1c30
tl:39 fb:--H-FL-- lb:0x0 cc:8
col 0:[3] c2 4a 46
col 1:[5] 53 4d 49 54 48
col 2:[5] 43 4c 45 52 4b
col 3:[3] c2 50 03
col 4:[7] 77 b4 0c 11 01 01 01
col 5:[3] c2 09 19
col 6:* NULL *
col 7:[2] c1 15
実際の行データは、「block_row_dump:」というフレーズで始まります。次に、データの行が与えられます。残りは同様であるため、ここでは1行のデータのみを示しました。この行は、クラスターのテーブル「0」(タブ)に属していることがわかります。この例にはクラスターがないため、複数のテーブルがないため、この値はゼロになります。これが行「0」であり、その行のアドレスが指定されていることもわかります。このアドレスは、上記のロードマップに対応している必要があります。
「tl」値は、オーバーヘッドを含む、この行の合計バイト数を示します。この行が39バイトを占めていることがわかります。 「cc」値は列数を示します。この行には8つの列があります。これは、テーブルでDESCRIBEを実行して列をカウントするか、USER_TAB_COLUMNSを照会することで簡単に確認できます。
「fb」値は、行に関するフラグを提供します。 「H」は、列の先頭があることを意味します。 「F」は、行の最初の部分があることを意味します。 「L」は、行の最後の部分もあることを意味します。これは行の最初と最後の部分であるため、行は連鎖されません。これは行の先頭でもあるため、行は移行されていません。
行の残りの情報は、各列のデータです。たとえば、列1には、次のASCII文字コード「534d495448」があります。 ASCII変換チャートをざっと見ると、これらの文字が「SMITH」であることがわかります。サンプルのEMPテーブルに精通している場合は、SMITHが当社の従業員の1人であることをご存知でしょう。列6がNULLであることに注意してください。列4はHIREDATE列です。これはDATEデータ型です。このブロックから、DATEデータ型に7バイトのストレージが必要であることを簡単に確認できます。列0には数値が含まれています。ここでの3バイトは、その数を表しています。