Menu

28 Eylül 2010 Salı

Transactions


Transaction’ın kelime anlamı işlem, iş görmedir. Yani veri bloğuna yapılan işlemdir diyebiliriz. Bir grup DML deyiminin session tarafından execute edilmesidir.
Update, Delete, Insert,  Merge, Select For Update, Lock Table deyimlerinden biri ile başlar. Commit ya da rollback ile biter.
‘A’ (Atomicity): Bir tansactionın ya tamamen olması ya da  hiçbir işlemin yapılmamasıdır. Örneğin bankamatikten bir işlem yapan bir kişinin elektrilerin kesilmesi, cihazın bozulması vb durumlar ile yarıda kesilmiş bir işlem karşısında yaptığı işlemlerin hepsi rollback edilerek başlangıç durumuna geri döndürülmesi olayıdır.
                            Sağlıklı bir transaction
                                                Yarıda kesilen bir transaction

‘C’ (Concurency): Veri tabanı tutarlı veri sağlar.
‘I’ (Isolation) : Veritabanına birden fazla kullanıcı erişebilir. Birinin yaptığı işlemi diğerinin yaptığı işlem etkilemez.

 Yukarıdaki örnekte A kişisi Mehmet’in salary bilgisini 500, b kişisi ise Ahmet’in salary bilgisini 300 olarak update işlemi yapıyor. Ama select ettiklerinde sadece kendi değişikliklerini görebiliyorlar çünkü henüz ikisi de commit işlemi yapıp transactionı bitirmediler.


Commit yaptıklarında yani transactionı bitirdiklerinde ise her iki değişikliği de görebilirler.
‘D’ (Durability): Commit edilen işlemlerin veritabanına işlendiğinden emin olunmasıdır.
Transaction Kontrol Deyimleri
       COMMIT : Unique system change number (SCN) atanır. Log writer process (LGWR), SGA’s redo log bufferları redo log file’lara yazar. Oracle rowlarda tutulan kilitleri serbest bırakır. Transactionı bitirir.
       ROLLBACK : Yapılanları geri alır. Rowlarda tutulan kilitleri serbest bırakır. Transactionı bitirir.
       SAVEPOINT : Transaction içinde bir point (noktayı) işaretlemeni sağlar. Bir den çok point de işaretlenebilir.
       ROLLBACK TO : Herhangi bir durumda istenildiğinde işaretlenen pointlere geri dönülmesi sağlar.
       SET TRANSACTION : Transactionın isolation levelının vb belirlenmesini sağlar.
-          Isolation Level
-          Specifying UNDO Segment
Farklı Atomicity’ler
Statement-Level Atomicity : Oracle, Sybase and SQL Server’s ların aksi şekilde hareket eder. 
  
   1: create table t2 ( cnt int );
   2: insert into t2 values ( 0 );
   3: commit;
   1: create table t ( x int check ( x>0 ) );

   1: create trigger t_trigger
   2: before insert or delete on t for each row
   3: begin
   4:    if ( inserting ) then
   5:         update t2 set cnt = cnt +1;
   6:    else
   7:         update t2 set cnt = cnt -1;
   8:    end if;
   9:    dbms_output.put_line( 'I fired and updated '  ||
  10:                                    sql%rowcount || ' rows' );
  11: end;
   1: insert into t values (1);
   2: insert into t values(-1);
   3: select * from t2;


Yukarıdaki gibi check constraint’li bir t tablosu, içinde 0 değeri olan bir t2 tablosu ve insert ve deleteden önce tetiklenecek bir trigger yaratalım. T tablosuna aşağıdaki gibi insert işlemlerini yapmaya çalıştığımızda ilk insertin yapıldığı ikincinin ise yapılmadığı görülmektedir. Yani ilk işlem başarı ile gerçekleşmiş ama oracle tarafından commit işlemi yapılmış kullanıcıya bırakılmıştır, ikincisinde ise işlem başarısız olmuştur.

Başarılı olan işlemler için commit ya da rollback yapmaz. Kullanıcıya bırakır.
Procedure-Level Atomicity : Kullanıcı bir kod bloğunu çalıştırır. Oracle çevresine savepoint yerleştirir. 

   1: create or replace procedure p
   2: as
   3:  
   4: begin
   5:  
   6:         insert into t values ( 1 );
   7:  
   8:         insert into t values (-1 );
   9:  
  10: end;
  11:  
bir p procedure2u yaratalım ve çalıştıralım.

   1: select * from t;
   2: select * from t2;

sorgusu yaptığımızda görüldüğü gibi iki insertü de yapmamıştır. Çünkü ikinci insert hata verdiği için ardışık işlem kesintiye uğramış ve bu yüzden oracle procedure’un başına koyduğu savepointe geri dönmüştür. 

   1: begin
   2:  
   3:     savepoint sp;
   4:  
   5:     p;
   6:  
   7: exception
   8:  
   9:     when others then
  10:         null;
  11:  
  12:         rollback to sp;
  13:  
  14: end;
  15:  

   1: begin
   2:  p; 
   3: exception 
   4: when others then null; 
   5: end; 
   6: / 
   7:  
   8: I fired and updated 1 rows 
   9: I fired and updated 1 rows 
  10:  
  11: PL/SQL procedure successfully completed.
  12:  
  13: select * from t;
  14:  
  15: X
  16: ----------
  17: 1
  18:  
  19: select * from t2;
  20:  
  21: CNT
  22: ----------
  23: 1
  24:  
 
1. insert işlemi gerçekleşir, ikinci de hata oluştuğu için exception bloğuna düşer.
Immediate Constraints :
Sql deyimi bittikten sonra integrity constraints kontrolü yapılır. Aşağıdaki örnekte t tablosu yaratılmış ve 1, 2 değerleri insert edilmiş. Aşapıdaki update işlemi çalıştırıldığında eğer her satırda constraints kontrolüü olsaydı ikinci satırda hata alınırdı ama sql deyimi bittikten sonra kontrol yapıldığı için işlem gerçeklenmekte.


   1: create table t  ( x int unique );
   2:  
   3: insert into t values ( 1 );
   4:  
   5: insert into t values ( 2 );
   6:  
   7: update t set x = x+1;
   8:  
 
Kötü Transactionlar
-          Loop içinde cmmit işlemi yapmak.
-          Autocommit özelliğinin açık olması (default ). 

   1: INSERT INTO T SELECT OBJECT_NAME FROM ALL_OBJECTS;
   2:  
   3: COMMIT; 
   4:  
   5: FOR x in (SELECT * FROM ALL_OBJECTS )
   6:  
   7: LOOP
   8:  
   9:      INSERT INTO T VALUES ( x.object_name);
  10:  
  11:      COMMIT; 
  12:  
  13: END LOOP; 
  14:  
 
Distributed Transactions
Uzak sunucuda da değişiklik yapılıyorsa ya ikisinde de yapar ya da hiçbirinde yapmaz(Atomicity). 2PC protokolünü kullanır.
DDL’ler kendi içinde commit yapar, commit yapılamadığından DDL de yapılamaz.
DDL yapılmasının tek yolu DBMS.JOB ya da Oracle 10g, the scheduler packageile gelen DBMS_SCHEDULER kullanılarak uzaktan bir iş tanımlanır ve bu işlem ile commit yapılabilir.

Autonomous Transactions
Sadece loglama işlemlerinde kullanımalıdır.Transaction içinde transaction yaratarak, commit ve rollback değişikliklerini parent transactiondan bağımsız gerçekleştirir.


Yazan : Bahar Gezici
http://www.bahargezici.com/post/2010/07/28/Turkcell-Staj-e28093-Transactions.aspx

REDO & ROLLBACK 2

