Blog

MySQL ve PostgreSQL Isolation Level İncelemesi

Merhaba arkadaşlar,

Sizlere PostgreSQL ve MySQL’de isolation level  ( Read Uncommitted, Read Committed, Repeatable Read, Serializable ) üzerine yaptığım araştırma sonuçları hakkında bilgiler vereceğim. Yazımda bu veritabanlarının farklı senaryolarda verileri kullanıcılara nasıl yansıttığını anlatacağım. Isolation leveller hakkında internette yeterince bilgi  olduğu için bunlar hakkında detaylara inmeyeceğim. Isolation leveller transaction işlemlerinde çok önemli. Bir proje geliştirdiğimizde veritabanımızın farklı senaryolarda nasıl tepkiler verdiğini bilmek, veri güvenliği ve kullanıcının hangi veri üzerinde işlem yaptığını bilmesi çok önemli. Birazdan size göstereceğim 3 farklı senaryoda göreceksiniz ki kullanıcı acaba hangi değere sahip veri üzerinde işlem yapıyor?

Senaryolarımız resimde görüldüğü gibi;

Senaryo

Gördüğünüz gibi 3 farklı senaryoda, farklı noktalarda bu iki veritabanı MySQL ve PostgreSQL’in farklı isolation level için nasıl davrandığını göreceğiz.

PostgreSQL için  öncelikle iki farklı terminalden giriş yapıyoruz.

Kullandığım komutlar ;

PostgreSQL’e root kullanıcı olarak girmek için :

$ sudo -u postgres psql

Giriş yaptıktan sonra herhangi bir isimle veritabanı oluşturuyoruz. Ben daha önceden oluşturmuştum. Bu veritabanına da student isimli, student_id ve student_name isiminde alanlara sahip bir tablo oluşturdum.

Daha önceden oluşturduğum students veritabanına bağlanmak için :

postgres=# \connect students

Veritabanında bulunan tabloları görüntülemek için :

students=# \dt

Tabloda bulunan verileri görüntülemek için :

students=# SELECT * FROM student;

Ekran görüntüsü :

Terminal Görüntüsü

Güncel transaction isolation level’i öğrenmek için :

students=# select current_setting('transaction_isolation'); 

Oturumdaki transaction isolation level’i değiştirmek için :

students=# SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL SERIALIZABLE;

Sadece bir transaction da isolation level’i değiştirmek için :

students=# SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;

A noktası için senaryomuzu uygulayabilmek için iki terminalde isolation levelleri aynı olarak ayarladıktan sonra iki terminalde BEGIN komutu ile transaction başlatıyoruz. Her iki oturum için transaction başlattıktan sonra   1. senaryo daki gibi  oturumun birinde güncelleme yapıyoruz ve ardından diğerinde okuma yapıyoruz. Aşşağıdaki resimde gördüğünüz gibi read committed için bir transaction da güncelleme yaptıktan sonra diğer transaction da okuma yaptığınızda transaction sonlandırılmadığı için eski değeri görüyoruz.

Terminal Görüntüsü

Isolation level güncelleme :

4

Aynı senaryo read uncommitted için de okuma yapıldığında  read committed ile aynı sonuç elde edilir. Fakat aynı işlem MySQL de yapıldığında read uncommitted için güncellenmiş veri okunur. Aşşağıdaki şekilde terminaller alt alta yer almaktadır. Daha önce anlattığım gibi her ikisinde önce transactionlar BEGIN komutu ile başlatılır  daha sonra altaki terminalden güncelleme yapılır. Bu işlemden sonra üstteki terminalden okuma yapılır.

Terminal Görüntüsü

Bu şekilde veritabanımızın farklı senaryolarda nasıl davrandığını test edebiliriz. Bu işlem MySQL’de de aynı şekilde terminalden yapılabiliyor. MySQL için isolation’ı öğrenme ve değiştirme komutları farklı. Ben bu testleri daha önceden yapmıştım.   Sonuçları alt tarafta paylaştım.

                  |   PostgreSQL                |    MySQL
---------------------------------------------------------------------------------------------------------
A Noktası
READ UNCOMMITTED  |  Eski değeri okur           | Yeni değeri okur  
READ COMMITTED    |  Eski değeri okur           | Eski değeri okur  
REPEATABLE READ   |  Eski değeri okur           | Yeni değeri okur  
SERIALIZABLE      |  Eski değeri okur           | Transaction 2 için bekler ve bittiğinde eski değeri okur
	
B Noktası	              
READ UNCOMMITTED  |  Veri güncellenir	        | Veri güncellenir 
READ COMMITTED    |  Veri güncellenir	        | Veri güncellenir 
REPEATABLE READ   |  Veri güncellenir	        | Veri güncellenir 
SERIALIZABLE      |  Veri güncellenir	        | Transaction 1 için bekler 
	
C Noktası	              
READ UNCOMMITTED  |  Eski değeri okur	        | Yeni değeri okur 
READ COMMITTED    |  Eski değeri okur	        | Eski değeri okur  
REPEATABLE READ   |  Eski değeri okur	        | Eski değeri okur  
SERIALIZABLE      |  Eski değeri okur	        | Eski değeri okur  
	
D Noktası	              
READ UNCOMMITTED  |  Yeni değeri okur	        | Yeni değeri okur   
READ COMMITTED    |  Yeni değeri okur	        | Yeni değeri okur   
REPEATABLE READ   |  Eski değeri okur	        | Eski değeri okur   
SERIALIZABLE      |  Eski değeri okur 	        | Eski değeri okur  
	
E Noktası	              
READ UNCOMMITTED  |  Verileri gösterir	        | Verileri gösterir 
READ COMMITTED    |  Verileri gösterir	        | Verileri gösterir 
REPEATABLE READ   |  Verileri gösterir	        | Verileri gösterir 
SERIALIZABLE      |  Verileri gösterir	        | Verileri gösterir
	
F Noktası	              
READ UNCOMMITTED  |  Veri güncellenir	        | Veri güncellenir  
READ COMMITTED    |  Veri güncellenir	        | Veri güncellenir
REPEATABLE READ   |  Veri güncellenir	        | Veri güncellenir
SERIALIZABLE      |  Veri güncellenir	        | Transaction 2 için bekler 
	
G Noktası	             
READ UNCOMMITTED  |  Transaction 1 için bekler  | Transaction 1 için bekler 
READ COMMITTED    |  Transaction 1 için bekler  | Transaction 1 için bekler 
REPEATABLE READ   |  Transaction 1 için bekler  | Transaction 1 için bekler 
SERIALIZABLE      |  Transaction 1 için bekler  | Execption: ERROR 1213 (40001): Deadlock found when trying to get lock;

Üstteki sonuçlardan gördüğümüz gibi PostgreSQL, MySQL’e göre daha kararlı bir yapıya sahip ve ölüm kilidi (deadlock) durumu oluşmuyor. Benim burda araştırmasını yaptığım  3 farklı senaryo daha değişik biçimlerde verilerin silinmesi gibi durumlar içinde incelemesi yapılabilir.

Teşekkürler..

Kolay gelsin…


Posted

in

by

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *