30 Aralık 2010 Perşembe

10gR1, 10gR2 ve 11g database’ lerinde Recyclebin Özelliğini Disable Etmek


10gR1 de recyclebin özelliği default olarak enable olarak gelir. 10gR1 içinde bu değeri diasble yapabiliriz.


SELECT a.ksppinm, b.ksppstvl, b.ksppstdf
FROM x$ksppi a, x$ksppcv b
WHERE a.indx = b.indx
AND a.ksppinm like '_recycle%'
ORDER BY a.ksppinm;

KSPPINM          KSPPSTVL    KSPPSTDF
_recyclebin         TRUE             TRUE

Disable yapmak için;

ALTER SYSTEM SET "_recyclebin"=FALSE SCOPE = BOTH;
System altered

Database’ i stop – start etmemiz gerekiyor.

Sorguyu tekrar çektiğimizde ;

SELECT a.ksppinm, b.ksppstvl, b.ksppstdf
FROM x$ksppi a, x$ksppcv b
WHERE a.indx = b.indx
AND a.ksppinm like '_recycle%'
ORDER BY a.ksppinm ;

KSPPINM       KSPPSTVL   KSPPSTDF
_recyclebin     FALSE           TRUE

Test edelim bakalım tablo drop ettiğimizde recyclebin’ e gidecekmi;

CREATE TABLE deneme as select * from tab;
Table created.

DROP TABLE deneme
Table dropped.

SELECT original_name FROM user_recyclebin;
no rows selected

Recyclebin’ i de hiçbir data yok.

10gR2 ve 11g de recyclebin’ i disable etmek için ise initial parametreler arasında yer alan Recyclebin parametresini OFF yapmak yeterli olacaktır. Yine bu parametre statik olduğundan dolayı database’ i stop – start etmeyi unutmamak gerekir.

-- Session bazında disable yapmak için;
ALTER SESSION SET recyclebin = OFF;
Session altered.

-- System  bazında disable yapmak için;
ALTER SYSTEM SET recyclebin = OFF;
System altered.

Flasback ile ilgili sonradan aklıma gelen konuları fırsat buldukça eklemeye devam edeceğim. Tabi flashback database’ i de unutmadım :)


Kamil TÜRKYILMAZ

29 Aralık 2010 Çarşamba

Tablo Seviyesinde Yapılan Flashback Operasyonları – 2 (Flashback Drop)


Flashback konusunda sadece flashback drop ve flashback database konularımız kaldı. Bu konuya başlamışken bu bölümdeki tüm konulara burada değinmek istiyorum. En azından birileri merak ederse tüm konulara tek link üzerinden ulaşabilme şansı olmuş olur. Falshback drop konusu ile ilgili olarak da Ogan kardeşim de kendi sayfasında yer verdi. İlham kaynağı olarak da beni referans göstermiş, bu konuda birilerine referans olabildiysem ne mutlu bana :)  bu vesileyle burdan oganada teşekkür etmek isterim, çünkü blog oluşturma fikrinin oluşmasında oda bana ilham kaynağı olmuştu :)


Aynı konuyu farklı bir yorumla Ogan’ da ele almış, bence çokda güzel olmuş oraya da göz atmanızı öneririm ;
http://oganozdogan.blogspot.com/2010/12/flashback-table-drop-recyclebin.html

Flashback Drop ; 

Flashback drop, drop table işlemini geri alan komuttur. Flashback drop işlemi aklınıza gelebilecek tüm recovery işlemlerinden çok daha hızlıdır ve kesinti gerektirmez data kaybına yol açmaz. 

Tablo drop ettiğiniz zaman, database hemen drop edilen tablonun size' ı kadar alanı dize geri kazandırmaz. Bunun yerine tablo üzerinde düzenleme yaparak tabloyu içerdiği tüm bileşenleri birlikte (index, constraint vs.) çöp kutusuna taşır. Recyclebine taşınan obkjeclere ait isimler system tarafından unigue olarak generate edilirler. Flashback operasyonu da tabloyu recyclebinden kurtarma çıkartma operasyonudur. Drop edilen tabloyu geri alırken orjinal ismiyle veya belirleyeceğiniz başka bir isimle veya recyclebindeki ismiyle alabilirsiniz. 

Sysdba yetkili bir kullanıcı ile çalışıyorsanız unutmamamız gereken şey, bu yetkiye sahip kullanıcının drop ettiği nesneler recyclebin koruması altında değildir. 

Flasback Drop için Ön Gereksinimler; 

Aşağıdaki liste Flashback Drop ve recyclebin ile ilgili işlemleri için gerekli olan kullanıcı ayrıcalıklarını özetler ; 