Yaptığımız işlemler ile ne kadar redo üretiyoruz?
Developer olarak yazdığımız kodun ne kadar redo ürettiği ile de ilgilenmeli ve bunu önemsemeliyiz. Çünkü ne kadar çok redo üretirsek kodumuzun yaptığı iş o kadar yavaşlar, performansı düşürür.
Insert, Update, Delete işlemlerinin satır sayısı ile redo üretimi ilişkisi aşağıdaki gibidir. Tabloyu inceleyeck olursak, Update ve Delete işlemlerinin 1 kerede 200 satırın işlem görmesi ile tektek işlem görmesi sırasında üretilen redo miktarı hemen hemen aynı. Ama Insert biraz daha farklı. 200 satırı data bloka yazarken farklı, tek tek yazarken farklı davranır. Bu sebep ile Tek bir satırda yaptığı işlem, satır satır yaptığı işleme göre daha az redo üretir. 
 Ayrıca loop içine commit eklersek  redo miktarı ciddi derecede artar ve 3 kat yavaşlar. 


Bu yüzden mümkün olduğunca az satırda işlemlerimizi yapmalı, commiti ise gerçekten ihtiyacımız olduğunda kullanmalı ve rollback yapmaktan kaçınmalıyız.
Trigger kullanıldığında ise, before trigger deyimi değerlerde bir değişiklik yapmamasına rağmen genellikle redo miktarını arttırmaya eğimlidir. Before ya da After trigger Delete redo miktarını etkilemez, Insert redo miktarı ise her ikisi için de aynıdır, Update redo miktarı ise before’dan etkilenir ama after’dan etkilenmez. 
Redo Log’ları devredışı bırakabilir miyim?
Redo Log’ları devredışı bırakamıyoruz. Çünkü database için redo loglar çok önemlidir. Ama bazı operasyonlar redo log miktarını azaltabilmektedir. Bazı sql deyimleri nologging özelliğini desteklemektedir. Ama bu loglamayı sıfırladığı anlamına gelmez. Normale göre daha az redo log üretilir.
Block CleanOut
Locklar block headerda yer almaktadır. Block’a bir sonraki erişimde header bilgisini yani transaction bilgisini silmemiz gerekebilir. Bu faaliyet redo üretir ve block’un kirlenmesine (dirty data) neden olur.

 Bir tablo yaratttık ve içine veriler ekledik, commit ettik.
 Önce redo_size(Kyte’ın kitabında oluşturduğu bir view)’ımıza bakıp datayı okuduk. Okuma sırasında oluşan redo miktarını aldık. Select sırasında üretilen redo miktarı yaklaşık 30KB. Bu da table full scan sırasında block headerların değiştiğini gösteriyor. İkinci kez run ettiğimizde;


Hiç redo üretilmediğini görmekteyiz, tüm data block headerlar temiz.
Eğer süreç
 Çok miktarda yeni datanın bluk loading ile database’e yüklenmesi
      - Yeni eklenen tüm datanın update edilmesi
      - Dataya sorgu yapılmasına izin verilmesi
     ‘den oluşuyorsa, bu durumdan ciddi anlamda etkilenirsiniz.
Dataya bir sorgu yaptığınızda, data ek processlere maruz kalabilir. Data update edildikten sonra istatistik toplatılması block headerların silinmesini sağlayacaktır.
Temporary Tables ve Redo/Rollback
Temprorary tables Oracle 8.1.5 ile gelmiştir. Bu bölümde sadece logging üzerindeki etkisinden söz edeceğim. Database Tables bir sonraki bölüm o kısımda daha ayrıntılı bahsedeceğimJ.
Temprorary tables data block’ları için redo oluşturmazlar. Yani bu tablo üzerinde yapılan bir değişiklik recoverable değildir. Ama Temprorary tables rollback yaparlar ve bu yüzden rollback loglanır. Bu yüzden az da olsa redo üretirler.
 İki tane tablo yaratalım; biri temprorary table diğeri normal table.
 Tablolar üzerinde birkaç sql yapan bir procedure yazdık. Ve sonuçları analiz ettik.
Normal tabloya yapılan Insert çok fazla redo üretir, temp tanlosu için ise nerdeyse üretmez. İnsert için sadece rollback datası loglanmıştır. 

