MVCC(Multiversion Concurrency Control) Nedir, Nasıl Çalışır?

MVCC (Multi Version Concurrent Control), veri tabanına eşzamanlı erişim sağlamak için veritabanı yönetim sistemleri tarafından kullanılan eşzamanlılık kontrol yöntemidir, yani MVCC postgresql veri tabanında eş zamanlı olarak okuma ve yazma işlemlerinin sorunsuz yapılabilmesi adına geliştirilen bir modeldir. Aslında amaç basit veritabanında read yapanlar write yapanları engeleyemesin, yazma yapanlarda okuma yapanları engeleyemesin.  Bu teknik Postgres’e özgü değildir Oracle, Berkeley DB, CouchDB vb veritabanları bir tür MVCC’yi uygularlar.

Eşzamanlılık kontrolü olmadan, bir transaction yazarken aynı anda başka bir transaction veriyi okursa, okuyucunun yarı yazılı veya tutarsız bir veri parçası görmesi mümkündür. Örneğin, iki banka hesabı arasında bir banka havalesi yaparken, bir okuyucu, para orijinal hesaptan çekildiğinde ve hedef hesaba yatırılmadan önce bankadaki total bakiyeyi okursa, paranın hesaptan kaybolduğunu düşünür.

İzolasyon, verilere eşzamanlı erişimlerde garantiler sağlayan özelliktir. İzolasyon, eşzamanlılık kontrol protokolü aracılığıyla gerçekleştirilir. İzolosyanu sağlamanın en basit yoluRead/Write locks, Two-Phase Locking gibi lock mekanizmalarıdır ancak lock contentiona(çekişme) neden olur ve contention ölçeklenebilirliği etkiler. Bu nedenle, veritabanı araştırmacıları, locklamayı minimuma indirmeye çalışan farklı bir Eşzamanlılık Kontrolü modeli geliştirdiler, böylece:

  • Read yapanlar, write yapanları engellemez
  • Write yapanlar read yapanları engellemez

(devamı..)

 66 total views


PostgreSQL’de Write Ahead Logging (WAL) Kavramı

Write Ahead Logging (WAL), veri bütünlüğünü(data integrity) sağlamaya yönelik standart bir yöntemdir. Postgresql, üzerlerinde yapılan, insert/update/delete işlemlerini, bilgilerin asıl tutulduğu diskteki Data Page’lere yazmanın yanında Transaction Log adı verilen log dosyalarına da yazarlar. Hatta verilerin  tutulduğu data page’den önce transaction log’u diske yazar, sonrasında ihtiyaca göre data page’e yazar. Hatta commit edilen uygulama başarılı bir şekilde Commit edildi bilgisini Transcation Log dosyası diske yazıldığında verirler, data Page’lere diske yazılmasını beklemezler. Transaction Log’lar ardışıl disk Page’lerinde oldukları için onların diske yazılması muhtemelen dağınık durumda bulunan Data Page’lerin diske yazılmasından daha hızlı olacaktır.

NOT : PostgreSQL performans için Atomicity ve Durability’den taviz  vermek isteyenlere özel Transcation Log’ların diske yazılma işleminin Asenkron yapılmasına da olanak tanır. Bu durumda Postgresql, Transaction Log’un diske yazılmasını beklemeden Transaction’ın başarılı olduğunu uygulamaya bildirir ancak tam bu sırada sunucu çökmesi durumunda veri kaybı yaşanabilir.

Transaction log, veritabanının önemli bir parçasıdır, çünkü veritabanı yönetim sisteminin bir sistem arızası meydana geldiğinde bile herhangi bir veriyi kaybetmemesi gerekir. Elektrik kesintisi veya sunucu çökmesine neden olan başka bir sunucu arızası gibi arızalar nedeniyle hiçbir verinin kaybolmamasını sağlamak için bir veritabanı sistemindeki tüm değişikliklerin ve eylemlerin bir geçmiş logudur. Log, halihazırda yürütülen her transaction hakkında yeterli bilgi içerdiğinden, veritabanı sunucusunun, sunucu çökmesi durumunda transaction log’daki değişiklikleri ve eylemleri yeniden çalıştırarak veritabanı clusterı kurtarabilmesi gerekir. Veri tabanında transaction log kayıtlarının tutulmadığı durumu düşündüğümüzde, shared buffer poolda değiştirilmiş ama diske henüz değişikliklerin kalıcı olarak yazılmadığı durumlarda bir kesinti veya veri tabanı kapanması olduğunda transactionların tabloya eklediği veriler kaybedilir.

