Saya baru-baru ini mengerjakan beberapa kerusakan blok data dan saya perlu membuang beberapa blok data untuk memverifikasi isinya. Saya harus menepis kertas yang saya tulis sejak lama yang menunjukkan bagaimana melakukan ini. Berikut ini adalah sebagian dari kertas itu:
Untuk membuang blok milik tabel, Anda harus mengetahui nomor file dan nomor blok blok itu. Jika Anda sudah mengetahui nomor dan blok file, maka Anda sudah siap. Jika Anda tidak mengetahui nomor dan blok file, Anda dapat menanyakan DBA_EXTENTS untuk informasi tersebut. Sekarang kita tahu file dan blok mana yang menyimpan tabel kita, mari kita buang contoh blok tabel. Ini dilakukan sebagai berikut:
ORA9I SQL> alter system dump datafile 3 block 10;
System altered.
Anda dapat membuang berbagai blok dengan perintah berikut:
ORA9I SQL> alter system dump datafile 3 block min 10 block max 12;
System altered.
Sekarang mari kita lihat isi dari dumping one block.
Start dump data blocks 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 type: 0x06=trans data
Block header dump: 0x00c0000a
Object id on Block? 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
Ini adalah awal dari dump blok data. Baris pertama memberitahu kita bahwa kita sedang membuang file#3, dimulai dari blok#10 (minblk), dan diakhiri dengan blok#10 (maxblk). Seandainya kami membuang lebih dari satu blok data, nilai-nilai ini akan mewakili suatu rentang. Alamat blok data relatif (rdba) adalah 0x00c0000a. Untuk informasi lebih lanjut tentang rdba, lihat bagian selanjutnya dalam makalah ini. Di akhir baris ini, kita dapat melihat dalam tanda kurung bahwa rdba sesuai dengan file# 3, blok# 10 (3/10).
Baris ketiga menggambarkan SCN dari blok data. Dalam kasus kami, SCN adalah 0x0000.00046911. Ekor dari blok data terdiri dari dua byte terakhir dari SCN (6911) yang ditambahkan dengan tipe (06) dan urutan (02). Jika dekomposisi ekor tidak cocok dengan ketiga nilai ini, maka sistem mengetahui bahwa blok tersebut tidak konsisten dan perlu dipulihkan. Sementara nilai ekor ini muncul di awal blok dump, secara fisik disimpan di akhir blok data.
Jenis blok muncul di baris keempat. Beberapa jenis yang valid sesuai dengan tabel berikut:
Type Meaning
0x02 undo block
0x06 table or index data block
0x0e undo segment header
0x10 data segment header block
0x17 bitmapped data segment header
"Id objek di Blok?" baris memberitahu kita apakah objek ini ada di SYS.OBJ$. Sejak Oracle 6, ini harus selalu "Y". Jika Anda melihat baris berikutnya, nilai seg/obj memberitahu kita id objek segmen (dalam hex). Dalam contoh kita, ini adalah 0x6d9c. Hex '6D9C' adalah '28060' dalam desimal. Kami dapat memverifikasi bahwa ini adalah tabel kami dengan kueri berikut:
ORA9I SQL> select owner,object_name from dba_objects
2 where object_id=28060;
OWNER OBJECT_NAME
---------- ------------------------------
PEASLAND EMP
Seperti yang kami harapkan, ini meja kami.
Nilai csc adalah nomor Perubahan Sistem Pembersihan. Nilai ini memberitahu kita kapan pembersihan blok dilakukan pada blok ini. Semoga cocok dengan SCN blok data. Nilai itc adalah Hitungan Daftar Transaksi yang Diinginkan. Dalam kasus kami, ada dua transaksi yang tertarik pada blok ini. Transaksi yang menarik itu muncul di akhir contoh kita. Kita bisa melihat id transaksi (Xid) dari kedua transaksi tersebut. ID transaksi tersebut sesuai dengan segmen rollback yang digunakan untuk memproses transaksi kami.
Bendera (flg) adalah "-" atau "O", digunakan untuk menunjukkan apakah blok ini ada dalam daftar bebas. Jika blok ada dalam daftar bebas, benderanya akan menjadi "0". Jika tidak ada dalam daftar bebas, maka benderanya akan menjadi "-". Blok kami yang dimaksud ada di daftar gratis.
Yah, itu cukup banyak informasi dan kami belum benar-benar melihat terlalu banyak dump. Mari kita lihat bagian selanjutnya dari data block dump.
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
Nilai tsiz menunjukkan kepada kita jumlah ruang yang tersedia di blok untuk data. Di sini, kita mendapatkan '1fa0' yang diterjemahkan menjadi 8.096 byte ruang yang bisa digunakan. Sisa dari blok 8.192 byte kami digunakan untuk overhead seperti header blok.
Nilai ntab menunjukkan kepada kita berapa banyak tabel yang disimpan di blok ini. Kecuali blok ini milik sebuah cluster, nilai ini akan menjadi '1'. Nilai nrow memberitahu kita berapa banyak baris data yang disimpan di blok ini. Blok data kami memiliki 14 baris data.
Mulai dari alamat '0xe', kami mendapatkan direktori untuk setiap baris. Kita dapat melihat bahwa baris pertama (index entry zero) dimulai dari alamat offset ke blok '0x1c30'. Setiap baris blok mengikuti dari sini. Dengan cara ini, baris dapat ditemukan dengan sangat cepat. Ingat bahwa ROWID pada dasarnya adalah penunjuk ke baris unik. Di Oracle 8+, ROWID dalam bentuk O.F.B.R (atau objectno,relativefno,blockno,rowno). Jadi ketika sistem dengan cepat menunjuk ke blok tertentu dalam file tertentu, nomor baris menunjuk ke slot di direktori ini. Direktori kemudian menunjuk ke lokasi tertentu di blok. Ini adalah awal dari baris itu.
Sekarang setelah kita memiliki peta jalan ke blok data kita, mari kita lihat sisa file trace untuk melihat baris data yang sebenarnya di blok.
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
Data baris sebenarnya dimulai dengan frasa “block_row_dump:”. Kemudian deretan data diberikan. Saya hanya menampilkan satu baris data di sini, karena sisanya serupa. Kita dapat melihat bahwa baris ini milik tabel '0' (tab) dari cluster kita. Karena tidak ada cluster dalam contoh kita, kita tidak memiliki lebih dari satu tabel sehingga nilai ini akan menjadi nol. Kita juga dapat melihat bahwa ini adalah baris '0' dan alamat dari baris tersebut diberikan. Alamat ini harus sesuai dengan peta jalan kami yang disebutkan di atas.
Nilai 'tl' memberi kita jumlah total byte untuk baris ini, termasuk overhead apa pun. Kita dapat melihat bahwa baris ini menempati 39 byte. Nilai 'cc' memberi kita jumlah kolom. Kami memiliki delapan kolom di baris ini. Ini dapat dengan mudah diverifikasi dengan melakukan DESCRIBE pada tabel dan menghitung kolom, atau dengan menanyakan USER_TAB_COLUMNS.
Nilai 'fb' memberi kita tanda tentang baris. 'H' berarti kita memiliki kepala baris. 'F' berarti kita memiliki bagian pertama dari baris. 'L' berarti kita juga memiliki bagian terakhir dari baris. Karena ini adalah bagian pertama dan terakhir dari baris, baris tidak dirantai. Karena ini juga merupakan kepala baris, baris tersebut belum dipindahkan.
Sisa informasi untuk baris adalah data untuk setiap kolom. Misalnya, di kolom 1, kami memiliki kode karakter ASCII berikut, "53 4d 49 54 48". Sekilas melihat grafik konversi ASCII akan memberi tahu kita bahwa karakter ini adalah "SMITH". Jika Anda familiar dengan contoh tabel EMP, Anda akan tahu bahwa SMITH adalah salah satu karyawan kami. Perhatikan bahwa kolom 6 adalah NULL. Kolom 4 adalah kolom HIREDATE. Ini adalah tipe data DATE. Dari blok ini, Anda dapat dengan mudah memverifikasi bahwa tipe data DATE memerlukan penyimpanan tujuh byte. Kolom 0 berisi angka. Tiga byte di sini adalah representasi dari angka itu.