10 Ağustos 2010 Salı

11g: Yeni Özellik (Interval Partitioning)

Merhaba,

Oracle'ın Enterprise sürümü ile satın alınabilen ve 10g ile birlikte hayatımıza giren Partitioning'in yeni bir özelliğinden bahsedeceğim, "Interval Partitioning". Aslında partitioning konusu altındaki en ciddi geliştirme diyebilirim zira partitioning ile uğraşan kişilerin zaman zaman aldığı klasik hatalardan, sürekli partition yaratmaktan ve silme zahmetinden bizi kurtarıyor.

Bir range partition yaratmanın script'ini inceleyelim;

create table sales6
(
sales_id number,
sales_dt date
)
partition by range (sales_dt)
(
partition p0701 values less than (to_date('2007-02-01','yyyy-mm-dd')),
partition p0702 values less than (to_date('2007-03-01','yyyy-mm-dd'))
);

Yukarıda yarattığımız partition'lar Ocak ve Şubat aylarına aittir. Peki bu tabloya Mart ayına ait bir veri girmeye çalıştığımız zaman ne olacak? Aşağıdaki hatayı alacaksınız;

ORA-14400: inserted partition key does not map to any partition

Bu hatayı aldınız çünkü girmek istediğiniz veriyi kapsamakta olan bir partition, geçerli olan tabloda bulunmamaktadır. Bu veriyi eğer bu tabloya girmek istiyorsanız Mart ayına ait bir partition yaratmak zorundasınız. Aksi halde girmeye çalıştığınız veriyi, ilgili tabloya işlemenizin bir imkanı bulunmamakta. Şimdi size şu soruyu yöneltmek istiyorum. Partition ekleme işini sizin için Oracle yapsa, çok iyi olmaz mıydı? İşte 11g ile gelen partitioning özelliklerinden birisi de budur. Oracle eklemesi gerektiğini algılar ve ilgili tabloya partition'ı ekler. Interval Partitioned

create table sales6
(
sales_id number,
sales_dt date
)
partition by range (sales_dt)
interval (numtoyminterval(1,'MONTH'))

(
partition p0701 values less than (to_date('2007-02-01','yyyy-mm-dd'))
);

Yukarıdaki tabloyu yarattık ve tablomuzda olmayan bir partition'a ait veriyi girmeye çalıştık. Normal şartlarda (interval yazmadığımız zaman) bildiğiniz gibi hata almamız gerekiyordu ancak;

SQL> insert into sales6 values (1,'01-jun-07');

1 row created.

Oracle istediğimiz veriyi işledi ve hata vermeden! Peki işlediğimiz veri nereye gitti? Oracle'ın bu veriyi bizim yarattığımız Ocak partition'ına eklemesine imkan yok. Lütfen aşağıdaki çıktıyı inceleyin;

SQL> select partition_name, high_value
2 from user_tab_partitions
3 where table_name = 'SALES6'
PARTITION_NAME HIGH_VALUE
----------------------------------------------------------------
P0701 TO_DATE(' 2007-02-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
SYS_P41 TO_DATE(' 2007-07-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA

Haziran'a ait partition Oracle tarafından otomatik olarak yaratıldı ve veri işlememize engel bir durum oluşmasını ortadan kaldırdı. Partition'a verilen isim de yine Oracle tarafından otomatik olarak şeçildi.

Yarattığımız bu partition'ları farklı tablespace'lerde saklamak istersek eğer aşağıdaki sorguyu koşabiliriz;

interval (numtoyminterval(1,'MONTH'))
store in (TS1,TS2,TS3)

TS1, TS2 ve TS3 arasında "round robin" adı verilen ortak bir paylaşım sağlanmaktadır.

"Interval Partitioning" özelliğine sahip bir tablo yaratıldığı zaman inceleyebileceğiniz data dictionary görüntüsü DBA_PART_TABLES olacaktır. 10g ile 11g arasında bu görüntü bazında farklılıklar bulunmaktadır. Örneğin 10g'de partitioning olmadığı için INTERVAL diye bir kolon bulunmuyordu. Ancak 11g'de bu özellik eklendiği için DBA_PART_TABLES görüntüsü de değiştirildi.

Burada gelebilecek en olası soru şudur; "Interval değerini değiştirebilir miyiz? Değiştirmek için ne yapmamız lazım?" Evet, interval değiştirebilirsiniz. Aylık değil, örneğin yıllık hale de getirebilirsiniz ve Oracle partition'ları bu şekilde yaratmaya başlayacaktır. Bakınız;

SQL> alter table mypart2 SET INTERVAL (NUMTOYMINTERVAL(1,'YEAR');

Son yönlenecek bir soru ise "interval partitioning'i iptal edebilir miyiz?" Evet, edebilirsiniz zira interval partitioning ile ilgili birkaç "logging" problemi olduğunu duymuştum. Bir örnekte ilgili tablo ve üzerinde partition'lar, indeks'ler nologging olarak yaratılmış iken, interval partitioning'in otomatik olarak yarattığı partition'lar logging oluyordu. İlginç ancak bu şekilde davranmaması gerekiyor. Bu durumda geçici çözüm olarak interval partitioning kapatılabilir ve yerine elle yapılandırma devreye alınabilir;

SQL> alter table mypart2 SET INTERVAL ();

"Interval Partitioning" dışında eklenmiş birkaç özel partitioning türü daha bulunmaktadır ancak bana göre en kıymetlisi ve en yapılmış en büyük geliştirme budur. Birçok insanı partition'ların map etmemesi ile boğuşurken görmüştüm, bu özellik, bu güreşe bir son verecektir, vermelidir zira bir miktar masrafı olacaktır partitioning'in :)

İyi çalışmalar,

Ogan

Hiç yorum yok:

Takip et: @oganozdogan