NOT : Bu arada, crash durumunda recovery işleminin nasıl yapıldığına delecek olursak; Her bir checkpoint işleminden sonra transaction log dosyası sıfırlanır ve checkpoint ile ilgili bilgiler pg_control dosyasına yazılır, recovery işlemi yapılacağında sunucu öncelikle pg_control dosyasını ve checkpoint kaydını okur ve checkpoint kaydından sonraki transactionları REDO işleminden geçirir yani wal dosyalarından okur. pg_controldata ile controlfile’ın içine baktığımızda yukarıdada yazdığım gibi en sonki checkpointin LSN yazacaktır.

pg_controldata
(devamı..)

 98 total views


PostgreSQL’de Vacuum

VACUUM, dead tuple ların bulunduğu depolama alanını geri kazanır. Öncelikle Postgres üzerinde bir tabloda Update veya Delete çalıştırdığımızda neler olduğuyla başlayalım. DELETE işlemleri gerçekleştirildiğinde, verilerin bulunduğu tupleları fiziksel olarak silmek yerine mevcut tuple’ı DEAD olarak işaretler. Benzer şekilde, GÜNCELLEME işlemi gerçekleştirildiğinde, karşılık gelen mevcut tuple’ı DEAD olarak işaretler ve yeni bir tuple ekler.(Aslında Update = Hide/Unvisible + Insert demektir.)

Bu nedenle, her bir DELETE ve UPDATE komutu, asla kullanılmayacak olan bir DEAD tuple ile sonuçlanacaktır. Bu dead tuple lar, veriler aynı veya daha az sayıda olsa bile gereksiz fazladan alan kullanımına yol açacaktır.

İşte vacuum DEAD tuple ile ilgilenmeyi sağlayan bakım sürecidir. Vacuum işlemi sequential scan sırasında okunan tuple sayısını azaltacağı için okuma işlemlerinde de hızlanmaya sebep olacaktır. Sequential scan sıralı okuma işlemidir ve dead tuple’ları atlamaz. Dolayısı ile dead tuple’ların temizlenmesi daha az satır okunması anlamına gelir.

Vacuum, tüm tabloların taranmasını içerdiğinden, maliyetli bir işlemdir. 8.4 (2009) sürümünde, Visibility Map (VM), dead tupleların işaretlenme verimliliğini artırmak için tanıtıldı. 9.6 (2016) sürümünde, VM geliştirilerek freeze prosesi iyileştirildi.

Visibility Map

VM’in temel konsepti basittir. Her tablonun, tablo dosyasındaki her page’in görünürlüğünü tutan ayrı bir görünürlük haritası vardır. Pagelerin görünürlüğü, her page’de dead tuple olup olmadığını belirler. Vacuum, dead tuple içermeyen pageleri atlayabilir. Aşağıdaki şekildeki gibi bir tablomuz olduğunu düşünelim; Tablonun üç page’den oluştuğunu ve 0. ve 2. sayfaların dead tuplelar içerdiğini ve 1. sayfanın olmadığını varsayalım. Bu tablonun görünürüülük haritası(vm), hangi pagelerin dead tuplelar içerdiği hakkında bilgi içerir. Bu durumda, vacuum, VM’nin bilgilerine başvurarak 1. sayfayı atlar.

Postgresql Vacuum

Her VM bir veya daha fazla 8 KB page’den oluşur ve bu dosya ‘vm’ sonekiyle saklanır. Örnek olarak, FSM (18751_fsm) ve VM (18751_vm) dosyaları ile relfilenode 18751 olan bir tablo dosyası aşağıda gösterilmiştir.

 $ cd $PGDATA
