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:)