19 Ocak 2015 Pazartesi

Oracle 12C In-memory Opsiyonu

Oracle 12.1.0.2 sürümüyle yeni gelen özelliklerden birtanesi In-Memory opsiyonudur.Tablo, partition yada diğer database objelerinin memory'de tutulmasını sağlar. SGA içerisinde data alışılageldik row formatında değil, Column based olarak tutulur. Tek database üzerinde verilerimizin hem row hem de in memory opsiyonu sayesinde column based olarak tutulması, bize OLTP işlemlerinin yanısıra Analitik işlemleri de performanslı biçimde yapma avantajı kazandırır. Oracle Exalytics ürününü piyasaya çıkardığı yıllarda timesten adı verilen in-memory database sayesinde raporlama datasını memory'den çekerek BI alanında performans bakımından büyük bir adım atmıştı. Exalyticsin bir engineered system olması sebebiyle maliyeti çok yüksekti. 12C ile gelen in-memory opsiyonu sayesinde raporlama işlemlerimizde OLTP veritabanımızı kullanırken Performans bakımından büyük kazanımlar elde etmiş oluyoruz.

In-memory opsiyonu kullanırken DB buffer cachede tutulan data değiştirilmez,SGA içerisinde yeni bir pool'a istenilen data columnar formatta tutulacak şekilde depolanır. In-memory opsiyonuyla, memoryde tutulan objelerin tekrar DBbuffer cache load edilmesi gereksizdir. Bu opsiyonla sıkıştırılmış veri içerisinde arama yapılabiliyor. Column format sıkıştırma işlemlerini çok performanslı yapabildiği gibi, bir değer önemli avantajıda; donanımın uyumlu olması halinde SIMD vector proccessing'i kullanmasıdır.
SIMD vector Proccessing (Single Instraction Proccessing Multiple Data Value) : SIMD destekli işlemcilerde 32 bitlik 1 register, 8bitlik 4 register gibi davranır.

In-memory özelliği ile SGA içerinde önceden varolan buffercahce vb memory alanlarında bir değişiklik olmazken,bu özellik için oracle mimarisine dahil edilen ekstra proces, parametre ve memory alanları mevcuttur. INMEMORY_SIZE parametresini 0'dan farklı bir değere set ettiğimiz zaman bu özellik database'imiz için aktif hale gelmekle birlikte bu parametre, SGA içerisinde memory'e alınacak dataların tutulduğu IN-MEMORY COLUMN STORE alanının size'ını da belirlemiş olur. IMCO(in-memory coordinater) backgorund process'i ise memory'de tutulmasını istediğimi dataları SGA'nın ilgili in-memory column store alanına load eder,her iki dakikada memoryde tutulan datanın refresh edilmesini sağlar, bu processe bağlı SMCO(Space Management Coorinater Process) background processi ve workerlar bulunur.
Datanın memory'e alınması instance restart edildiğinde yada ilgili dataya erişildiğinde yapılabilir. Database instance başlatıldığı sırada memory'e alınmış data diskten tekrar okunarak in-memory column alanına yeniden yüklenmesi gerekir. Rac databaselerde birden fazla instance mevcuttur ve dolayısıyla instance sayısı kadar IMcolumn store alanı olacaktır. Bir tabloyu memory de tutmak istediğimiz zaman default olarak NO DUPLICATE opsiyonuyla tablonun datası instance'lardan sadece birtanesinin IMcolumn store alanında tutulmak üzere memory'e alınır. Bu sayede partition'lı bir tablomuzun bir partition'ını instance 1'de tutarken, diğer partition'ını ise instance 2'de depolanacak şekilde memory alanına alabiliriz. Yada DUPLICATE opsiyonuyla tabloyu memory'e aktarırken tüm instancelardaki IMcolumn store alanına aynı datanın yüklenmesini sağlayabiliriz.

Hangi Datanın memroy'e daha önce alınacağını Priorty özelliğini set ederek belirleyebiliriz. Bir objeyi memory'e almak için ilk önce INMEMORY_SIZE parametresini set ederek bu opsiyonu aktif hale getiriyoruz. Statik bir parametre olduğundan restart ettikten sonra bu değişiklik aktif hale gelecektir. Bu tanımlamayı yaparken SGA boyutuna dikkat etmemiz gerekiyor.
ALTER SYSTEM SET INMEMORY_SIZE=200M SCOPE=SPFILE


Yukarıda gördüğümüz gibi, bu opsiyonu aktif hale getirdikten sonra databasei açtığımızda SGA altında artık In-Memory Area adı altında bir alanımız da bulunuyor.Şu anda bu bellek bölgesinde herhangi bir data store edilmemektedir. Instance startup'ında bu alana istediğimiz obje datasının load edilmesi için PRIORITY özelliğini set etmeliyiz demiştik. PRIORITY seçeneklerine bakacak olursak;
NONE: Hiçbir öncelik tanımlamazsak full scan yapan bir sorgu gelmeden memory'ye alınmayacaktır.
LOW:instance başlatıldığı anda memory'ye yüklenecektir.
MEDIUM:instance başlatıldığı anda memory'ye yüklenecektir.
HIGH:instance başlatıldığı anda memory'ye yüklenecektir.
CRITICAL:instance başlatıldığı anda memory'ye yüklenecektir.  İnstance başlangıcında memorye alınma önceliği tahmin edileceği gibi CRITICAL, HIGH, MEDIUM, LOW şeklindedir

Inmemory opsiyonunu aktif hale getirdikten sonra bir tabloyu nasıl inmemory'e alabileceğimize bakalım. v$im_segments'den memory'deki objeleri sorgulayabiliriz.
SQL> select owner,segment_name,inmemory_size,bytes,bytes_not_populated,populate_status from v$im_segments;
no rows selected