Normal tabloya yapılan Update temp tabloyadaki redonun iki katı cıvarındadır. Temp tablosu için Update işleminin ilk (before) kısmı loglanırken sonraki(after) kısmı loglanmaz. Bu yüzden aradaki fark iki kattır.
Delete işleminde redo miktarları birbirlerine yakındır. Değişen blokların için yapılan redo az ama rollback için yapılan redo büyüktür. Bu yüzden normal tablo çok az daha fazla redo üretir.

  •      - Temp tablolarında Delete yerine Tuncate kullanılmalıdır.

  •      - Insert ve select işlemleri için daha çok temp tabloları kullanılmalıdır.

  • Set Transaction

  • SET TRANSACTION hangi rollback segmentini kullanmak istiyorsak onu seçmemize imkan sağlar.

  • SET TRANSACTION USE ROLLBACK SEGMENT rb_seg_name;


  • Özellikle çok büyük rollback segmentlerine ihtiyaç duyulduğunda ve tanımlanan rollback segmentinin kullanılacağı her transactionın başında çalıştırılmalıdır.

REDO & ROLLBACK

Günler çok çabuk geçerken sunumlar da artıyor ve ben bu yazı dizisinde kitabın 5. chapterına gelmiş bulunuyorum. Bu chapter DBA ile developer arası bir konudur. Bu chapterı iki makaleye böldüm, oldukça uzun ve önemli bir konu olduğunu düşünüyorum. Daha ayrıntılı bir aktarım için bu şekil daha iyi olacak sanırım.
Peki Redo nedir ?
Yapılan tüm transaction işlemlerinin kayıt haline alınmış halidir. Geri gönüş yapılmak istendiğinde redo ve rollbackten faydalanılabilir. Recovery amacı ile kullanılır. Transaction Logs olarak da adlandırılır. Rollback’e aynı zamanda Undo denilmektedir yani redo ve undo tamamen zıt şeylerdir.
İki tip redo log file yapısı vardır: Archived Redo Logs ve Online Redo Logs . Yapıları aynı, üstlendikleri görevler farklıdır.
Güç gittiğinde -> instance failure’a sebep olur. Online Redo Log ile recover edilir.
Disk sorunlarında -> Archived Log ve Online Redo Log’lar kullanılır.
Kaza –> kaza ile silinmemesi gereken bir object silindiyse vb durumlarda kazadan önceki zamana dönmek için kullanılır. Archived Redo Logs ve Online Redo Logs ‘dan yararlanılır.
Online Redo Log : Her oracle veritabanının en az 2 tane online redo logu vardır.
Archived redo Log: Online redo logların kopyasıdır.  Online redolog da yer kalmadığı zaman ARCH process tarafından başka bir locationa yazılır.
Commit ne yapar?
Commit transactionın boyutundan bağımsız, hızlı bir operasyondur.  Büyük transaction daha uzun sürede commit edilir diye bir şey yoktur. Dolayısı ile transactionı küçük parçalara bölmek işlem hızını arttırmaz. Bu yanlış bir düşüncedir.
Peki neden ?
Commit yapılmadan zaten database gerekli değişiklikleri arkaplanda yapmıştır.
-          Rollback segment kayıtları SGA’da oluşturulmuştur.
-          Değişen datablockler SGAda oluşturulmuştur.
-          Buffer redo oluşturlmuştur.
-          Yukarıdaki 3 işlemin büyüklüğüne bağlı olarak diske flush edilmiş olabilir.
-          Kilitler elde edilmiştir.
Commit yapıldıktan sonra
-          Unique system change number (SCN) atanır.
-       Log writer process (LGWR), SGA’s redo log bufferları redo log file’lara yazar.
-       Oracle rowlarda tutulan kilitleri serbest bırakır.
-       Transactionı bitirir. v$Transaction daki verimiz kaybolur.
SCN Ne İşe Yarar ?
-          Transactionları sıralar.
-          Hata sonrası sistem kurtarmayı sağlar
-          Tutarlı okumayı sağlar (read consistency)
-          Checkpointing
Bir insert, update vb.. yapıldığında sadece değişen kısmını alır.
Her commit sırasında I/O işlemi yapılır. 3sn de bir commit edilmese bile redo log file’lara yazılır. Asıl uzun süren bu I/O işlemidir. Redolog bufferın sizeına da bakılmalı, eğer dolmuşsa 3 snden az bir süre içinde de yazılabilir.  I/O işlemi olduğundan configurasyona göre değişir.
Batch işlem yapılıyorsa blok olarak data alınmalı, insert edilmeli,daha sonra commit edilmeli. Database crash olması ihtimaline karşı nerde kalındığını bilmek için bir kolonda işlendi işlenmedi bilgisi tutulabilir.
Rollback Ne Yapar?
Rollback yapılmadan zaten database gerekli değişiklikleri arkaplanda yapmıştır.
-          Rollback segment kayıtları SGA’da oluşturulmuştur.
-          Değişen datablockler SGAda oluşturulmuştur.
-          Buffer redo oluşturlmuştur.
-          Yukarıdaki 3 işlemin büyüklüğüne bağlı olarak diske flush edilmiş olabilir.
-          Kilitler elde edilmiştir.
Rollback yapıldıktan sonra
-          Rollback segmentindeki data okunur.
-          Yapılan işlemin tersi yapılır (insert edildiyse,delete işlemi vb..)
-          Kilitler serbest bırakılır.
-          Bütün değişiklikler geri alınmış olur.
Rollback işlemi biraz daha farklı ve maliyetlidir. 