* Drop; 
Drop yetkisine sahip herhangi bir kullanıcı bir nesneyi recyclebin' e gönderebilir. Bunun drop etmesi yeterli olacaktır. 

* FLASHBACK TABLE ... TO BEFORE DROP
Bu sorgunun hakları Drop yetkilerine bağlıdır. Bu, object drop edebilen herhangi bir user, flashback drop ile bu object'i recyclebin den geri alabilir. 

* Purge 
Recyclebin den objecti purge etme yetkiside Drop yetkisine bağlıdır. Drop Table veya Drop any table yetkisine sahip herhangi bir kullanıcı recyclebindeki objecti purge edebilir. 

* SELECT for objects in the Recycle Bin
Recyclebin içerisindeki tabloyu select etmek ve Flashback ile tabloyu geri döndürmek için kullanıcıların Select ve Flashback haklarına sahip olmaları gerekmektedir 

Her drop edilen object recyclebin' e gitmez, dolayısıyla bir nesnenin recyclebin den geri alınabililmesi için aşağıdaki kriterleri sağlaması gerekmektedir ;

1 - Recyclebin sadece system objeleri dışındaki, local managed tablepsace' lerindeki objecler için geçerlidir. Eğer table system objesi değilse, locak managed tablespace' indeyse fakat ilgili tabloya ait bir veya daha fazla object dictionary managed tablespace' e ise bu objeler recyclebin de korunur. 

2 - Üzerinde Fine-Grained Auditing (FGA) ve Virtual Private Database (VPD) kuralları tanımlanmış olan tablolar, recyclebin koruması altında değillerdir. 

3 - Partition yapılmış index-organize tablolar recyclebin koruması altında değildir. 

4 - User veya oracle database' i tarafından alanı yeniden kullanabilmek için tablo purged edilmemiş olmalıdır. 

Buraya kadarki olan kısımı örneklendirecek olursak ; 

10g den farklı olarak 11g de recyclebin parametresi initial parametresine bağlanmıştır. Parametrenin şu anki değerini görmek için ; 

SQL> show parameter recyclebin ;
NAME               TYPE               VALUE
-------------       -----------        --------
recyclebin           string                 ON

Bu değer ON olması recyclebin özelliğinin açık olduğu anlamına gelir, bu değer OFF olarak dönerse recyclebin kapalı demektir ve açılması gerekecektir. Onun içinde ; 

Alter system set recyclebin = ON scope = SPFILE ; 

Dememiz, sonrasında bu parametre statik bir parametre olduğundan dolayı database’ in stop – start edilmesi gerekecektir. Bizim örneğimizde açık olduğundan dolayı devam edebiliriz. 

Recyclebin içerisindeki objeleri select etmek için ; 

SELECT object_name AS recycle_name, original_name, type  FROM recyclebin; 

Sorgusundan faydalanabiliriz. 

RECYCLE_NAME                                         ORIGINAL_NAME       TYPE
BIN$YM3moW14Rqub/ZjqACiKNw==$0    FLASHBACK_TEST     TABLE
BIN$3wr5BbnwQYK+AKilebLkBg==$0       FLASHBACK_TEST     TABLE
BIN$NpK/KUt/Sk2pOZk6VrpurA==$0        FLASHBACK_TEST      TABLE

Recyclebin içerisinde yer alan bir tablonun datalarını select etmek için; 

SELECT count(*) FROM "BIN$YM3moW14Rqub/ZjqACiKNw==$0"
COUNT(*)
--------
1522
1 row selected.

Recyclebindeki tabloyu geri almak için ; 

FLASHBACK TABLE "BIN$YM3moW14Rqub/ZjqACiKNw==$0" TO BEFORE DROP;
"bin$ym3mow14rqub/zjqaciknw==$0" successfully completed.

Aynı işlemi tablonun orijinal ismi ile de gerçekleştirebiliriz. 

FLASHBACK TABLE FLASHBACK_TEST TO BEFORE DROP;
Flashback_test successfully completed.

Flashback drop komutu ile aşağıdaki gibi bir hata alırsanız bunun nedeni geri almaya çalıştığınız tablonun orjinal ismi başka bir tablo olduğundan dolayıdır, dolayısıyla tabloyu geri alırken farklı bir isimle geri almaya çalışmalıyız ; 

FLASHBACK TABLE "BIN$NpK/KUt/Sk2pOZk6VrpurA==$0" TO BEFORE DROP
Error at line 1
ORA-38312: esas ad, mevcut bir nesne tarafindan kullaniliyor

