Redefiniton Oracle 9i ile Oracle dünyasına tanıtılan DBMS_REDEFINITION paketidir. DBMS_REDEFINITON paketi production ortamlarda veritabanında kesinti sürelerini nerdeyse sıfır denilecek sürelerde tablo’nun storage parametrelerini degiştirmek,farklı bir tablespace e taşımak veya yeni kolonlar eklemek,silmek ve degiştirmek için kullanılabilir. Örnekler verecek olursak ;

  • Lob alanlı yapılarda basic file’dan secure file a geçmek
  • Kolon eklemek, çıkarmak veya değiştirmek
  • Tabloyu partitionlı yapıya geçirmek
  • Tabloyu reorganize etmek
  • Ve tablodaki bütün storage parameterelerini değiştirirken kullanabiliriz.

DBMS_REDEFINITION paketi aslında arka planda aşağıda resimde gösterilen işlemi yapıyor.

Oracle Redefinition Example

 

 

 

 

 

 

  1. Öncelikle bu paketle tablonun Online redefinition işlemine uygun olup olmadığına bakıyor. Bu kontrolü yaparken bizden primary key veya rowid değerine göre kontrol yaptırmamızı isteyecek.
  2. Bu adımda tablonun hedeflediğmiz halini oluştururuz. Aslında bu biraz Create table as select’e benziyor.
  3. Üçüncü adımda ise ana tablomuzdaki verileri yeni oluşturduğumuz tabloya aktarır.
  4. Bu adımda ise ana tablo ile yeni tablo arasında veri anlamında çok fark var ise istediğimiz zaman bu verilerin senkronozisyonunu sağlar.
  5. Son adımda ise tabloya kısa bir süreliğine erişimi kapatarak verilerin senkronozisyonunu sağlar ve daha sonrasında tabloların isimleri yer değiştirir. Böylece amacımızada ulaşmış oluyoruz.

Aslında bütün resmin kısaca bir defa daha üstünden geçersek hedeflediğimiz tabloyu oluştururuz. Daha sonra DBMS_REDEFINITION paketini kullanarak ana tablodaki veriler yeni tabloya atılır aslında burda yapılan işlem insert table(a,b,c) select a,b,c from table işlemidir, tabi bununla birlikte yeni tablo materialized view e çevrilir ve aynı anda ana tablo için materialized view log olusturup tablomuza gelen insert,delete ve update işlemlerini kayit altina alınır. Daha sonrasında tablolarımızı her senkron etme işlemimizde ise materialized view log kullanılarak refresh (fast refresh) edilir. En sonda tabloların ismi rename yapılarak isim değişikliği yapılır.

Aşağıda yapacağım örnekte Lob alan bulunan tablomda compress özelliğini kullanacağım ve bunu yaparken redefinition kullanacağım için çok az kesintim olacak.

1.  Ana tablomun create scripti aşağıdaki gibidir.

CREATE TABLE "MUSTAFA"."TABLE_1"
(
   "NO"                   NUMBER (15, 5) NOT NULL ENABLE,
   "DATE"                 TIMESTAMP (6),
   "XXX_NUMBER"   VARCHAR2 (25 BYTE),
   "DATA"                 BLOB,
   CONSTRAINT "PK_1" PRIMARY KEY ("NO")
)
TABLESPACE "TEST_SECUREFILE"
LOB ("DATA") STORE AS BASICFILE (TABLESPACE "TEST_SECUREFILE");

2. Tablomuz redefinition yapıp yapmamaya uygun olup olmadığımızı aşağıdaki sorgularla görebiliriz.

2.1. PK üstünden redefinition yapıp yapmamaya uygunluk kontrolü için.

EXEC DBMS_REDEFINITION.CAN_REDEF_TABLE('MUSTAFA', 'TABLE_1',1);

2.2. ROWNUM üstünden redefinition yapıp yapmamaya uygunluk kontrolü için.