Locking and Concurrency

En zoru, çok kullanıcılı databaselerde database- driven uygulamaların aynı anda erişimin sağlanabilmesi ve aynı zamanda kullanıcıların tutarlı veriler üzerende işlem yapabilmesidir. Locking ve concurency kontrolü işte bu zor olanı gerçeklemektedir.
Lock
Çok kullanıcı tarafından paylaşılan kaynaklara, eş zamanlı erişimi ve aynı zamanda kullanıcının veri bütünlüğü ile tutarlı bir dataya erişmesini sağlayan mekanizmadır. Genel nesne tipleri locklardan etkilenir(tablo ve satırlar, structure ve data ). Oracle datayı datayı satır bazında kilitler. Yani; concurrency kısaca pek cok kullanıcının aynı anda aynı dataya ulaşabilmesi durumu, consistency de her bir kullanıcının kendisinin ya da bir başka kullanıcının transaction ı aynı anda çalışsa bile tutarlı bir data setine sahip olabilmesi şeklinde özetlenebilir…
Isolation Levels
Uygulanma durumlarına göre farklı sonuçlar doğurabilirler.
Dirty Read: Commit edilmemiş data demektir. Oracle dirty datanın okunmasına izin vermez. Başka bir kullanıcı tarafından read yapıldığında en son commit edilmiş hali okunur. constraint, foreign key yok.
Non-repeatable Read: t1 anında bir satırı okuduğumuzda aldığımız veri ile t2 anında okuduğumuz veri aynı olmayabilir. Update görmüş, silinmiş vb olabilir.
Phantom Reads: Transaction A where sözcüğüyle bir select çalıştırdıktan sonra, B Transaction'ı where şartını sağlayan bir insert yaparsa, A aynı sorguyu tekrar çalıştırdığında farklı sonuç alacaktır.
Isolation level, Oracle’ın sql statementları nasıl consistency işlemi yapacağını ve hangi lockun kullanılacağının bilgisidir.
  Read Uncommitted
  Read Committed (Default)
  Non-Repeatable
  Serializable Transactions
  Read-only
Oracle; Read Commited (ki bu default değerdir),  Serializable Transactions , Read-Only Transactionsları desteklemektedir.
Read uncommited: Dirty read yapılmasını sağlar. Oracle buna izin vermez.
Read Commited: Her bir sorgu çalıştırıldığında o ana kadar commit edilmiş data bilgileri okunur. Dirty read yapılmaz.
Serializable Transactions: Read Committeda ek olarak, kendi içinde yaptığı INSERT,UPDATE ve DELETE statementlarına da izin verir.
Read-Only : Read Committed gibidir ama INSERT, UPDATE ve DELETE işlemleri yapılmaz. Sadece commit edilmiş datadır.