FLASHBACK TABLE "BIN$NpK/KUt/Sk2pOZk6VrpurA==$0" TO BEFORE DROP RENAME TO FLASHBACK_TEST_2 ; 
"bin$npk/kut/sk2pozk6vrpura==$0" successfully completed.

select count(*) from FLASHBACK_TEST_2
COUNT(*)
----------
1522
1 row selected.

Son durumda tablomuzu sorunsuz olarak FLASHBACK_TEST_2 ismiyle geri almış olduk. 

Burada bir ufak bir yarıntı daha, drop etmiş olduğunuz tablo üzerinde index var ise doğal olarak index de drop olmuş oluyor. Bu durumda recyclebin’ i select ettiğimizde indexide burada görüyor olmamız gerekiyor. 

select owner, object_name, original_name, type from dba_recyclebin 

OWNER    OBJECT_NAME                                          ORIGINAL_NAME      TYPE
KAMIL      BIN$NoffUfJZS7OfErV1yYUBzg==$0        IDX_DENEME              INDEX
KAMIL      BIN$xlo4tuPpRVmYb+jJ+2o70A==$0        FLASHBACK_TEST     TABLE

Bu tabloyu geri aldığınızda index’ in ismi recyclebindeki ismi ile kalıyor, bunu bilmekde fayda var. 

FLASHBACK TABLE "BIN$xlo4tuPpRVmYb+jJ+2o70A==$0" TO BEFORE DROP;
"bin$xlo4tupprvmyb+jj+2o70a==$0" successfully completed.

select owner, index_name, table_owner from dba_indexes where owner = 'KAMIL'
and table_name = 'FLASHBACK_TEST'; 

OWNER    INDEX_NAME                                       TABLE_OWNER
KAMIL     BIN$NoffUfJZS7OfErV1yYUBzg==$0    KAMIL

Çok hoş bir isim olmadığından dolayı sonradan bunu değiştirmek isterseniz ;

ALTER INDEX " BIN$NoffUfJZS7OfErV1yYUBzg==$0" RENAME TO idx_flashback_index_1 ; 
index altered.

Flashback Drop konusu özetle bu kadar aslında, son olarak flashback’ le ilgili bikaç işe yarar script verebilirim, konuyu tamamlayacı nitelikde olduğundan yardımcı olabilir diye  düşünüyorum;

-- tablespace’si flashback dışında bırakma / alma
 
Alter tablespace ts_name Flashback ON
Alter tablespace ts_name Flashback OFF

--flashback recovery areade neyin ne kadar yer tut. bilgisi
select file_type, 
percent_space_used as used,
percent_space_reclaimable as reclaimable,
number_of_files as numbers
from v$flash_recovery_area_usage

--flashback recovery areanın backuplanması 
Rman> backup recovery files

--Database de flashback modun açık olup olmadığı 
select dbid,name,log_mode, flashback_on,
open_mode,db_unique_name 
from v$database

--flashback areanın doluluk oranı 
select name, 
to_char(space_limit,'999,999,999,999') as space_limit,
to_char(space_limit - space_used + 
space_reclaimable,'999,999,999,999') as space_available,
round((space_used - space_reclaimable)/space_limit * 100,1) as pct_full, number_of_files
from v$recovery_file_dest

Bir sonraki yazıma bu konunun son kısmı olan Flashback Drop ile devam etmeyi planlıyorum. Görüşmek üzere …


Kamil TÜRKYILMAZ

28 Aralık 2010 Salı

ORA-01122: database file 9 failed verification check (ora-01110 – ora-01208)