EXEC DBMS_REDEFINITION.CAN_REDEF_TABLE('MUSTAFA', 'TABLE_1',2);

NOT : Kontrol sonucu aşağıdaki gibi hata almıyorsak devam edebiliriz.

EXEC DBMS_REDEFINITION.CAN_REDEF_TABLE('MUSTAFA', 'TABLE_2',1)
Error report -
ORA-12089: "MUSTAFA"."TABLE_2" tablosu birincil anahtarsız çevrimiçi yeniden tanımlanamaz
ORA-06512: konum "SYS.DBMS_REDEFINITION", satır 143
ORA-06512: konum "SYS.DBMS_REDEFINITION", satır 1635
ORA-06512: konum satır 1
12089. 00000 - "cannot online redefine table \"%s\".\"%s\" with no primary key"
*Cause: An attempt was made to online redefine a table that does not have
 a primary key defined on it.
*Action: Do not attempt to online redefine a table that does not have a
 primary key defined on it.

NOT : Tablomuz büyükse isteğe bağlı parallelliği açabiliriz.

alter session force parallel dml parallel 20;
alter session force parallel query parallel 20;

3. Yeni tablomuzu orjinal tablodan farklı compress özelliği ekleyerek oluşturuyoruz.

CREATE TABLE "MUSTAFA"."TABLE_2"
(
 "NO" NUMBER (15, 5) NOT NULL ENABLE,
 "DATE" TIMESTAMP (6),
 "XXX_NUMBER" VARCHAR2 (25 BYTE),
 "DATA" BLOB,
 CONSTRAINT "PK_2" PRIMARY KEY ("NO")
)
TABLESPACE "TEST_SECUREFILE"
LOB ("DATA") STORE AS SECUREFILE (TABLESPACE "TEST_SECUREFILE" COMPRESS HIGH);

4. Artık redefinition işlemine başlayabiliriz. Start_redef_table tanımları sırasıyla şu şekilde (‘schema_ismi’,’orjinal_tablo’,’yeni_tablo’,’orjinal_tablo_kolon1 yeni_tablo_kolon1,orjinal_tablo_kolon2 yeni_tablo_kolon2, …..) diye gitmekte.
Bu işlem bittiğinde var olan datalar yeni tablonuza aktarılmış olacak,aktarılmamış olanlarda materilized view log da saklanıcaklar.
Eğer tablonuzda Pk bulunmuyorsa ROWNUM üstünden redef işinizi tamamlamanız gerekir.

4.1. PK üstünden redefinition başlatmak için.

exec dbms_redefinition.start_redef_table('MUSTAFA','TABLE_1','TABLE_2','NO NO, DATE DATE, XXX_NUMBER XXX_NUMBER , DATA DATA');

4.2. ROWNUM üstünden redefinition başlatmak için.

exec dbms_redefinition.start_redef_table('MUSTAFA','TABLE_1','TABLE_2','NO NO, DATE DATE, XXX_NUMBER XXX_NUMBER , DATA DATA', 2);

NOT : Start lie birlikte 1 tane temporary ve 1 tane kalıcı tablo oluşturuyor.

Yapılan DML işlemleri commit işleminden sonra materialized view log’a yani MUSTAFA.MLOG$_TABLE_1 tablosuna kaydedilir.

select * from MUSTAFA.MLOG$_TABLE_1;
select * from MUSTAFA.RUPD$_TABLE_1;

NOT : Start işlemini başlattıgımızda DBMS_REDEFINITON paketinin arka planda çalıştırdığı sql benim örnegim için aşağıdaki gibi.

INSERT /*+ BYPASS_RECURSIVE_CHECK APPEND SKIP_UNQ_UNUSABLE_IDX */ INTO "MUSTAFA"."TABLE_2"("NO","DATE","XXX_NUMBER","DATA") 
SELECT "NO","DATE","XXX_NUMBER","DATA" FROM "MUSTAFA"."TABLE_1";

