Ortam: Oracle Database, ASM (External, Normal ve High redundancy diskgroup’lar)
Bu yazıda v$database_block_corruption görünümünün nasıl dolduğunu, laboratuvarda corruption’ın nasıl oluşturulduğunu ve bulunan corruption’ın yedek var/yok, ARCHIVELOG açık/kapalı, ASM redundancy, corruption tipi gibi her durumda nasıl giderileceğini anlatıyorum. En sonda tüm durumlar tek tabloda özetleniyor.
1. Corruption türleri
Oracle, veri dosyası bloklarındaki bozulmaları (intra block corruption) ikiye ayırır:
| Tür | Belirti | Örnek |
|---|---|---|
| Fiziksel | ORA-01578, alert log’da bloğun dökümü | Bozuk header, fractured (başı ve sonu uyumsuz), checksum hatası, misplaced (başka bloğun içeriği), sıfırlanmış blok |
| Mantıksal | Checksum geçerli ama içerik bozuk: ORA-00600 [4512], [kdBlkCheckError], DBV-200 | Var olmayan transaction’a kilitli satır, kullanılan alan blok boyutuna uymuyor |
| NOLOGGING | ORA-01578 ile birlikte ORA-26040 | NOLOGGING yüklenen veri, recovery sonrası bozuk görünür |
| Tablo/index tutarsızlığı | ORA-08102, ORA-01499, ORA-00600 [kdsgrp1] | Index’te olan satır tabloda yok. Blok bozuk değildir, view’da görünmez |
db_block_checking açıksa ve blok diskte zaten mantıksal olarak bozuksa, bloğa yapılan sonraki güncelleme onu soft corrupt işaretler ve artık ORA-01578 alırsınız.
2. v$database_block_corruption nasıl dolar?
Görünümü sadece RMAN doldurur (BACKUP, BACKUP VALIDATE, VALIDATE). SQL’de ORA-01578 almak ya da DBV çalıştırmak görünümü doldurmaz. Her RMAN taramasında yenilenir, onarılan bloklar listeden düşer.
| CORRUPTION_TYPE | Anlamı |
|---|---|
| ALL ZERO | Blok tamamen sıfır |
| FRACTURED | Header ve tail uyuşmuyor |
| CHECKSUM | Checksum hatalı |
| CORRUPT | Başka bir fiziksel bozulma |
| LOGICAL | Fiziksel yapı sağlam, içerik tutarsız |
| NOLOGGING | NOLOGGING işlemden kalan bozuk blok |
12c ve sonrasında RMAN’in bulduğu NOLOGGING bloklar ayrıca v$nonlogged_block görünümünde listelenir.
3. Lab: corruption oluşturma
Sadece test ortamında yapın. Komutlar ASM diskine doğrudan yazar.
a) Test tablosu
CREATE TABLESPACE corr_ts DATAFILE '+DATA' SIZE 100M;
CREATE TABLE corr_test TABLESPACE corr_ts AS
SELECT level id, rpad('x',100,'x') txt FROM dual CONNECT BY level <= 100000;
CREATE INDEX corr_test_idx ON corr_test(id) TABLESPACE corr_ts;
b) Bozulacak bloğu seç
SELECT dbms_rowid.rowid_relative_fno(rowid) file_no,
dbms_rowid.rowid_block_number(rowid) block_no
FROM corr_test WHERE id = 500;
c) Bloğun ASM’deki yerini bul (ASM instance’ta)
ASM dosya numarasını datafile adından alın (+DATA/DB/DATAFILE/corr_ts.280.123456 için 280). 1 MB AU ve 8K blokta bir AU’da 128 blok vardır:
SELECT lxn_kffxp copy_no, disk_kffxp disk_no, au_kffxp au_no
FROM x$kffxp
WHERE group_kffxp = <diskgroup_no> AND number_kffxp = 280
AND xnum_kffxp = TRUNC(<block_no>/128);
copy_no 0 birincil kopyadır, 1 ve 2 mirror kopyalardır. Disk yolunu v$asm_disk.path içinden disk_no ile bulun.
d) Bloğa çöp yaz
printf 'CORRUPT' | dd of=<disk_path> bs=1 conv=notrunc \
seek=$(( AU_NO*1048576 + (BLOCK_NO%128)*8192 + 200 ))
ASM kullanmayan bir lab’da dosya doğrudan bozulabilir: seek=$(( BLOCK_NO*8192 + 200 )) ve of=<datafile>.
e) Cache’i temizle ve doğrula
ALTER SYSTEM FLUSH BUFFER_CACHE;
SELECT /*+ FULL(t) */ count(*) FROM corr_test t; -- ORA-01578
Normal redundancy’de sadece copy_no=0 kopyasını bozarsanız ASM scrub ile onarım senaryosunu test edersiniz. Tüm kopyaları (Normal’de 0 ve 1, High’da 0, 1 ve 2) bozarsanız Normal/High de External gibi davranır.
4. Corruption var mı? Tespit
RMAN
RMAN> VALIDATE CHECK LOGICAL DATABASE;
-- Hızlandırmak için: birden fazla channel, büyük dosyada bölümleme, tek dosya veya blok aralığı
RMAN> BACKUP VALIDATE CHECK LOGICAL DATAFILE 5 SECTION SIZE 1024M;
RMAN> VALIDATE CHECK LOGICAL DATAFILE 1 BLOCK 5 TO 20;
CHECK LOGICAL olmadan mantıksal bozulmalar yakalanmaz. Eksik dosya yüzünden hata alırsanız SKIP INACCESSIBLE ekleyin. İlerlemeyi v$session_longops ile izleyebilirsiniz. NOARCHIVELOG modda 10g ve öncesinde veritabanı MOUNT olmalıdır, 11g ve sonrasında bu kısıt yoktur.
Bozuk blok hangi segmente ait?
SELECT e.owner, e.segment_type, e.segment_name, e.partition_name, c.file#,
GREATEST(e.block_id, c.block#) bas_blok,
LEAST(e.block_id+e.blocks-1, c.block#+c.blocks-1) son_blok,
c.corruption_type aciklama
FROM dba_extents e, v$database_block_corruption c
WHERE e.file_id = c.file# AND e.block_id <= c.block#+c.blocks-1
AND e.block_id+e.blocks-1 >= c.block#
UNION ALL
SELECT s.owner, s.segment_type, s.segment_name, s.partition_name, c.file#,
s.header_block, s.header_block, c.corruption_type||' - SEGMENT HEADER'
FROM dba_segments s, v$database_block_corruption c
WHERE s.header_file = c.file# AND s.header_block BETWEEN c.block# AND c.block#+c.blocks-1
UNION ALL
SELECT NULL, NULL, NULL, NULL, c.file#,
GREATEST(f.block_id, c.block#), LEAST(f.block_id+f.blocks-1, c.block#+c.blocks-1), 'FREE BLOCK'
FROM dba_free_space f, v$database_block_corruption c
WHERE f.file_id = c.file# AND f.block_id <= c.block#+c.blocks-1
AND f.block_id+f.blocks-1 >= c.block#
ORDER BY 5, 6;
Sonuç üç türden biridir: bir segment (tablo, index, LOB…), bir segment header ya da free block. Sonraki adımlar buna göre değişir.
Diğer kontrol yöntemleri
| Yöntem | Not |
|---|---|
dbv file=... blocksize=8192 userid=... | Veritabanı açıkken çalışır. ASM dosyası için userid zorunludur. Bloğu tek başına inceler, segmente ait olmayan bloğu da bozuk gösterebilir. Tablo/index uyumsuzluğunu bulamaz |
ANALYZE TABLE t VALIDATE STRUCTURE CASCADE [ONLINE] | Tablo-index çapraz kontrolü yapan en kapsamlı komuttur. İlk hatada durur. Partition’lı tabloda INTO INVALID_ROWS gerekir |
Full table scan, CREATE TABLE AS SELECT veya export | İlk hatada durur, index’leri kontrol etmez |
5. Hangi sırayla deneyeceğiz?
- Active Data Guard standby’ı var mı? Bozuk blok standby’dan getirilir.
- Yedek ve ARCHIVELOG var mı? RMAN block media recovery (bölüm 6).
- Normal/High redundancy mı? Önce ASM scrub (bölüm 7).
- Yedek var ama NOARCHIVELOG mu? Yedeği yan ortama açıp satırları oradan alın (bölüm 8).
- Hiçbiri yoksa:
DBMS_ROWID.ROWID_CREATEile bozuk bölgeyi ayırıp tabloyu temizleyin (bölüm 9).
6. Yedek ve ARCHIVELOG varsa: block media recovery
Tablo çevrimiçi kalır, sadece bozuk blok kısa süre erişilemez olur.
RMAN> RECOVER CORRUPTION LIST; -- view'daki tüm bloklar
RMAN> RECOVER DATAFILE 7 BLOCK 1234 DATAFILE 7 BLOCK 1250; -- seçili bloklar
RMAN> VALIDATE DATAFILE 7 BLOCK 1234; -- doğrulama
Şartlar ve dikkat edilecekler:
- Veritabanı ARCHIVELOG modunda olmalı, Enterprise Edition gerekir.
- Blok full veya level 0 yedekten (ya da flashback log’dan) alınır, redo ile güncellenir. Level 1 incremental yedek block restore için kullanılmaz.
- Yedekteki blok da bozuksa işe yaramaz. Önce
RESTORE DATAFILE 7 VALIDATEveyaVALIDATE BACKUPSETile yedeği kontrol edin. - NOLOGGING bloklarda redo olmadığı için bu yöntem çalışmaz (bölüm 11).
- Active Data Guard varsa bozuk blok standby’dan otomatik onarılabilir.
7. ASM redundancy’ye göre
| Diskgroup | Kopya | Ne yapılır? |
|---|---|---|
| External | 1 | ASM düzeltemez. Yedek, standby (bölüm 6) ya da bölüm 9 gerekir |
| Normal | 2 | Bir kopya sağlam ise ASM scrub onarabilir |
| High | 3 | Aynı, daha fazla kopya |
ALTER DISKGROUP data SCRUB FILE '+DATA/DB/DATAFILE/corr_ts.280.123456' REPAIR POWER LOW;
Oracle 21c ve sonrasında RMAN ile her kopyayı ayrı doğrulayabilirsiniz, böylece hangi kopyanın bozuk olduğunu görürsünüz:
RMAN> VALIDATE DATAFILE 5 MIRROR ALL;
RMAN> VALIDATE DATAFILE 5 MIRROR 2;
Scrub sonrası VALIDATE ile tekrar kontrol edin. Hata sürüyorsa tüm kopyalar bozuktur. Veritabanının mantıksal olarak ürettiği bozuk bloklar tüm kopyalara yazılır, bu yüzden Normal/High burada koruma sağlamaz.
8. Yedek var ama ARCHIVELOG kapalıysa
Block media recovery redo gerektirdiği için çalışmaz. Seçenekler:
- Yedeği yan ortama aç. Yedekten ayrı bir sunucuda (
DUPLICATE DATABASEveya restore) veritabanını açın, kayıp satırları DB link ya da Data Pump ile geri alın. Satırlar yedek tarihindeki halleriyle gelir, sonradan yapılan değişiklikler olmaz. - Kaynak sistemden veya export’tan yeniden yükle. Tablo bir ETL ile besleniyorsa en temizi budur.
- Bunlar yoksa bölüm 9.
Uzun vadede ARCHIVELOG moda geçmek ve düzenli RMAN yedeği almak tek gerçek çözümdür.
9. Hiçbir yöntem yoksa: DBMS_ROWID.ROWID_CREATE ile bozuk bölgeyi ayırıp temizleme
Durum: yedek yok (veya NOARCHIVELOG), standby yok, External redundancy. Bozuk bloktaki satırlar kaybolur. Hedefimiz kalan veriyi korumak ve tabloyu yeniden sorunsuz DML alır hale getirmek.
Neden bloğa doğrudan DELETE, UPDATE veya NULL basamıyoruz? Satırlar bozuk bloğun içindedir. DML için Oracle bloğu okumak zorundadır ve ORA-01578 verir. (NULL yöntemi sadece LOB için mümkündür, bölüm 10.) Bunun yerine ROWID_CREATE ile bozuk bloğun ROWID aralığını üretip tabloyu bu aralığı hiç okumadan tarıyoruz.
Hazırlık
Bozuk blok bilgisi v$database_block_corruption içindeki file#, block# ve blocks sütunlarından, segment bilgisi bölüm 4’teki sorgudan gelir.
-- file# -> rowid içindeki göreli dosya numarası
SELECT file#, rfile# FROM v$datafile WHERE file# = 7;
-- segmentin data_object_id değeri (partition ise subobject_name = partition adı)
SELECT data_object_id FROM dba_objects
WHERE owner = 'SCOTT' AND object_name = 'CORR_TEST' AND subobject_name IS NULL;
DEFINE obj = 73412 -- data_object_id
DEFINE fno = 7 -- rfile#
DEFINE bs = 1234 -- bozuk aralığın ilk bloğu (block#)
DEFINE be = 1234 -- bozuk aralığın son bloğu (block# + blocks - 1)
Birden fazla bozuk aralık varsa her biri için aşağıdaki aralık koşullarını ekleyin.
Adım 1. Kaybolacak satırların anahtarlarını listele
Tabloya dokunmadan, index üzerinden bozuk bloktaki satırların anahtarlarını görebilirsiniz. Bu liste kayıp raporunuzdur.
SELECT /*+ INDEX_FFS(t corr_test_idx) */ t.id, t.ROWID
FROM scott.corr_test t
WHERE t.ROWID BETWEEN DBMS_ROWID.ROWID_CREATE(1, &obj, &fno, &bs, 0)
AND DBMS_ROWID.ROWID_CREATE(1, &obj, &fno, &be, 32767);
Planda INDEX FAST FULL SCAN olmalı, TABLE ACCESS olmamalıdır. Aksi halde sorgu ORA-01578 verir. Tabloda hiç index yoksa kayıp satırları listeleyemezsiniz.
Adım 2. Sağlam satırları kurtar
Bozuk aralığın öncesini ve sonrasını ayrı ayrı okuyup birleştiriyoruz. NOT BETWEEN veya <> kullanmayın, çünkü bu koşul her satırı değerlendirmek için bozuk bloğu da okur ve ORA-01578 verir.
CREATE TABLE scott.corr_test_kurtarilan TABLESPACE users NOLOGGING AS
SELECT /*+ FULL(t) */ * FROM scott.corr_test t
WHERE t.ROWID < DBMS_ROWID.ROWID_CREATE(1, &obj, &fno, &bs, 0)
UNION ALL
SELECT /*+ FULL(t) */ * FROM scott.corr_test t
WHERE t.ROWID > DBMS_ROWID.ROWID_CREATE(1, &obj, &fno, &be, 32767);
Salvage tablosunu bozuk dosyadan farklı bir tablespace’e koyun. Partition’lı tabloda her partition’ın kendi data_object_id değeri vardır, işlemi sadece bozuk partition için FROM scott.corr_test PARTITION (p_ocak) t ile yapın.
Adım 3. Doğrula ve güvene al
SELECT count(*) FROM scott.corr_test_kurtarilan;
Sonraki adım TRUNCATE olduğu için salvage tablosu artık tek kopyadır. Önce expdp ile dışarı alın.
Adım 4. Bozuk bloğu segmentten çıkar ve veriyi geri yükle
TRUNCATE extent’leri free space’e iade eder ve bozuk blok tablodan çıkmış olur. Tablo nesnesi, index’leri, constraint’leri, trigger’ları, grant’leri ve istatistikleri yerinde kalır, yeniden oluşturmanız gerekmez.
-- Bu tabloya referans veren FK'ler varsa önce disable edin, trigger'ları da kapatın
ALTER TABLE scott.corr_test DISABLE ALL TRIGGERS;
TRUNCATE TABLE scott.corr_test;
INSERT /*+ APPEND */ INTO scott.corr_test SELECT * FROM scott.corr_test_kurtarilan;
COMMIT;
ALTER TABLE scott.corr_test ENABLE ALL TRIGGERS;
DROP TABLE scott.corr_test_kurtarilan PURGE;
Partition’lı tabloda sadece ALTER TABLE ... TRUNCATE PARTITION p_ocak yeterlidir, diğer partition’lara dokunulmaz. Segment header bozuksa TRUNCATE de çalışmaz (bölüm 10).
Adım 5. Free space’e düşen bozuk bloğu formatla
Truncate sonrası bozuk blok free space’tedir. Yeniden kullanılıp formatlanana kadar RMAN ve DBV onu bozuk göstermeye devam eder, yedek de ORA-19566 ile hata verir. Hemen temizlemek için bloğu boş bir tabloya zorla yazdırıyoruz:
-- Bozuk dosyanın tablespace'inde, SYS olmayan kullanıcıyla
CREATE TABLE scott.s (n NUMBER, c VARCHAR2(4000)) NOLOGGING PCTFREE 99 TABLESPACE corr_ts;
-- Bozuk blok kullanılınca hata verecek trigger (SYS ile)
CREATE OR REPLACE TRIGGER corrupt_trigger AFTER INSERT ON scott.s FOR EACH ROW
BEGIN
IF DBMS_ROWID.ROWID_BLOCK_NUMBER(:NEW.ROWID) = &bs
AND DBMS_ROWID.ROWID_RELATIVE_FNO(:NEW.ROWID) = &fno THEN
RAISE_APPLICATION_ERROR(-20000, 'Bozuk blok formatlandi');
END IF;
END;
/
-- Free extent boyutunu öğren, aynı boyutta extent al (blok tabloya girene kadar tekrarla)
SELECT bytes FROM dba_free_space
WHERE file_id = &fno AND &bs BETWEEN block_id AND block_id + blocks - 1;
ALTER TABLE scott.s ALLOCATE EXTENT (DATAFILE '+DATA/DB/DATAFILE/corr_ts.280.123456' SIZE 64K);
SELECT segment_name FROM dba_extents
WHERE file_id = &fno AND &bs BETWEEN block_id AND block_id + blocks - 1;
-- Satır ekle, ORA-20000 gelince blok formatlanmış demektir
BEGIN FOR i IN 1..100000000 LOOP INSERT INTO scott.s VALUES (i, 'x'); END LOOP; END;
/
Sonra temizlik:
ALTER SYSTEM SWITCH LOGFILE; -- iki kez
ALTER SYSTEM CHECKPOINT;
RMAN> VALIDATE DATAFILE 7 BLOCK 1234;
DROP TABLE scott.s PURGE;
DROP TRIGGER corrupt_trigger;
Notlar: ASSM tablespace’te extent alma adımını birkaç kez tekrarlamanız gerekebilir. Datafile AUTOEXTEND kapalı olmalıdır. Flashback açıkken free blokların formatlanmayabildiği bilinen bir bug vardır (Bug 7381632). Blok bir dosya bitmap bloğuysa formatlanamaz.
Alternatif: DBMS_REPAIR ile atlatma (veri taşımadan, geçici çözüm)
Tabloyu hemen DML’e açmak istiyorsanız bozuk bloğu işaretleyip atlatabilirsiniz. Blok diskte kalır ve RMAN raporlamaya devam eder.
BEGIN
DBMS_REPAIR.ADMIN_TABLES('REPAIR_TABLE', DBMS_REPAIR.REPAIR_TABLE, DBMS_REPAIR.CREATE_ACTION, 'USERS');
END;
/
DECLARE c PLS_INTEGER;
BEGIN
DBMS_REPAIR.CHECK_OBJECT('SCOTT', 'CORR_TEST', repair_table_name => 'REPAIR_TABLE', corrupt_count => c);
DBMS_REPAIR.FIX_CORRUPT_BLOCKS('SCOTT', 'CORR_TEST', DBMS_REPAIR.TABLE_OBJECT, repair_table_name => 'REPAIR_TABLE', fix_count => c);
DBMS_REPAIR.SKIP_CORRUPT_BLOCKS('SCOTT', 'CORR_TEST', DBMS_REPAIR.TABLE_OBJECT, DBMS_REPAIR.SKIP_FLAG);
END;
/
Sonra index’leri drop/create ile yeniden oluşturun. RMAN yedeği için SET MAXCORRUPT FOR DATAFILE 7 TO 1; gerekir. Kalıcı çözüm yine bu bölümdeki ROWID_CREATE + TRUNCATE yöntemidir.
10. Segment tipine göre özel durumlar
Index. Veri kaybı yoktur, index tablodan yeniden üretilir. DROP INDEX + CREATE INDEX yapın. REBUILD eski index’i okuyabilir ve bozuk blokta takılabilir.
LOB. Bozuk LOB içeriği kaybolur, ama satırın kendisi sağlamdır. Burada gerçekten NULL basabilirsiniz:
DECLARE
v_buf RAW(32767); v_len NUMBER; v_pos NUMBER; v_amt NUMBER;
BEGIN
FOR r IN (SELECT ROWID rid, doc FROM scott.t_lob) LOOP
BEGIN
v_len := DBMS_LOB.GETLENGTH(r.doc); v_pos := 1;
WHILE v_pos <= v_len LOOP
v_amt := 32767;
DBMS_LOB.READ(r.doc, v_amt, v_pos, v_buf);
v_pos := v_pos + v_amt;
END LOOP;
EXCEPTION WHEN OTHERS THEN
IF SQLCODE IN (-1578, -26040, -22922) THEN
UPDATE scott.t_lob SET doc = EMPTY_BLOB() WHERE ROWID = r.rid; -- veya NULL
COMMIT;
ELSE RAISE; END IF;
END;
END LOOP;
END;
/
CLOB için EMPTY_CLOB() ve VARCHAR2 buffer kullanın. Eski bozuk chunk’ları temizlemek için ALTER TABLE ... MOVE LOB(doc) STORE AS (TABLESPACE yeni_ts) yapılabilir. LOB segmentinde ORA-01578 ile ORA-26040 birlikte geliyorsa Oracle’ın KB151992 scriptine bakın.
IOT. Index tablonun kendisi olduğu için index drop/create yöntemi uygulanamaz. DBMS_REPAIR ile atlatma ve Oracle KB146316 scripti kullanılır.
Segment header. Header bozuksa ROWID_CREATE, TRUNCATE ve DBMS_REPAIR yöntemleri çalışmaz. Yedekten restore veya Oracle Support gerekir.
Free block. Veri kaybı yoktur. Bölüm 9, adım 5’teki formatlama ile temizlenir.
Temporary segment. Temp tablespace’i yeniden oluşturun, içinde kalıcı veri yoktur.
SYSTEM, UNDO, control file, redo. SYSTEM ve veri sözlüğü için yedek/restore veya Oracle Support gerekir (hcheck.sql ile sözlük tutarlılığı kontrol edilir). UNDO için yeni undo tablespace oluşturup geçiş yapılır. Control file ve redo için multiplex kopyalar kullanılır.
Table/index tutarsızlığı (ORA-08102, ORA-01499). Tablo doğru kabul edilir, ilgili index drop/create ile yeniden oluşturulur. ANALYZE ... VALIDATE STRUCTURE CASCADE ile doğrulayın.
11. NOLOGGING corruption
Bloklar redo üretmeden yüklendiği için block media recovery işe yaramaz. Tablo veya index’i yeniden oluşturun, veriyi kaynaktan tekrar yükleyin. Aynı sorunu yaşamamak için ALTER DATABASE FORCE LOGGING; kullanın.
12. Onarım sonrası doğrulama ve önleme
RMAN> VALIDATE CHECK LOGICAL DATABASE;
SELECT * FROM v$database_block_corruption; -- boş olmalı
- Önce kök nedeni arayın: alert log, storage ve OS/donanım logları. Aynı yerde tekrar eden bozulma disk veya controller sorunudur.
DB_BLOCK_CHECKSUMaçık olsun (TYPICAL veya TRUE), bozulmaları I/O sırasında yakalar.DB_BLOCK_CHECKING‘i açmadan önce mevcut mantıksal bozulmaları onarın, aksi halde bozuk bloklar bir sonraki güncellemede soft corrupt olur.- Düzenli
VALIDATE CHECK LOGICAL DATABASEve yedeğin kendisini doğrulayanRESTORE VALIDATEçalıştırın.
13. Özet tablo
| Durum | Yöntem | Veri kaybı |
|---|---|---|
| Yedek + ARCHIVELOG (her redundancy) | RECOVER CORRUPTION LIST / RECOVER ... BLOCK | Yok |
| Active Data Guard standby var | Bloğu standby’dan otomatik/RMAN ile onar | Yok |
| Flashback log var | Block recovery flashback log’dan blok alabilir | Yok |
| Normal/High, tek kopya bozuk | ALTER DISKGROUP ... SCRUB ... REPAIR | Yok |
| Normal/High, tüm kopyalar bozuk | External gibi: yedek, standby veya ROWID_CREATE | Duruma göre |
| External, yedek yok | Yedek/standby gerekir, yoksa ROWID_CREATE | Bozuk blok satırları |
| Yedek var, NOARCHIVELOG | Yedeği yan ortama aç, satırları geri al | Yedek tarihinden sonraki değişiklikler |
| Hiçbiri yok, tablo | ROWID_CREATE ile ayır, CTAS, TRUNCATE, geri yükle, bloğu formatla | Sadece bozuk bloktaki satırlar |
| Hiçbiri yok, hızlı çözüm | DBMS_REPAIR FIX + SKIP, sonra index’leri yeniden oluştur | Sadece bozuk bloktaki satırlar |
| Index | DROP + CREATE INDEX | Yok |
| LOB | Bozuk LOB’u EMPTY/NULL yap (PL/SQL), gerekirse LOB MOVE | Sadece o LOB değerleri |
| IOT | DBMS_REPAIR atlatma, KB146316 scripti | Bozuk bloktaki satırlar |
| Mantıksal corruption (checksum geçerli) | Yedek varsa block recovery, yoksa tablo gibi (ROWID_CREATE) | Duruma göre |
| NOLOGGING | Veriyi/index’i yeniden oluştur veya yükle | Yeniden yüklenir |
| Table/index tutarsızlığı | Index’i drop/create | Yok |
| Free block | Dummy tablo + trigger ile formatla | Yok |
| Segment header, SYSTEM, dictionary | Restore veya Oracle Support | Duruma göre |
| UNDO | Yeni undo tablespace’e geç | Yok |
| Temp | Temp tablespace’i yeniden oluştur | Yok |
| Control file, redo | Multiplex kopyadan geri al | Yok |
Bu yazıdaki yöntemlerin bir kısmı (özellikle ASM üzerinde dd ile corruption oluşturma ve bozuk blok formatlama) sadece test ortamında denenmelidir. Üretimde işlem yapmadan önce Oracle Support ile görüşmeniz önerilir.






Bir yanıt yazın