Hiçbir selectte bekleme yapılmaz. Readler serbesttir. Write yapan read yapanı beklemez.
Repeateable Read: Oracle transactionun başladığı anı tuttuğu için herhangi bir ana geri dönülebilir. Roll-back etkilidir. Aslında Flashback de budur.


Transaction Level’ın set edilmesi;
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
SET TRANSACTION ISOLATION LEVEL READ ONLY;
Session Level’ın set edilmesi;
ALTER SESSION SET ISOLATION_LEVEL READ COMMITTED;
ALTER SESSION SET ISOLATION_LEVEL SERIALIZABLE;
ALTER SESSION SET ISOLATION_LEVEL READ ONLY;
Oracle Lock Duration:
Tüm Lock’lar, transaction deyimleri tarafından elde edilir ve transaction süresince tutulur. Commit ya da rollback yapılana kadar locklar saklı tutulur. Ayrıca, Oracle her savepointten sonra lock bırakır.
Oracle Lock Mode:
  Exclusive Lock Mode: Değiştirme anında kullanılan locktur. Kimse insert yapamaz.
 Share Lock Mode: İki kullanıcı aynı anda bir datayı exclusive lock üzerine koyamaz, değiştirilemez. Read edilebilir.
Oracle Lock Tipleri
  DML locks (data locks)
  DDL locks (dictionary locks)
  Oracle Internal Locks/Latches
  Oracle Distributed Locks
  Oracle Parallel Cache Management Locks
DML Lock (Update, Insert vb..): işlem yapılacak olan satırı ya da satırları kilitler.
DDL Lock (Create , Alter, Drop vb..): nesnelerin yeniden tanımlanmasını engeller.
TX – (Transaction) Locks: Row bazında attribute olarak tutar. Commit ya da rollback yapılana kadar lock kalır. Bir tür kuyruk yapısına sahiptir. Transaction bitene kadar diğer sessionlar bekler. Normal Select işlemlerinde TX kullanılmaz. Değiştirilen ya da select for update yapılan her bir satır tx locku ile kilitlenir.
TM – (DML Enqueue) Locks:Tablo içeriği değiştirilirken, başka kullanıcılar tarafından yapısının değiştirilmemesi (alter, drop uygulanmaması) için kullanılan locktur.
  V$TRANSACTION, her aktif transaction için entry içerir.
  V$SESSION, aktif sessionları gösterir.
  V$LOCK, anlık kilitleri gösterir.
SQL sorgusu ile manual olarak kilitlenebilir. (bütün segment page loglanmaz, row bazındadır.)
SELECT...FOR UPDATE
LOCK TABLE IN EXCLUSIVE MODE
DBMS_LOCK paketi kullanılarak kilit yaratılabilir.
DBMS_LOCK
DeadLock
Kaynağı paylaşma durumu oldugunda karşımıza çıkabilecek durumlardan en basta geleni belki de deadlock hatası alma durumudur. Deadlock aynı kaynağı paylaşan 2 ya da daha fazla transaction ın birbirinin işinin bitmesini beklemesi olarak özetlenebilir.



A anında her 2 transaction da işlemleri gerçekleştirir. T1 anında empno = 1000 olan satırı, T2 anında ise empno = 2000 olan satırı kilitlerve işlemi gerçekleştirir. B anında T1 empno = 2000, T2 de empno = 1000 olan kaydı update etmek için lock mekanizmasını devreye sokar. Ancak bu durumda A anındaki işlemden sonra commit ya da rollback yapılmadıgı için sistem her 2 transaction için lock mekanizmasını o satırlar üzerinden kaldırmamıştır. Bu sebeble B anında T1 ve T2 birbirini beklemeye baslayacaklardır. Oracle deadlock durumunu otomatik olarak fark eder, tespit eden transaction ın tarafında rollback çalıştırır ve bir mesaj ile durum kullanıcıya bildirilir. 


Bahar Gezici

Kaynak : http://www.bahargezici.com/category/Oracle.aspx