Arkadaşlar, bugün şirkette yaşadığımız bir disaster probleminin ortaya çıkışından ve soruna nasıl bir çözüm bulduğumuza varan uzun bir operasyonun üzerimizde yarattığı stresden bahsetmek istiyorum. Aslına haftaya güzel başlamıştık taki disaster tarafındaki standby database’ lerimizin kurulumu ile ilgilenen bir arkadaşımızın bizim için çok kritik olan bir production database’ ine ait 3 datafile’ i olduğu lokasyonda ziplemeye başlamasına kadar :) Sorunlar silsilesi tam bu noktada başlıyor, 3 tane dbf file’ ınız .gz olduğundan artık yok, ayrıca disk üzerinde aynı partitionda çalışan bir gzip procesi’ nin düzgün kill edilememesinden dolayı diskin doluluk oranı %100 olmuş durumda, kullanılabilir alan sıfır :) Database açık, database’ in toplam buyutu 500 gb (aslında bu tarz kritik database’ lerimiz arasında en ufak olanı bu olduğundan dolayıda biraz şanslıyız :) ziplenen 3 dbf’ in bağlı bulunduğu tablespace’ in büyüklüğü 260 gb, ve tablespace’ a ait tüm datafile’ ler begin backup modda. Aslında tüm niyetimiz database’ i kapatmadan soruna çözüm üretmekti ancak arka tarafda neler yapıldığınıda tam olarak kestiremiyorduk yani disk full dolu tam bu esnada yapılan gzip operasyonu, gzip bile düzgün tamamlanmış olmayabilirdi, byte mertebesinde dosyada olabilecek bir corruption tüm senaryonuyu değiştirmek için yeterli bir nedendi. Yaptığımız bir takım tespitlerden sonra system admini arkadaşlardan disk üzerinde yeterli büyüklükte bir partition alarak gece alınmış olan rman backupdan dönmeye karar verdik. (%100 dolmuş olan alanı farklı bir isimle unmount ettik, yeni aldğımız alanıda kullanılan eski isimle mount ettik) 500 gb backupın 480 gb okuduğu esnada (ki bu süreç tam 01:50 dak. kadar sürdü) yani sonuna gelmişken restore operasyonumuz HPUX-ia64 Error: 27: File too large hatasıyla fail oldu :) (system admini arkadaşımız diski verirken large file parametresine dikkat etmeden verdiği için yüksek size’ lı dbf’ leri kopyalarken hata fail oldu) Sonrasında yeni bir rman restore işine girişmeden tüm archive loglarımız olduğundan dolayı archive logları kullanarak ilgili datafile’ leri recover etmeye karar verdik. Ve bu şekilde tüm datafile’ lerimizi recover etmeyi başardık. Sonuç bizim açımızdan başarılıydı. Bunu aslında biraz da bu tarz operasyonların kritikliğinden bahsetmek için yazdım. Yapmış olduğumuz işlemlerin veya kontrollerin bir kısmından burda bahsettim. Asıl zor olan, bir disaster durumunda başınızda onlarca kişi toplanmışken ve her bir kafadan ayrı bir ses çıkıyorken sorunu iyi analiz edip, en kısa yoldan çözüm üretebilen bu işde ciddi şekilde başarılı oluyor diye düşünüyorum. Bu tarz koşullarda soğukkanlılığınızı, sakinliğinizi kaybetmeden paniklemeden çalışabiliyorsanız, bence bir dba’ in mutlaka sahip olması gereken bu vasıflarına sahipsiniz demektir. Bunların üzerine deneyim ve tecrübelerinizi de eklediğinizde işte o zaman ortaya kaliteniz çıkıyor. Disaster' sız günlerde görüşmek üzere :)

Flashback drop ile devam etmeye çalışacağım. 
İyi geceler.



Kamil TÜRKYILMAZ 

25 Aralık 2010 Cumartesi

Tablo Seviyesinde Yapılan Flashback Operasyonları


Flashback table ile tablonun geçmiş bir andaki durumuna dönülebilir. Bu işlem online ve çok hızlı yapıldığından dolayı, tablonun önceden alınmış olan bir backupından faydalanarak yapılması ile karşılaştırılamayacak derecede dba’ lere zaman kazandırmaktadır. Tablonun flashback drop ile tekrar kazanılması sırasında tablo üzerinde yer alan index,triggger, constraintlerde tablo ile birlikte tekrar kazanılmaktadır. Bu komutun çalıştırılabilmesi için bir takım gereksimler bulunmaktadır. Bunlar ;

• Flashback table operasyonunda da diğer flashback işlemlerinde olduğu gibi Undo tablespace’ i kullanılır.
 

• Flashback operasyonu tablodaki datalara ait rowid’ leri değiştireceğinden dolayı tablonun row movement özelliğinin enable olması gerekmektedir.
 

• Bunun yanında flashback işlemini yapacak olan kullanıcı da database seviyesinde FLASHBACK ANY TABLE yetkisine veya sadece obje için Flashback yetkisine sahip olmalıdır.
 

• Yine tablo üzerinde SELECT, INSERT, DELETE ve ALTER yetkilerine sahip olunmalıdır.
 

• Bu işlemler için Undo tablespace’ I kullanıldığını bahsettiğimize göre o zaman, gitmek istediğimiz zamana kadarki verilerinde undo tablespace’ inde tutuluyor olması gerekmektedir.
 

Buraya kadar bahsettiklerimiz Flashback table operasyonu için olması gerekenler idi. Ancak bu belirttiğimiz kriterlerin hepsi var olsada yinede kimi tablolar üzerinde bu komutu çalıştıramazsınız. Bunlardan da kısaca bahsedelim;