SQL> alter table oe.customers inmemory priority critical;
Table altered.
SQL> select owner,segment_name,inmemory_size,bytes,populate_status from v$im_segments;

OWNER    SEGMENT_NAME   INMEMORY_SIZE BYTES      POPULATE_STATUS
------------
OE                  CUSTOMERS 1179648   131072        COMPLETED
Priorty özelliğini none olarak tanımladığımızda ise tabloya full table scan yapan bir sorgu geldikten sonra tablo memoryye alınır..Burda instance restart edildiği zaman memory sıfırlanacak, tekrar bir sorgu gelemeyene kadar oe.customers tablosu memorye load edilmeyecektir.
SQL> alter table oe.customers inmemory priority none;
Table altered.
SQL> select owner,segment_name,inmemory_size,bytes,bytes_not_populated,populate_status from v$im_segments;
no rows selected

SQL> select * from oe.customers;

SQL> select owner,segment_name,inmemory_size,bytes,populate_status from v$im_segments;

OWNER    SEGMENT_NAME   INMEMORY_SIZE BYTES      POPULATE_STATUS
------------
OE               CUSTOMERS 1179648   131072        COMPLETED

Memoryde tutulan bir objenin priority'sinin ne olduğunu öğrenmek için ise aşağıdaki sorguyu kullanabiliriz.

SQL> SELECT OWNER, SEGMENT_NAME, INMEMORY_PRIORITY, INMEMORY_COMPRESSION FROM V$IM_SEGMENTS;

Bir objenin artık memory'de tutulmasını istemiyorsak  NO INMEMORY sql'ini kullanabiliriz.

SQL> alter table oe.customers  NO INMEMORY;

Memory'de tutulacak datayı table olarak belirleyebildiğimiz gibi,bu seçimi kolon bazında da yapabiliriz. İstediğimiz tablonun sadece tutulmasını istediğimiz kolonları için in-memory özelliğini aktif hale getirebiliriz.Önce ilgili tabloyu memory'ye almamız gerekiyor.

SQL> alter table oe.customers INMEMORY;

 SQL> alter table oe.customers
(CUST_ADDRESS,PHONE_NUMBERS,NLS_LANGUAGE,NLS_TERRITORY,CREDIT_LIMIT,CUST_EMAIL)
 INMEMORY MEMCOMPRESS FOR CAPACITY HIGH (CUSTOMER_ID,CUST_FIRST_NAME,CUST_LAST_NAME)
 INMEMORY MEMCOMPRESS FOR QUERY HIGH (ACCOUNT_MGR_ID,CUST_GEO_LOCATION,DATE_OF_BIRTH)
 NO INMEMORY (MARITAL_STATUS,GENDER,INCOME_LEVEL);

Memory'ye aldığımız tablonun kolonlarını aşağıdaki sorgu ile v$im_column_level'dan sorguladığımız zaman aşağıdaki sonucu elde ediyoruz.

Compression metodlarından bahsedecek olursak;
NO MEMCOMPRESS: Memoryde tutulacak data üzerinde herhangi bir sıkıştırma uygulanmaz
MEMCOMPRESS FOR DML: Datayı DML operasyonları için optimize edecek şekilde sıkıştırır. En az sıkıştırma oranı bu metodda uygulanır.
MEMCOMPRESS FOR QUERY LOW: En iyi query performasını elde edecek şekilde sıkıştırma yapar.Datayı MEMCOPRESS FOR DML'den daha fazla sıkıştırır.
MEMCOMPRESS FOR QUERY HIGH: QUERY LOW'dan daha yüksek performans sağlar. Datayı query lowdan fazla, memcompress for capacity low metodundan daha az bir sıkıştırma oranı ile sıkıştırır.
MEMCOMPRESS FOR CAPACITY LOW: İyi bir query performansına sahip olmasının yanında yüksek bir sıkıştırma oranına da sahiptir. Memcompress For query high'dan fazla, memcompress for capacity high'dan daha az sıkıştırma yapar.
MEMCOMPRESS FOR CAPACITY HIGH: Bu metodda ise en yüksek oranda data sıkıştırması yapılır.

Aşağıdaki sorgu yardımıyla memorydeki tablonun sıkıştırma methodu ve sıkıştırma oranı hakkında bilgi edinebiliriz..

SQL> select segment_name, bytes Disk, inmemory_size, populate_status, inmemory_compression COMPRESSION,  bytes / inmemory_size comp_ratio from v$im_segments;

inmemory_clause_default parametresi IN MEMORY sql'ini kullandığımız zaman default olarak hangi opsiyonlarla bu özelliği aktif hale getireceğimizi belirler. Yani bu parametreyi aşağıdaki gibi set ettiğimizi düşünürsek her bir IN MEMORY cümlesinde default olarak sıkıştırma methodunu query high olarak belirleyecektir..

SQL> alter system set inmemory_clause_default="INMEMORY MEMCOMPRESS FOR QUERY HIGH" ;


12C In-memory opsiyonunun karşılaştırmalı performans incelemesi için ise Gökhan Atıl'ın 12C In-Memory sunumunu bu linkten ineceleyebilirsiniz..


Kaynaklar:
http://docs.oracle.com/database/121/ADMIN/memory.htm#ADMIN00207
Gökhan ATIL 12C IN-MEMORY Sunumu (Troug Ankara Etkinliği - http://www.slideshare.net/gokhanatil/oracle-12c-database-in-memory)
http://oracle-base.com/articles/12c/in-memory-column-store-12cr1.php


0 yorum:

Yorum Gönder