$ ls -la base/16384/18751*
-rw------- 1 postgres postgres  8192 Apr 21 10:21 base/16384/18751
-rw------- 1 postgres postgres 24576 Apr 21 10:18 base/16384/18751_fsm
-rw------- 1 postgres postgres  8192 Apr 21 10:18 base/16384/18751_vm

Free Space Map

Free space map, her veri dosyasının boş alanı hakkındaki bilgileri depolar. Yukarıdada gördüğümüz gibi anadosyaya paralel ‘fsm’ soneki ile biten dosyada saklanır bilgiler. FSM’nin amacı yeterli alan içeren bir page’i hızlı bir şekilde bulmaktır veya böyle bir page’in bulunmadığını veri dosyasının bir page kadar büyütülmesi gerektiğini belirlemek içindir.

Freeze Tuple

Postgresql’deki her yazma işlemi veya bağımsız ifadeye benzersiz bir transaction id (veya XID) atanır. Bu XID, diğer eşzamanlı kullanıcıların transactionla ilişkili satır değişikliklerini görebileceğini belirleyerek öncelik görünürlüğünü(precedence visibility) belirler. Salt okunur işlemlere XID atanmaz. Bu XID’ler, depolamadaki her satıra xmin ve xmax biçiminde damgalanır ve satırı “görebilen” minimum ve maksimum eşzamanlı transactionları belirtir. Bunları row header lerine yerleştirerek, Postgresql’in eşzamanlılık(concurrency) yeteneklerini destekleyen transaction çakışması çözümünü merkezileştiriyor.

Ancak, XID’lerle ilgili bir sorun var: bunlar dört baytlık bir tamsayıdır. Bu, 2,1 milyar işlemden sonra başa sarmaları gerektiği anlamına gelir. Ve XID sayacı başa sardığında, eski XID’lerin tüm eski row headerlarından çıkarılması gerekir. Bu, XID’nin xmin ve xmax’tan kaldırılması ve özel RelFrozenXID değeriyle değiştirilmesi anlamına gelir; bu, herkesin görebileceği çok eski bir transactionı belirtir. (devamı..)

 98 total views


PostgreSQL’de Foreign Data Wrapper (FDW)

2003 yılında, SQL standardına SQL Management of External Data (SQL/MED) adı verilen uzak verilere erişim özelliği eklendi. Bu özellik, 9.1 sürümünden beri SQL / MED’in bir bölümünü gerçekleştirmek için PostgreSQL tarafından geliştirilmektedir. SQL / MED’de, uzak sunucudaki bir tabloya foreign tablo denir. PostgreSQL Foreign Data Wrapper (FDW), local tablolara benzer foreign tabloları yönetmek için SQL / MED kullanırlar.

PostgreSQL Foreign Data Wrapper

Yani kısaca FDW, Postgres içerisinden harici/uzak/farklı veri sistemlerine doğrudan bağlanmanızı, sorgulamanızı sağlayan tercümanlardır diyebiliriz. Bir eklenti olarak kurulan FDW ile sadece uzak farklı veritabanı sistemlerine bağlanmak ve veri alabilmenin, sorgu gönderebilmenin yanı sıra aynı zamanda yazma işlemi de yapabilmekteyiz. FWD’yi, farklı veri kaynaklarından verileri normalize ederek merkezi bir veritabanına join sorgular oluşturarak çekmek için ETL aracı olarak da kullanmak da mümkün olmakla birlikte, belki en performanslı araç olmayabilir ama şurası kesin ki en hızlı yöntemdir.