• Üzerinde işlem yapılacak olan object aşağıdaki kategorileri içermemelidir; Cluster table, materialized views, Advanced Queuing (AQ) tables, static data dictionary tables, system tables, remote tables, object tables, nested tables, or individual table partitions or subpartitions.
 

• Tablonun yapısı flashback table ile dönülecek zaman aralığı içerisinde değişmemiş olması gerekmektedir. (Tablonun yapısını değiştiren DDL işlemleri; upgrading, moving, or truncating a table; adding a constraint to a table, adding a table to a cluster; modifying or dropping a column; adding, dropping, merging, splitting, coalescing, or truncating a partition or subpartition (with the exception of adding a range partition)

• Üzerinde çalıştığınız uygulama tablodaki kayıtların rowid’ lerine bağımlı ise, flashback table kullanmamalısınız. (Flashback table operasyonu sonrasında towid’ ler değiştiğinden dolayı)
 

• Undo tablespace’ inde datayı tutmak için yeterince yer olmalıdır. Undo tablespace’ indeki Undo datası, datanın değişmeden önceki halini tutar. Flashback table minumum tutulan undo datasına undo retention time’ e bakarak karar verir. Undo_retention parametresi için Oracle’ ın önerdiği değer 1 gün yani 86400 saniyedir.
 

Konuyu örneklendirmeden aslında database’ de flashback modu nasıl açarız, hangi parametreleri var ne anlama geliyor gibi konulara biraz değinelim, zira sürekli olarak flashback komutlarından bahsediyoruz ama database nasıl flashback moda alınacak bundan hiç konuşmadık.
 

Database’ in falshback modda olup olmadığını aşağıdaki şekilde kontrol edebiliriz.
 

select flashback_on from v$database ;
 

FLASHBACK_ON
 
-----------------
YES
 
1 row selected.

Olduğunu görmeliyiz, sorgu sonucu NO olarak dönüyor ise database’ iniz flashback modda değildir demektir. Flashback moda almak için önce database’ i kapatıyoruz, mount modda açıyoruz. Burada unutulmaması gereken flashback modu açmak için database mutlaka archive modda olması gerektiğidir.
 

SQL> shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.

SQL> startup mount
ORACLE instance started.
Total System Global Area 419430400 bytes
Fixed Size 1249368 bytes
Variable Size 83890088 bytes
Database Buffers 327155712 bytes
Redo Buffers 7135232 bytes
Database mounted.

SQL> select log_mode from v$database ;
LOG_MODE
------------
ARCHIVELOG

Database’ imiz archive modda, flashback için gerekli parametreleri tanımlamaya başlayabiliriz. Burada önemli olan 3 tane parametremiz var; Kaç dakika geriye gidebileceğimizi belirtten,
 
DB_FLASHBACK_RETENTION_TARGET parametresi, Flashback loglarının birikeceği alanın boyutunun ne olacağını belirttiğimiz DB_RECOVERY_FILE_DEST_SIZE velogların nereye yazılacağının tanımlandığı DB_RECOVERY_FILE_DEST parametresidir. Disk üzerinde kullanılan alanların takibi bizler için ciddi önem taşır, dolayısıyla burda DB_RECOVERY_FILE_DEST_SIZE parametresi çok önemli diye düşünüyorum çünkü bu parametre ile logların toplam size’ ının belli bir boyutunu geçmesini engelleyebilirsiniz. Burada retention target ile dest_size parametreleri çakışabilir, orda şu kural geçerli olur, belirtiğiniz size dolana kadar log üretir bu arada retention_target değerine ulaşılmamış olsada en eski logdan başlayarak ezerek yazamaya devam eder. Yani retention_target değerine ulaşılamadı diye size’ I belirtmiş olduğunuz değerin üstüne çekemez. Şimdi bu parametreleri set edelim. Sample değerlerimiz;
 

Retention_target = 24 saat,
 
Dest_size = 10 gb,
 
Dest_size = D:\oracle\flashback_area olsun.
 

SQL> ALTER SYSTEM SET DB_FLASHBACK_RETENTION_TARGET=1440 scope=BOTH
System altered.

SQL> ALTER SYSTEM SET DB_RECOVERY_FILE_DEST_SIZE=10G scope=BOTH;
System altered.

SQL> ALTER SYSTEM SET DB_RECOVERY_FILE_DEST=' D:\oracle\flashback_area\' scope=BOTH;
System altered.

Bazen path’ i belirtirken aşağıdaki gibi bir hata mesajı alabilirsiniz bu durumda, archive lokasyonunu önce sıfırlayıp sonra tekrar set etmek gerekebiliyor.
 

ORA-02097: parameter cannot be modified because specified value is invalid
ORA-16018: cannot use LOG_ARCHIVE_DEST with LOG_ARCHIVE_DEST_n or DB_RECOVERY_FILE_DEST

SQL> ALTER SYSTEM SET log_archive_dest='';
System altered.

SQL> ALTER SYSTEM SET DB_RECOVERY_FILE_DEST=' D:\oracle\flashback_area\' scope=BOTH;
System altered.

SQL> ALTER SYSTEM SET log_archive_dest_1='LOCATION=d:\oracle\arch\';

Gerekli değisiklikleri yaptıktan sonra, asağıdaki ifadeyi çalıstırıp, ayarları kontrol edebilirsiniz:
Tüm bu ön ayarlamaları yaptıkdan sonra Flashback özelliğini aktif hale getirebiliriz ;
 

SQL> ALTER DATABASE FLASHBACK ON;
Database altered.

Database’ imizi açıyoruz;
 

SQL> ALTER DATABASE OPEN;
Database altered.

Tüm bu işlemlerden sonra Oracle’ ın aşağıda linkini de belirtiğim sayfasında yer alan örnekle devam edebiliriz ;
 

Öncelikle sistemin şu anki SCN numberını öğrenmekle başlayalım;

SELECT CURRENT_SCN FROM V$DATABASE;
CURRENT_SCN
-----------
10824010
1 row selected.

Sonra önceden alınmış olan bir restore point noktası olup olmadığını kontrol edelim ;
 

SELECT NAME, SCN, TIME FROM V$RESTORE_POINT;
No rows.
 

Undo_retentition time değerini kontrol edelim.
 

SELECT NAME, VALUE/60 MINUTES_RETAINED  FROM V$PARAMETER
 
WHERE NAME = 'undo_retention';

NAME MINUTES_RETAINED
undo_retention 1440
1 row selected.

Tablo üzerindeki rowid’ lerin değişebilmesini sağlamak için tablomuzun row movement özelliğini açalım.
 

SQL>ALTER TABLE kamil.flashback_table_test ENABLE ROW MOVEMENT;
Table altered.

Sonrasında tüm tablonun delete edildiğini varsayalım.
 

SQL>delete kamil.FLASHBACK_TABLE_TEST
5018 rows deleted.

SQL>commit;
Commit complete.

select count (*) from kamil.FLASHBACK_TABLE_TEST;
 
COUNT(*)
----------
0
1 row selected.

SQL>FLASHBACK TABLE kamil.FLASHBACK_TABLE_TEST TO TIMESTAMP TO_TIMESTAMP('2010-12-25 16:35:00', 'YYYY-MM-DD HH24:MI:SS');
Flashbacktable successfully completed.

SQL>select count (*) from kamil.FLASHBACK_TABLE_TEST;
COUNT(*)
----------
5018
1 row selected.

Diğer flashback table komutu ile ilgili örnekler ;
 
FLASHBACK TABLE kamil.FLASHBACK_TABLE_TEST TO TIMESTAMP TO_TIMESTAMP('2010-12-25 16:35:00', 'YYYY-MM-DD HH24:MI:SS');

FLASHBACK TABLE kamil.FLASHBACK_TABLE_TEST TO TIMESTAMP TO_TIMESTAMP('2010-12-25 16:35:00', 'YYYY-MM-DD HH24:MI:SS') ENABLE TRIGGERS;
 

FLASHBACK TABLE kamil.FLASHBACK_TABLE_TEST TO scn 10824900;
 

Flashback işlemi sırasında tablo üzerindeki trigger’lar default olarak disable halde gelirler. İşlemi gerçekleştirirken tablo üzerindeki trigger’ların da aktif durumda olmasını istiyorsak flashback komutumuzun sonuna Enbale Triggers parametresini eklememiz yeterli olacaktır.
 

FLASHBACK TABLE kamil.FLASHBACK_TABLE_TEST TO TIMESTAMP TO_TIMESTAMP('2010-12-25 16:35:00', 'YYYY-MM-DD HH24:MI:SS') ENABLE TRIGGERS ;
 

Kaynak;
 
http://download.oracle.com/docs/cd/E11882_01/backup.112/e10642/rcmflash.htm#BRADV81517

Bir sonraki yazıma Flashback drop ile devam edeceğim.
 
Görüşmek üzere …


Kamil TÜRKYILMAZ 

21 Aralık 2010 Salı

Satır Seviyesinde Flashback Operasyonları


Satır bazında yapılan flashback 3 şekilde yapılabilir; 

Flashback Query ; Bir tabloda ki verilerin geçmiş bir zamandaki durumunlarını select etmek için kullanırız. Örneğin, bir tablo üzerinde yanlışlıkla yapılan ve commit edilen bir update işlemi sonrasında, update öncesindeki değerlerin neler olduğunu görebilmemizi sağlar. 

Flashback Versions Query ; Version query, bir kaydın, belirlenen iki zaman aralığındaki almış olduğu değerleri select eder. Yani a personelinin 2010, 1 Aralık saat 09:00 tarihindeki maaşı ile 2010 1 Kasım saat 09:00 daki maaşlarını karşılaştırabilirsiniz. 

Flashback Transaction Query ; Bir transaction tarafından yapılan DML işlemlerine ait yapılan değişiklikleri veya belli bir zaman aralığında yapılan tüm değişiklikleri, undo sql leri ile birlikte gösterir. 

Şimdi bu 3 koşulu örneklendirmeye çalışalım. Öncelikle üzerinde çalışacabileceğimiz bir sample data oluşturalım. İşlemin yapıldı tarih aralığı ise 21.12.2010 13:19:30 ve 13:25 arasına ait. Bu bilgiye sahip olmamız istediğimiz datayı bulmamızda yardım edecektir.
 

create table kamil.deneme (
id number(5),
ad varchar2(20),
soyad varchar2(30) ) ;
 

insert into kamil.deneme values (1,'aaa','bbb') ;
insert into kamil.deneme values (1,'ccc','ddd') ;
insert into kamil.deneme values (1,'eee','fff') ;
insert into kamil.deneme values (1,'ggg','kkk') ;
commit ;

update kamil.deneme set ad = 'xxx';
commit ;

insert into kamil.deneme values (1,'lll','mmm') ;
insert into kamil.deneme values (1,'nnn','ooo') ;
commit;

update kamil.deneme set ad = 'yyy';
commit;
 

Tablomuz hazır.
 

Flashback Query’ i test edelim. Tabloda son durumda en son yapılan update işlemi ile tüm kayıtların ad’ ı ‘yyy’ olarak set edilmiş gözüküyor. Eğer, tablonun 13:20 deki halini görmek istersek eğer; 

SELECT * FROM kamil.deneme AS OF TIMESTAMP TO_TIMESTAMP('2010-12-21 13:20:00', 'YYYY-MM-DD HH24:MI:SS')

==> SELECT * FROM kamil.deneme AS OF TIMESTAMP TO_TIMESTAMP('2010-12-21 13:20:00', 'YYYY-MM-DD HH24:MI:SS')

ID AD SOYAD
 
-- -------------------- ------------------------------
1 xxx bbb
 
1 xxx ddd
 
1 xxx fff
 
1 xxx kkk
 

4 rows selected.

Update işleminden önceki bir zaman aralığını select ettiğimiz için tablonun son durumunda tüm ad alanları ‘yyy’ olmasına rağmen burada önceki hallerini ‘xxx’ görüyoruz.
 

Burada tablodaki tüm kayıtları select etmek yerine sadece bir kayıtı select etmek isterseniz ;

Where soyad = ‘bbb’
 

satırını ekleyebilirsiniz. Milyonlarca kayıt olan bir tabloda tüm kayıtları elde etmek yerine sadece bir kayda bakmanız gerekebilir. Veya zaman aralığını tam olarak kestiremiyorsak, aşağıdaki deneyerek bulabiliriz. Veya scn number’ I biliyorsak ona göre where kriteri belirleyip select edebiliriz.
 

==> select * from kamil.deneme as of timestamp (systimestamp - interval '25' minute)

ID AD SOYAD
 
-- ----- ------------------------------
1 xxx bbb
 
1 xxx ddd
 
1 xxx fff
 
1 xxx kkk
 

4 rows selected.

Son bir not olarak flashback query ile select çalıştırdığımızda aşağıdaki gibi ora-01466 hatası alırsak bunun anlamı girmiş olduğumuz zaman aralığına ait herhangi DML işlemi olmadığı anlamına gelmektedir. Flashback DDL işlemlerini desteklememektedir.
 

==> select * from kamil.deneme as of timestamp (systimestamp - interval '55' minute)

select * from kamil.deneme as of timestamp (systimestamp - interval '55' minute)
*
Error at line 1
ORA-01466: unable to read data - table definition has changed

Flashback Versions Query test edelim. Tabloya son yapılan update işleminin 13:25 de yapıldığını varsayarsak 13:20 ile 13:26 daki tablo kayıtlarını select ettiğimde ad alanında yapılan değişikliği görebilmeliyim diye düşünüyorum.
 

Sorguyu ilk çalıştırdığımda aşağıdaki gibi bir hata aldım. Hatanın nedeni select etmeye çalıştığım zaman aralığının undo_retention dışında kalmasından dolayı idi. Parametreyi artırdığımda sorun
giderilmiş oldu.
 

==> SELECT versions_xid,
versions_startscn,
versions_endscn,
versions_operation,
VERSIONS_STARTTIME,
VERSIONS_ENDTIME,
id,
ad,
soyad
FROM kamil.deneme VERSIONS BETWEEN TIMESTAMP
TO_TIMESTAMP ('2010-12-21 13:20:00',
'YYYY-MM-DD HH24:MI:SS')
AND TO_TIMESTAMP ('2010-12-21 13:30:00',
'YYYY-MM-DD HH24:MI:SS') ;
 

Error at line 1
ORA-30052: invalid lower limit snapshot expression

==> alter system set undo_retention = 5000
System altered.

Tekrar çalıştırıyoruz.
 

==> SELECT versions_xid,
versions_startscn,
versions_endscn,
versions_operation,
VERSIONS_STARTTIME,
VERSIONS_ENDTIME,
id,
ad,
soyad
FROM kamil.deneme VERSIONS BETWEEN TIMESTAMP
TO_TIMESTAMP ('2010-12-21 13:20:00',
'YYYY-MM-DD HH24:MI:SS')
AND TO_TIMESTAMP ('2010-12-21 13:30:00',
'YYYY-MM-DD HH24:MI:SS')

Çıktıyı biraz sadeleştirip (düzgün okunması için bazı alanları çıkartıp) ekliyorum;
 

ID AD SOYAD
1 yyy ooo
1 yyy mmm
1 yyy kkk
1 yyy fff
1 yyy ddd
1 yyy bbb
1 nnn ooo
1 lll mmm
1 xxx bbb
1 xxx ddd
1 xxx fff
1 xxx kkk

Flashback Transaction Query’ i test edelim. Örneğimizde yapılan son update işleminin yanlışlıkla yapıldığını varsayalım. Bu tarz bir durumla karşılaşıldığında aşağıdaki query ile update’ in yapıldığı zamanı sorgulayıp yapılan her update işlemi için sistem tarafından otomatik olarak hazırlanmış olan undo_sql’ lerini çalıştırmamız yeterli olacaktır.
 

select start_scn, start_timestamp,
 
commit_scn, commit_timestamp,
 
operation,
 
table_name, table_owner,
undo_sql
 
from flashback_transaction_query
where table_owner='KAMIL'
and table_name = 'DENEME'
and start_timestamp > to_date('2010-12-21 13:25:00', 'YYYY-MM-DD HH24:MI:SS')

OPERATION UNDO_SQL
INSERT delete from "KAMIL"."DENEME" where ROWID = 'AAAV6AAAEAAAADIAAF';
INSERT delete from "KAMIL"."DENEME" where ROWID = 'AAAV6AAAEAAAADIAAE';
UPDATE update "KAMIL"."DENEME" set "AD" = 'nnn' where ROWID = 'AAAV6AAAEAAAADIAAF';
UPDATE update "KAMIL"."DENEME" set "AD" = 'lll' where ROWID = 'AAAV6AAAEAAAADIAAE';
UPDATE update "KAMIL"."DENEME" set "AD" = 'xxx' where ROWID = 'AAAV6AAAEAAAADIAAD';
UPDATE update "KAMIL"."DENEME" set "AD" = 'xxx' where ROWID = 'AAAV6AAAEAAAADIAAC';
UPDATE update "KAMIL"."DENEME" set "AD" = 'xxx' where ROWID = 'AAAV6AAAEAAAADIAAB';
UPDATE update "KAMIL"."DENEME" set "AD" = 'xxx' where ROWID = 'AAAV6AAAEAAAADIAAA';

Flashback Query' nin çalıştırılması için ya üzerinde işlem yapılacak olan tabloya yada tüm tablolar için aşağıdaki yetkilerin ilgili kullanıcıya verilmesi lazım;
 
         grant flashback on table_name to user_name;
         grant flashback on any table to user_name;

Flasback transaction query için ise aşağıdaki yetkinin verilmesi yeterli olacaktır; 
         grant select any transaction to user_name;

Çıkan sonuçdan da görüleceği üzere yapılan insert işlemine karşılık delete, update işlemine karşılık ters update scriptleri oluşdu. Bunu çalıştırmanız son yapılan işlemi geri almak için yeterli olacaktır. Production ortamlarda flashback komutları ile çalışırken dikkatli olmanız gerektiğini hatırlatmaya gerek yok diye düşünüyorum:)



Kamil TÜRKYILMAZ