5. Data taşıma işlemini bitirdiğimize göre orjinal tablodaki index,trigger,cons. ve grant gibi özellikleride yeni tablomuza taşıyabiliriz.Bu işlemi aşağıdaki gibi yada manuel olarak yapabilirsiniz.

-- Copy dependents.
SET SERVEROUTPUT ON
DECLARE
 l_num_errors PLS_INTEGER;
BEGIN
 DBMS_REDEFINITION.copy_table_dependents(
 uname => 'MUSTAFA',
 orig_table => 'TABLE_1',
 int_table => 'TABLE_2',
 copy_indexes => 1, -- Default
 copy_triggers => TRUE, -- Default
 copy_constraints => TRUE, -- Default
 copy_privileges => TRUE, -- Default
 ignore_errors => FALSE, -- Default
 num_errors => l_num_errors,
 copy_statistics => FALSE, -- Default
 copy_mvlog => FALSE); -- Default
 
 DBMS_OUTPUT.put_line('num_errors=' || l_num_errors); 
END;
/

DBMS_REDEFINITON paketinin senkronozisyonunu kontrol etmek için ana tablo verilerinde biraz oynayalım.

Delete MUSTAFA.TABLE_1 where rownum < 5000;

INSERT INTO MUSTAFA.TABLE_1("NO","DATE","XXX_NUMBER","DATA") 
SELECT "NO"*100,"DATE","XXX_NUMBER","DATA"FROM MUSTAFA.TABLE_1 where rownum < 20000;

commit;

6. Redefinition işlemini uzun tutup bitirmemeniz gereken durumlar oluşabiliyor eğer aradaki süre çok açılırsa son adım olan finish_redef_table uzun sürebiliyor bu tarz durumlarda sync işlemini yapmanızda yarar var.

BEGIN
DBMS_REDEFINITION.SYNC_INTERIM_TABLE('MUSTAFA','TABLE_1','TABLE_2');
END;
/

7. Redefinition işlemini artık bitirebiliriz. Bu komuttan sonra orjinal tablonuzla yeni tablonuz rename yapıp birbirlerinin yerine geçiceklerdir.

BEGIN
DBMS_REDEFINITION.FINISH_REDEF_TABLE('MUSTAFA','TABLE_1','TABLE_2');
END;
/

8. Redefinition işlemini iptal etmek için aşağıdaki komutu kullanabilirsiniz.

exec DBMS_REDEFINITION.ABORT_REDEF_TABLE('MUSTAFA', 'TABLE_1', 'TABLE_2')

9. Son durumda tabloların yapısı aşağıdaki gibidir.

CREATE TABLE "MUSTAFA"."TABLE_2"
(
 "NO" NUMBER (15, 5) NOT NULL ENABLE,
 "DATE" TIMESTAMP (6),
 "XXX_NUMBER" VARCHAR2 (25 BYTE),
 "DATA" BLOB,
 CONSTRAINT "PK_2" PRIMARY KEY ("NO")
)
TABLESPACE "TEST_SECUREFILE"
LOB ("DATA") STORE AS BASICFILE (TABLESPACE "TEST_SECUREFILE");


CREATE TABLE "MUSTAFA"."TABLE_1"
(
 "NO" NUMBER (15, 5) NOT NULL ENABLE,
 "DATE" TIMESTAMP (6),
 "XXX_NUMBER" VARCHAR2 (25 BYTE),
 "DATA" BLOB,
 CONSTRAINT "PK_1" PRIMARY KEY ("NO")
)
TABLESPACE "TEST_SECUREFILE"
LOB ("DATA") STORE AS SECUREFILE (TABLESPACE "TEST_SECUREFILE" COMPRESS HIGH);

http://docs.oracle.com/cd/B28359_01/server.111/b28310/diag001.htm#ADMIN11257
http://blog.canbakal.com/2012/05/20/oracle-table-redefinitio
Oracle DBMS_REDEFINITION ile Table Partitioning
Yararlı olması Dilegiyle …
Yazar : Mustafa Bektaş Tepe

Loading