FWD eklentilerinin bir kısmı Postgres üzerinde hazır olarak gelirken, bazıları açık kaynaklı paketin içine dahil edilemezler ve ayrıca indirilmelidirler. Buna örnek MySQL FWD’yi aktif hale getirmeden önce indirip kurmanız gerekir ki bu çok basit bir işlemdir. Bazı FWD Eklentilerine kısaca göz atalım:

  • Postgres FDW : Şüphesiz en kolay ve hızlı giriş yapabileceğimiz FWD, Postgres’in kaynak olarak farklı bir host üzerinde olan yine PostgreSQL veritabanına bağlanmak için kullandığımız Potgres FWD olacak.
  • MySQL FDW : Bu PostgreSQL extensionı MySQL için Foreign Data Wrapper (FDW) uygular.
  • Oracle FDW : oracle_fdw, WHERE koşullarının ve gerekli sütunların pushdown ve kapsamlı EXPLAIN desteği dahil olmak üzere Oracle veritabanlarına kolay ve verimli erişim için Foreign Data Wrapper sağlayan bir PostgreSQL extensionıdır.
  • CSV : File_fdw modülü, sunucunun dosya sistemindeki veri dosyalarına erişmek veya sunucudaki programları çalıştırmak ve çıktılarını okumak için kullanılabilen FDW file_fdw sağlar.
  • Sybase / MS SQL Server
  • BigTable or HBase
  • Cassandra
  • InfluxDB
  • MongoDB :
  • Redis
  • JSON
  • XML
  • pgsql-http
  • RSS
  • www
  • S3
  • Twitter
  • Elasticsearch
  • Hadoop
  • Docker
  • Log Files

(devamı..)

 60 total views,  2 views today


PostgreSQL’de Ayrıcalık (Privilege)

Bir nesne oluşturulduğunda ona bir sahip atanır. Sahip, normalde oluşturma(create) sorgusunu yürüten roldür. Çoğu nesne türü için, ilk durum, yalnızca sahibin (veya bir süper kullanıcının) nesne ile her şeyi yapabilmesidir. Diğer rollerin onu kullanmasına izin vermek için, ayrıcalıkların(privilege lerin) verilmesi gerekir.

Farklı ayrıcalık türleri vardır; SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER, CREATE, CONNECT, TEMPORARY, EXECUTE ve USAGE. Belirli bir nesne için geçerli olan ayrıcalıklar, nesnenin türüne (tablo, işlev, vb.) bağlı olarak değişir.

Bir nesneyi değiştirme veya silme hakkı her zaman yalnızca sahibinin ayrıcalığına sahiptir. Nesne sahibinin özel ayrıcalıkları (DROP,GRANT,REVOKE vb.) her zaman sahibine aittir başkasına verilemez veya veya iptal edilemez. Ancak nesne için istenirse ALTER komutu ile sahibi değiştirilebilir, örneğin;

 ALTER TABLE table_name OWNER TO new_owner; 

Privilege leri atamak için GRANT komutu kullanılır. Örneğin, mustafa mevcut bir rolse ve hesaplar mevcut bir tablodaysa, tabloyu güncelleme yetkisi şunla verilebilir;

GRANT UPDATE ON hesaplar TO mustafa; 

ALL sözcüğünü kullanırsak bu nesne ile ilgili tüm ayrıcalıkları role verir.

GRANT ALL ON hesaplar TO mustafa; 

PUBLIC özel “rol” adı, sistemdeki her role bir ayrıcalık tanımak için kullanılabilir. Ayrıca, bir veritabanının birçok kullanıcısı olduğunda ayrıcalıkların yönetilmesine yardımcı olmak için “grup” rolleri ayarlanabilir. Aşağıdaki örnekle hesaplar tablosu için bütün rol lere SELECT yetkilesi verilmiştir.

GRANT SELECT ON hesaplar TO PUBLIC; 

Ayrıcalığı iptal etmek yani almak için aşağıdaki gibi REVOKE kelimesini kullanırız;

REVOKE SELECT ON hesaplar FROM PUBLIC; 

Normalde sadece nesnenin sahibi veya superuser nesne üzerinde ayrıcalıklar verebilir veya iptal edebilir. Ancak, istenirse bunu diğerlerine de verme hakkı veren “with grant option” bir ayrıcalık vermek mümkündür.

Mevcut ayrıcalıklar şunlardır:

  • SELECT : Nesnenin herhangi bir sütunundan veya belirli sütunlarından veri okumaya izin verir. COPY TO kullanımınada izin verir. SELECT yetkisi UPDATE ve DELETE içinde gereklidir.
  • INSERT : Yeni bir satırın bir nesneye eklenmesine izin verir. COPY FROM kullanımınada izin verir.
  • UPDATE : Bu yetki ile verilerin güncellemesi yetkisi kazanmış oluruz.
  • DELETE : Verilerin silinmesine izin verir.
  • TRUNCATE : Nesne üzerinde truncate’e izin verir. Yani nesneyi boşaltmaya izinli oluruz.
  • REFERENCES : Bir tabloya veya bir tablonun belirli sütunlarına referans foreign key constraint oluşturulmasına izin verir.
  • TRIGGER : Tablo veya view üzerinde trigger oluşturmaya izin verir.
  • CREATE : Veritabanları için, veritabanı içerisinde yeni schema oluşturulmasına izin verir. Schemalar için, schema içinde yeni nesnelerin oluşturulmasına izin verir. Tablespace için tablolar, indeksler ve geçici dosyaların tablespace içinde oluşturulmasına izin verir
  • CONNECT : Yetki alan kişinin veritabanına bağlanmasına izin verir. Bu ayrıcalık bağlantı başlangıcında kontrol edilir (pg_hba.conf tarafından getirilen kısıtlamaların kontrol edilmesine ek olarak).
  • TEMPORARY : Veritabanı kullanılırken geçici tabloların oluşturulmasına izin verir.
  • EXECUTE : Fonksiyonda kullanılan herhangi bir operatörün kullanımı dahil olmak üzere fonksiyon veya prosedürü çalıştırmaya izin verir.
  • USAGE : Şemalar için, şemada bulunan nesnelere erişime izin verir. Prosedürel diller için, o dilde işlevlerin oluşturulması için dilin kullanılmasına izin verir. Foreign-data wrapper kullanılarak yeni sunucuların oluşturulmasına izin verir. Sequence için currval ve nextval işlevlerinin kullanımına izin verir.

(devamı..)

 36 total views


Postgresql’de Schema Kavramı

Bir önceki yazımda PostgreSQL’de schema kavramından ve obje hiyerarşi’sinden bahsetmiştim. Bu yazımızda schema kavramını detaylandıracağız. Önceki yazıdada bahsettiğim gibi PostgreSQL veritabanı cluster, bir veya daha fazla veritabanı içerebilir. Roller ve diğer birkaç nesne türü, tüm cluster genelinde paylaşılır yani global nesnelerdir. Sunucuya ise client bağlantısı, yalnızca bağlantı isteğinde, belirtilen tek bir veritabanındaki verilere erişebilir.

Veritabanı ise tabloları ve objeleri içeren bir veya daha fazla schema’ya sahip olabilir, yani her schema yalnızca bir veri tabanına ait olabilirken  bir veri tabanında birden çok schema yaratılabilir. Farklı isimdeki iki schema, aynı isimde objeler içerebilir. Aslında burada schema kavramı veritabanı objeleri için namespace anlamına gelmektedir. Veri tabanı objesine erişmek istendiği zaman schema_name.object_name isimlendirmesi kullanılır. Veritabanlarından farklı olarak, schemalar katı bir şekilde ayrılmaz: bir kullanıcı, yetkileri varsa, bağlı oldukları veritabanındaki schemaların herhangi birindeki objelere erişebilir.  Schemaları kullanmak istemenin birkaç nedeni vardır;

  • Birçok kullanıcının birbirine müdahale etmeden, veritabanını kullanmasına izin vermek için.
  • Veritabanı objelerini daha yönetilebilir hale getirmek için mantıksal gruplar halinde düzenlemek.
  • Üçüncü taraf uygulamalar, diğer objelerin adlarıyla çakışmaması için ayrı schemalara yerleştirilebilir.
  • Schemalar, işletim sistemi düzeyindeki dizinlere benzer, ancak schemalar iç içe olamaz.

(devamı..)

 36 total views


  • Sertifikasyon



  • Etiketler

  • Topluluklar

                     
                     
  • Copyright © 1996-2010 Mustafa Bektaş Tepe. All rights reserved.
    Türkçeleştirme Blogizma | AltyapıWordPress
    Takip Et

    Her yeni yazı için posta kutunuza gönderim alın.

    Diğer takipçilere katılın: