Veritabanı Notlarım View RSS

No description
Hide details



ORACLE12C YENİ ÖZELLİK: Clone Pluggable Database 6 Aug 2013 5:44 AM (11 years ago)

Oracle 12c ile gelen bu yeni özlelik ile uygulamanıza yapılacak bir deployment öncesi pre-prod yapmak istenildiğinde veya performans problemleri incelerken veritabanının bir kopyasına ihtiyaç duyduğumuzda bu yöntemle veritabanımızın bir kopyasını oluşturabiliriz.

Bu örnekte Container Database(CDB)'deki bir pluggable database(PDB)'den clone alınarak yine aynı CDB'de başka bir PDB veritabanı oluşturduk.

Çalışmaya başlamadan önce yeterli disk alanı olduğunu kontrol edilmeli.

DB isimleri:
CDB: test12c
PDB: pdb1
Oluşturulacak PDB: pdb2


-- Clone alınacak database'in read-only modda olması gerekiyor. İlk önce pdb'lerin durumlarına bakarız.

SQL> select name,open_mode from v$pdbs;

NAME                           OPEN_MODE
------------------------------ ----------
PDB$SEED                       READ ONLY
PDB1                           READ WRITE

-- Clone alınacak database'in read-only modda açılır.
SQL> alter pluggable database PDB1 close immediate;

Pluggable database altered.

SQL> select name,open_mode from v$pdbs;

NAME                           OPEN_MODE
------------------------------ ----------
PDB$SEED                       READ ONLY
PDB1                           MOUNTED

SQL> alter pluggable database PDB1 open read only;

Pluggable database altered.

SQL> select name,open_mode from v$pdbs;

NAME                           OPEN_MODE
------------------------------ ----------
PDB$SEED                       READ ONLY
PDB1                           READ ONLY


-- Pluggable database clone alınarak oluşturulur. (datafile isimleri de convert edildi)
CREATE PLUGGABLE DATABASE PDB2 FROM PDB1
 STORAGE UNLIMITED
 FILE_NAME_CONVERT=(
  '/test12c/oradata/test12c/Pdb1/system01.dbf', '/test12c/oradata/test12c/Pdb2/system01.dbf.clone',
  '/test12c/oradata/test12c/Pdb1/sysaux01.dbf', '/test12c/oradata/test12c/Pdb2/sysaux01.dbf.clone',
  '/test12c/oradata/test12c/Pdb1/SAMPLE_SCHEMA_users01.dbf', '/test12c/oradata/test12c/Pdb2/SAMPLE_SCHEMA_users01.dbf.clone2',
  '/test12c/oradata/test12c/Pdb1/example01.dbf', '/test12c/oradata/test12c/Pdb2/example01.dbf.clone',
  '/test12c/oradata/test12c/Pdb1/Pdb1_temp01.dbf', '/test12c/oradata/test12c/Pdb2/Pdb2_temp01.dbf.clone'
  )

-- PDB'lerin durumlarına bakıldığında yeni oluşturulan pdb'in mount modda olduğunu görürüz. Bu pdb'i(PDB2) açtık.
SQL> select name,open_mode from v$pdbs;

NAME                           OPEN_MODE
------------------------------ ----------
PDB$SEED                       READ ONLY
PDB1                           READ ONLY
PDB2                           MOUNTED

SQL> alter pluggable database PDB2 open;

Pluggable database altered.

SQL> select name,open_mode from v$pdbs;

NAME                           OPEN_MODE
------------------------------ ----------
PDB$SEED                       READ ONLY
PDB1                           READ ONLY
PDB2                           READ WRITE

-- Yeni oluşturulan pdb'e(PDB2) bağlanarak kontrol ederiz.
SQL> connect system/oracle123@localhost:1538/PDB2
Connected.
SQL> show con_name

CON_NAME
------------------------------
PDB2


-- Clone alınan Pdb read-only modda olduğu için bu pdb'i tekrar read-write modda açtık
SQL> ALTER PLUGGABLE DATABASE PDB1 CLOSE IMMEDIATE;

Pluggable database altered.

SQL> ALTER PLUGGABLE DATABASE PDB1 OPEN;

Pluggable database altered.

SQL> select name,open_mode from v$pdbs;

NAME                           OPEN_MODE
------------------------------ ----------
PDB$SEED                       READ ONLY
PDB1                           READ WRITE
PDB2                           READ WRITE


-- Oluşturulan yeni pdb'i tekrar drop etmek için.
-- PDB kapatılır

SQL> alter pluggable database PDB2 close immediate;

Pluggable database altered.


-- Clone alınana PDB drop edilir.
SQL> drop pluggable database PDB2 including datafiles;

Pluggable database dropped.

-- PDB'ler kontrol edilir.
SQL> select name,open_mode from v$pdbs;

NAME                           OPEN_MODE
------------------------------ ----------
PDB$SEED                       READ ONLY
PDB1                           READ WRITE


Tabi bu işlemlerin tamamını Sql Developer-DBA navigator ekranından fare ile komut yazmadan yapma imkanımız da var. Sql navigator ile artık birçok işlem yapılabiliyor, kurcalamanızı tavsiye ederim.






Add post to Blinklist Add post to Blogmarks Add post to del.icio.us Digg this! Add post to My Web 2.0 Add post to Newsvine Add post to Reddit Add post to Simpy Who's linking to this post?

Oracle 11G - Interval Partitioning Özelliği 3 Apr 2013 6:37 AM (12 years ago)



Bilindiği üzere devasa tablolara erişimde performans sıkıntılarının giderilmesi, data arşivleme, büyük hacimlerdeki eski dataların silinmesi gibi durumlarda partitioning hayat kurtarıyordu. Bununla birlikte 11g öncesi versiyonlarda bu tabloların sürekli yeni partition'larının oluşturulması gibi bir maliyet söz konusuydu. Önceki versiyonlarda partition yaparken belirtilen zaman aralığı dışında bir veri girmeye çalıştığımız zaman "ORA-14400: inserted partition key does not map to any partition" hatasını alıyorduk, çünkü girmek istediğiniz verinin konumlandırılacağı bir partition bulunmamaktaydı.
11g ile partition create ederken "interval" ifadesini de ekleyerek tablomuza belirtilen aralıkların dışında bir data gelmesi durumunda ilgili partition'ı kendisi oluşturuyor. 11g ile gelen bu yeni özellik sayesinde artık partitioning seçeneğine daha bir ısındım diyebilirim. 

Aşağıda bir örnekle açıklamaya çalıştım. Bu örnekte eski dataları, farklı bir arşiv tablespace'ine aktarıyorum.

İlk olarak Tablespace create: Arşiv ve son datalar için iki farklı tablespace create ediyorum.

create tablespace TS_PART_ARCH datafile '/u01/app/oracle/oradata/TS_PART_ARCH01.dbf' size 10m autoextend on next 10m maxsize 100m;
create tablespace TS_PART datafile '/u01/app/oracle/oradata/TS_PART01.dbf' size 10m autoextend on next 10m maxsize 100m;

Tablo create: Tabloyu create ederken 2013 mart ayı öncesi dataları içeren partition'ları arşiv için tanımalanan farklı bir tablespace'e(TS_PART_ARCH), 2013 Mart ve sonrası dataları içeren partition'ları da farklı bir tablespace'e aktaracağımız şekilde tabloyu create ediyorum. Bunu yapmamdaki amaç arşiv için yaratılan tablespace'i ilerleyen zamanlarda read-only'ye alabilmek, yavaş disklerde konumlandırmak gibi esneklikler sağlaması... Yeni yaratılan partition'lar için de default tablespace olarak TS_PART tablespace'ini belirttim.

CREATE TABLE PART_TABLE(sira number, tarih date)
  PARTITION BY RANGE (tarih)
  interval (numtoyminterval(1,'MONTH')) store in (TS_PART)
  (
  PARTITION part2011 VALUES LESS THAN (TO_DATE('2012-01-01','SYYYY-MM-DD')) TABLESPACE TS_PART_ARCH,
  PARTITION part2012 VALUES LESS THAN (TO_DATE('2013-01-01','SYYYY-MM-DD')) TABLESPACE TS_PART_ARCH,
  PARTITION part201301 VALUES LESS THAN (TO_DATE('2013-02-01','SYYYY-MM-DD')) TABLESPACE TS_PART_ARCH,
  PARTITION part201302 VALUES LESS THAN (TO_DATE('2013-03-01','SYYYY-MM-DD')) TABLESPACE TS_PART_ARCH,
  PARTITION part201303 VALUES LESS THAN (TO_DATE('2013-04-01','SYYYY-MM-DD')) TABLESPACE TS_PART
  )


-- Create edilen partititon'lara, bunların max değerlerine ve belirtilen tablespace'lerde yaratıldığını aşağıdaki sorgu ile görüyoruz.

SQL> select table_name,partition_name,high_value,tablespace_name from all_tab_partitions where table_name ='PART_TABLE';

TABLE_NAME                     PARTITION_NAME                
------------------------------ ------------------------------
HIGH_VALUE                                        
--------------------------------------------------
TABLESPACE_NAME               
------------------------------
PART_TABLE                      PART2011                      
TO_DATE(' 2012-01-01 00:00:00', 'SYYYY-MM-DD HH24:
MI:SS', 'NLS_CALENDAR=GREGORIAN')                 
TS_PART_ARCH                   
                                                                                
PART_TABLE                      PART2012                      
TO_DATE(' 2013-01-01 00:00:00', 'SYYYY-MM-DD HH24:
MI:SS', 'NLS_CALENDAR=GREGORIAN')                 
TS_PART_ARCH                   
                                                                                
PART_TABLE                      PART201301                    
TO_DATE(' 2013-02-01 00:00:00', 'SYYYY-MM-DD HH24:
MI:SS', 'NLS_CALENDAR=GREGORIAN')                 
TS_PART_ARCH                   
                                                                                
PART_TABLE                      PART201302                    
TO_DATE(' 2013-03-01 00:00:00', 'SYYYY-MM-DD HH24:
MI:SS', 'NLS_CALENDAR=GREGORIAN')                 
TS_PART_ARCH                   
                                                                                
PART_TABLE                      PART201303                    
TO_DATE(' 2013-04-01 00:00:00', 'SYYYY-MM-DD HH24:
MI:SS', 'NLS_CALENDAR=GREGORIAN')                 
TS_PART 

5 rows selected.


-- Eski tarihli datalar insert edilir:

SQL> insert into PART_TABLE values (1,'01.01.2007');
SQL> insert into PART_TABLE values (2,'01.01.2008');
SQL> insert into PART_TABLE values (3,'01.01.2009');
SQL> insert into PART_TABLE values (4,'01.01.2010');
SQL> insert into PART_TABLE values (5,'01.01.2011');
SQL> commit;


-- Dataların ilgili partition'da olduğu kontrol edilir.

SQL> select * from PART_TABLE partition(part2011)

      SIRA TARIH     
---------- ----------
         1 01/01/2007
         2 01/01/2008
         3 01/01/2009
         4 01/01/2010
         5 01/01/2011

5 rows selected.


-- 2012 ye ait kayıtlar girilir.

SQL> insert into PART_TABLE values (6,'01.01.2012');
SQL> insert into PART_TABLE values (7,'01.07.2012');
SQL> insert into PART_TABLE values (8,'15.09.2012');
SQL> commit;


--- Dataların 2012 partition'ında olduğu kontrol edilir.

SQL> select * from PART_TABLE partition(part2012)

      SIRA TARIH     
---------- ----------
         6 01/01/2012
         7 01/07/2012
         8 15/09/2012

3 rows selected.


-- 2013 tarihli mevcut ve ileri tarihli partition'lar için yeni kayıtlar girilir.

SQL> insert into PART_TABLE values (10,'15.02.2013');
SQL> insert into PART_TABLE values (11,'15.03.2013');
SQL> insert into PART_TABLE values (11,'15.04.2013');
SQL> insert into PART_TABLE values (12,'15.05.2013');
SQL> insert into PART_TABLE values (13,'15.06.2013');
SQL> commit;


-- 2013 Ocak partition'ında(PART201301) kayıt atılmadığı için data gelmiyor.

SQL> select * from PART_TABLE partition(part201301);

no rows selected.


-- Diğer aylara denk gelen datalar kontrol edilir:

SQL> select * from PART_TABLE partition(part201302);

      SIRA TARIH     
---------- ----------
        10 15/02/2013
1 row selected.

SQL> select * from PART_TABLE partition(part201303);


      SIRA TARIH     
---------- ----------
        11 15/03/2013
1 row selected.


Mevcut ve yeni yaratılan partititon'lara ve bunların max değerlerinin ne olduğuna bakılır. Aynı zamanda partition'ların belirtilen tablespace'lerde, yeni yaratılan partition'ların da default olarak belirtilen tablespace'de (TS_PART) yaratıldığını görüyoruz.

SQL> select table_name,partition_name,high_value,tablespace_name from all_tab_partitions where table_name ='PART_TABLE';

TABLE_NAME                     PARTITION_NAME                
------------------------------ ------------------------------
HIGH_VALUE                                        
--------------------------------------------------
TABLESPACE_NAME               
------------------------------
PART_TABLE                      PART2011                      
TO_DATE(' 2012-01-01 00:00:00', 'SYYYY-MM-DD HH24:
MI:SS', 'NLS_CALENDAR=GREGORIAN')                 
TS_PART_ARCH                   
                                                                                
PART_TABLE                      PART2012                      
TO_DATE(' 2013-01-01 00:00:00', 'SYYYY-MM-DD HH24:
MI:SS', 'NLS_CALENDAR=GREGORIAN')                 
TS_PART_ARCH                   
                                                                                
PART_TABLE                      PART201301                    
TO_DATE(' 2013-02-01 00:00:00', 'SYYYY-MM-DD HH24:
MI:SS', 'NLS_CALENDAR=GREGORIAN')                 
TS_PART_ARCH                   
                                                                                
PART_TABLE                      PART201302                    
TO_DATE(' 2013-03-01 00:00:00', 'SYYYY-MM-DD HH24:
MI:SS', 'NLS_CALENDAR=GREGORIAN')                 
TS_PART_ARCH                   
                                                                                
PART_TABLE                      PART201303                    
TO_DATE(' 2013-04-01 00:00:00', 'SYYYY-MM-DD HH24:
MI:SS', 'NLS_CALENDAR=GREGORIAN')                 
TS_PART                      
                                                                                
PART_TABLE                      SYS_P41                       
TO_DATE(' 2013-05-01 00:00:00', 'SYYYY-MM-DD HH24:
MI:SS', 'NLS_CALENDAR=GREGORIAN')                 
TS_PART                      
                                                                                
PART_TABLE                      SYS_P42                       
TO_DATE(' 2013-06-01 00:00:00', 'SYYYY-MM-DD HH24:
MI:SS', 'NLS_CALENDAR=GREGORIAN')                 
TS_PART                      
                                            
PART_TABLE                      SYS_P43                       
TO_DATE(' 2013-07-01 00:00:00', 'SYYYY-MM-DD HH24:
MI:SS', 'NLS_CALENDAR=GREGORIAN')                 
TS_PART                      
                                                                                
8 rows selected.

-- Yeni yaratılan partition'ların datalarına bakılır.
SQL> select * from PART_TABLE partition(SYS_P42);

      SIRA TARIH     
---------- ----------
        12 15/05/2013
1 row selected.


SQL> select * from PART_TABLE partition(SYS_P43);

      SIRA TARIH     
---------- ----------
        13 15/06/2013
1 row selected.



Bu özellik için söylenebiliecek birkaç ek bilgi; 
- interval partition olan tabloları DBA_PART_TABLES view'ındaki "INTERVAL" kolonundan öğrenebiliriz. 
- Aylık olarak tanımladığımız partition'ları yıllık partition'a aşağıdaki komutu ile çevirebiliriz:
ALTER TABLE part_table SET INTERVAL (NUMTOYMINTERVAL(1,'YEAR');" 
- Range partitio olan bir tabloyu interval partition'a aşağıdaki komut ile basit bir şekilde çevirebiliriz:
ALTER TABLE part_table SET INTERVAL(NUMTOYMINTERVAL(1, 'MONTH'));
- Interval partitioning olan tabloyu tekrar sadece range partition'a çevirmek içinse aşağıdaki komutu kullanabiliriz: 
ALTER TABLE part_table SET INTERVAL ();
- Interval partition'da verilen bu aralık kolay bir şekilde değiştirilebilir. Aşağıdaki komutta 1 aylık olan aralığı 3 aya çevirebiliriz:
ALTER TABLE part_table SET INTERVAL(NUMTOYMINTERVAL(3, 'MONTH'));
- Interval partition olan bir tablonun bulunduğu tablespace aynı syntax ile değiştirilebilir. Örneğin belirtilen 3 tablespace arasında "round robin" mantığı ile partition'lar konumlandırılabilir. Aşağıdaki örnekte ts1 ile ts3 arasında partition'ların saklanması sağlanabilir.
ALTER TABLE part_table SET STORE IN(ts1, ts2, ts3);


Kolay gelsin.

Add post to Blinklist Add post to Blogmarks Add post to del.icio.us Digg this! Add post to My Web 2.0 Add post to Newsvine Add post to Reddit Add post to Simpy Who's linking to this post?

Veritabanı dosyalarını(datafile) başka bir dizine taşıma 22 Mar 2013 7:27 AM (12 years ago)



Bu işlem veritabanı kapalıyken veya açıkken yapılabilir.

1 ) Veritabanı Kapalıyken:
* Database kapatılır.
SQL > shutdown imeediate

* Datafile yeni dizine kopyalanır veya move edilir.
$ cp /old_location/dbfilename01.dbf /new_location/
Taşımayıp kopyaladıysanız eski lokasyondaki datafile'ı kullanmasını önlemek adına ek önlem için rename edebiliriz.
$ mv /old_location/dbfilename01.dbf /old_location/dbfilename01.dbf_OLD

* Database mount mode'da açılarak datafile rename edilir.
SQL > startup mount
SQL > alter database rename file '/old_location/dbfilename01.dbf' to '/new_location/dbfilename01.dbf';

* Database open mode'a alınır.
SQL > alter database open;


2 ) Veritabanı Açıkken:
Bunu yapabilmek için database'in archive log mode'da olması gerekiyor. Bunu aşağıdaki komutla kontrol edebilirsiniz.
SQL> select log_mode from sys.v_$database;

LOG_MODE
------------
ARCHIVELOG

* Datafile offline'a alınır.
SQL> alter database datafile '/old_location/dbfilename01.dbf' offline;

* Datafile yeni dizine kopyalanır veya move edilir.
$ cp /old_location/dbfilename01.dbf /new_location/
Taşımayıp kopyaladıysanız eski lokasyondaki datafile'ı kullanmasını önlemek adına ek önlem için rename edebiliriz.
$ mv /old_location/dbfilename01.dbf /old_location/dbfilename01.dbf_OLD

* Veritabanın taşınan datafile'ı yeni lokasyonda olduğunu göstermek için rename ederiz:
SQL> alter database rename file '/old_location/dbfilename01.dbf' to '/new_location/dbfilename01.dbf';

* Datafile'ı tutarlı hale getirmek için recover edilir.
SQL> alter database recover datafile '/new_location/dbfilename01.dbf';

* Tekrar kullanıma açmak için online mode'a alınır.
SQL> alter database datafile '/new_location/dbfilename01.dbf' online;


şeklinde taşıma işlemini tamamlamış oluruz. 

Add post to Blinklist Add post to Blogmarks Add post to del.icio.us Digg this! Add post to My Web 2.0 Add post to Newsvine Add post to Reddit Add post to Simpy Who's linking to this post?

Materialized View kullanımı ve Fast Refresh için basit bir örnek 2 Dec 2011 6:49 AM (13 years ago)

Materialized view’lar(MV) genel olarak Data warehouse sistemlerinde kullanılır. Normal view’lar sadece sorguları saklayıp istenildiğinde dataları ilgili tablolardan belirtilen kriterlere göre getirirken, materialized view’larda sorguların yanı sıra bu sorguların sonucunda dönen datalar da tutulur. Yani bir nevi tablo görevi görür. Bunun kullanılma amacı ise; devasa datalara sahip tabloların sadece belirtilen kriterlere uyan datalarını önceden hazırlayıp hızlı bir şekilde sunmak.

Materialized view’ların sorguladığı tablolardaki datalar değiştiğinde değişikliklerin bu view’lara yansıması için bu materialized view’ların refresh edilmesi gerekiyor.

Birkaç refresh metodu bulunmaktadır ve mv create işleminde belirtilir. COMPLETE ve FAST. Refresh işlemi için DBMS_MVIEW.REFRESH prosedürü kullanılır.

Refresh Complete: MV refresh complete yapıldığında mv’ı oluşturan sorgu tekrar çalıştırılır ve gelen dataların tamamı mv’daki dataların yerine geçer. Refresh etmek için DBMS_MVIEW.REFRESH prosedürünün method parametresine C gönderilir.

execute DBMS_MVIEW.REFRESH( LIST => 'MV', METHOD => 'C' );

Refresh Fast: MV fast refresh yapabilmek için; mv’ın bağlı olduğu tablolar üzerine materialized view log’lar create edilir. MV log’lar yaratıldığı tablolar üzerinde değişen kayıtları PK bazında saklar. Fast refresh yapıldığında ise bu mv log’lardan sadece değişen kayıtları bularak bunları mv’a taşır. Refresh etmek için DBMS_MVIEW.REFRESH prosedürünün method parametresine F gönderilir.

execute dbms_mview.refresh( list => 'MV', method => 'F' );

Fast refresh opsiyonlarından otomatik ve manuel refresh işlemi için aşağıdaki gibi basit bir örnek yapalım:

İlk olarak test için bir tablo yaratılır ve materialized view log kullanabilmek için bu tablo üzerinde bir primary key tanımı yapılır. Daha sonra bu tablo üzerine bir Materialized view log(MV LOG) ve Materialized View (MV) create edilir.

SQL> create table tablo1 as select rownum r,'ROW'||rownum line from all_objects where rownum<=5;

Table created

SQL> alter table tablo1 add primary key(r);

Table altered

SQL> create materialized view log on tablo1 with primary key;

Materialized view log created

SQL> drop materialized view mv_tablo1;

Materialized view dropped

SQL> create materialized view mv_tablo1 refresh fast with primary key as select * from tablo1;

Materialized view created

SQL> select * from tablo1;

R LINE

---------- -------------------------------------------

1 ROW1

2 ROW2

3 ROW3

4 ROW4

5 ROW5

SQL> select * from mv_tablo1;

R LINE

---------- -------------------------------------------

1 ROW1

2 ROW2

3 ROW3

4 ROW4

5 ROW5

Daha sonra tablo üzerinde birkaç DML işlemi yapılır. Commit’ledikten sonra MV da dataların güncellenmediğini görülür.

SQL> update tablo1 set line='DUMMY' where r=1;

1 row updated

SQL> update tablo1 set line='ROW1' where r=2;

1 row updated

SQL> update tablo1 set line='ROW2' where r=1;

1 row updated

SQL> select * from tablo1;

R LINE

---------- -------------------------------------------

1 ROW2

2 ROW1

3 ROW3

4 ROW4

5 ROW5

SQL> select * from mv_tablo1 order by r;

R LINE

---------- -------------------------------------------

1 ROW1

2 ROW2

3 ROW3

4 ROW4

5 ROW5

SQL> commit;

Commit complete

SQL> select * from tablo1;

R LINE

---------- -------------------------------------------

1 ROW2

2 ROW1

3 ROW3

4 ROW4

5 ROW5

SQL> select * from mv_tablo1 order by r;

R LINE

---------- -------------------------------------------

1 ROW1

2 ROW2

3 ROW3

4 ROW4

5 ROW5

MV refresh işi aşağıdaki komut ile manuel çalıştırdıktan sonra güncellenen dataların MV’a geldiği görülür.

SQL> exec dbms_mview.refresh('MV_TABLO1');

PL/SQL procedure successfully completed

SQL> select * from mv_tablo1 order by r;

R LINE

---------- -------------------------------------------

1 ROW2

2 ROW1

3 ROW3

4 ROW4

5 ROW5

SQL>

Bu sefer aynı işlem MV create işleminde ON COMMIT ifadesi kullanılarak tekrarlanır.

Aynı şekilde tablo ve primary key tanımı yapıldıktan sonra MV Log ve MV create edilir. Farklı olarak MV create ederken refresh işleminin commit sonrası otomatik yapmasını için “ON COMMIT” ile create edilir.

SQL> create table tablo2 as select rownum r,'ROW'||rownum line from all_objects where rownum<=5;

Table created

SQL> alter table tablo2 add primary key(r);

Table altered

SQL> create materialized view log on tablo2 with primary key;

Materialized view log created

SQL> drop materialized view mv_tablo2;

Materialized view dropped

SQL> create materialized view mv_tablo2 refresh fast on commit with primary key as select * from tablo2;

Materialized view created

SQL> select * from tablo2;

R LINE

---------- -------------------------------------------

1 ROW1

2 ROW2

3 ROW3

4 ROW4

5 ROW5

SQL> select * from mv_tablo2;

R LINE

---------- -------------------------------------------

1 ROW1

2 ROW2

3 ROW3

4 ROW4

5 ROW5

Tablo üzerinde DML işlemleri yapılır.

SQL> update tablo2 set line='DUMMY' where r=1;

1 row updated

SQL> update tablo2 set line='ROW1' where r=2;

1 row updated

SQL> update tablo2 set line='ROW2' where r=1;

1 row updated

DML işlemleri sonrası Commit atılmadan tablo ve MV daki datalar sorguladığında değişen dataların doğal olarak mv’a yansımadığı görülür.

SQL> select * from tablo2;

R LINE

---------- -------------------------------------------

1 ROW2

2 ROW1

3 ROW3

4 ROW4

5 ROW5

SQL> select * from mv_tablo2 order by r;

R LINE

---------- -------------------------------------------

1 ROW1

2 ROW2

3 ROW3

4 ROW4

5 ROW5

Commit atıldıktan sonra mv datalarını kontrol edildiğinde dataların bu sefer MV’da güncellendiğini görülür. MV commit sonrası otomatik olarak refresh edilmiş oldu.

SQL> commit;

Commit complete

SQL> select * from mv_tablo2 order by r;

R LINE

---------- -------------------------------------------

1 ROW2

2 ROW1

3 ROW3

4 ROW4

5 ROW5

EK BILGI:

MV Log'ları sorgulamak için MLOG$_ objeleri kullanılır. DML işlemleri geldiğinde bu objede dml işlemi görmüş datalar görünmektedir.

Fast refresh sırasında on commit ifadesi kullanılıp kullanılmayan mv log’larda ufak bir farklılık görünür.

Otomatik refresh olan MV'ların MV Log'larında commit'lenmemiş dataları görürüz.

SQL> insert into tablo2 values(6,'ROW6');

1 row inserted

SQL> commit;

Commit complete

SQL> select * from mv_tablo2 order by r;

R LINE

---------- -------------------------------------------

1 ROW2

2 ROW1

3 ROW3

4 ROW4

5 ROW5

6 ROW6

6 rows selected

SQL> select * from mlog$_tablo2;

R SNAPTIME$$ DMLTYPE$$ OLD_NEW$$ CHANGE_VECTOR$$ XID$$

---------- ----------- --------- --------- -------------------------------------------------------------------------------- ----------

SQL> delete tablo2 where r=6;

1 row deleted

SQL> select * from mlog$_tablo2;

R SNAPTIME$$ DMLTYPE$$ OLD_NEW$$ CHANGE_VECTOR$$ XID$$

---------- ----------- --------- --------- -------------------------------------------------------------------------------- ----------

6 1/1/4000 D O 00 8444936496

SQL> commit;

Commit complete

SQL> select * from mlog$_tablo2;

R SNAPTIME$$ DMLTYPE$$ OLD_NEW$$ CHANGE_VECTOR$$ XID$$

---------- ----------- --------- --------- -------------------------------------------------------------------------------- ----------

Manuel refresh edilen MV'ların MV Log'larında ise commit'lenmemiş dataların yanı sıra refresh edilmemiş datalar da görünmektedir.

SQL> insert into tablo1 values(6,'ROW6');

1 row inserted

SQL> select * from mlog$_tablo1;

R SNAPTIME$$ DMLTYPE$$ OLD_NEW$$ CHANGE_VECTOR$$ XID$$

---------- ----------- --------- --------- -------------------------------------------------------------------------------- ----------

6 1/1/4000 I N FE 1.68895293

SQL> commit;

Commit complete

SQL> select * from mlog$_tablo1;

R SNAPTIME$$ DMLTYPE$$ OLD_NEW$$ CHANGE_VECTOR$$ XID$$

---------- ----------- --------- --------- -------------------------------------------------------------------------------- ----------

6 1/1/4000 I N FE 1.68895293

SQL> exec dbms_mview.refresh('MV_TABLO1');

PL/SQL procedure successfully completed

SQL> select * from mlog$_tablo1;

R SNAPTIME$$ DMLTYPE$$ OLD_NEW$$ CHANGE_VECTOR$$ XID$$

---------- ----------- --------- --------- -------------------------------------------------------------------------------- ----------

SQL>

İyi akşamlar.

Add post to Blinklist Add post to Blogmarks Add post to del.icio.us Digg this! Add post to My Web 2.0 Add post to Newsvine Add post to Reddit Add post to Simpy Who's linking to this post?

FLASHBACK RECOVERY: 30 Jul 2009 5:03 AM (15 years ago)

Flashback özelliğinin kullanımı ile ilgili kısa bir örnek yapalım.
Bu örnekte test çalışmasında kullanılmak database'in flashback özelliğinin açarak bir restore point yaratıp, testlerin ardından yaratılan restore point'e dönerek database'i test öncesindeki haline getiririz.

ilk önce veritabanının flashback için kullanacağı alanı ayarlarız. Aşağıdaki parametrelerden bu alanın ayrılmadığını görebiliriz.
SQL> show parameters db_recovery;

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
db_recovery_file_dest string
db_recovery_file_dest_size big integer 0

Bu alanı aşağıdaki gibi set edebiliriz.
alter system set db_recovery_file_dest_size=2g;
alter system set db_recovery_file_dest='/app/oracle/flash_recovery_area';
init.ora dosyasına aşağıdaki satırlar yazılır:
*.db_recovery_file_dest='/app/oracle/flash_recovery_area'
*.db_recovery_file_dest_size=2147483648

Bu işlemleri yaptıktan sonra tekrar parametreleri kontrol ederek aşağıdaki gibi set edildiğini görebiliriz.
SQL> show parameters db_recovery;

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
db_recovery_file_dest string /app/oracle/flash_recovery_area
db_recovery_file_dest_size big integer 2G

Bu alanı ayarladıktan sonra flashback özelliğini açmak için veritabanını kapatarak mount modda açarız.
SQL> shu immediate
SQL> startup mount
Mount modda açtığımız database'in flashback özelliğini açarak test'lerin ardından geri dönebilieceğimiz restore point i yaratırız.
SQL> alter database flashback on;
SQL> create restore point Before_Test_Point guarantee flashback database;

test işlemlerine başlanabilmek için database açılır.
SQL> alter database open;

***************************************************************
TEST işlemleri yapılır.
****************************************************************

Test'ler bitince yarttığımız restore point noktasına dönmek için database i tekrar kapatarak mount modda açarız.
SQL> Startup mount force;
flashback işlemini yaparız:
flashback database to restore point Before_Test_Point;

Bu işlemden sonra artık test çalışmaları öncesine dönmüş olduk. Bundan sonra flashback özelliği kapatılarak yarttığımız restore point i drop ederiz.
SQL> alter database flashback off;
SQL> drop restore point Before_Test_Point;

flashback de kullanılmak üzere belirlediğimiz alanı kapatmak için init.ora dosyasına eklenen açşağıdaki satırlar kaldırılır.
*.db_recovery_file_dest='/app/oracle/flash_recovery_area'
*.db_recovery_file_dest_size=2147483648

Database kapatılarak test aşamasında redo.log'lara yazılan bilgiyi temizlemek için resetlogs ile açılır.
shu immediate;
startup mount;
alter database open resetlogs;


İşinize yaraması dileğimle...


Serkan YILMAZ

Add post to Blinklist Add post to Blogmarks Add post to del.icio.us Digg this! Add post to My Web 2.0 Add post to Newsvine Add post to Reddit Add post to Simpy Who's linking to this post?

RMAN:DUPLICATE DATABASE İLE YENİ BİR VERİTABANI YARATMA 28 Jul 2009 2:14 AM (15 years ago)


Veritabanımızın son alınan mevcut backup'ından yeni bir test ortamı oluştururken hazırladığım aksiyon planını aşağıdaki gibi paylaşmak istedim. Eklemek istediğiniz veya yanlış olduğunu düşündüğünüz hertürlü konuyu paylaşırsanız sevinirim.

Tanımlar:
prd: kopyası oluşturalacak production sistemi

prdserver: production veritabanı server ı
test: oluşturulacak test sistemi.

testserver: test veritabanı server ı

catalogdb: rman katalog bilgilerinin bulunduğu veritabanı
catdbserver: katalog veritabanı server ı


Test ortamında listener düzenlemesi:
* oluşturulacak test ortamının mevcut listener.ora dosyasına aşağıdaki satırlar eklenir.


(SID_DESC =
(GLOBAL_DBNAME = prd)
(ORACLE_HOME = /app/oracle/product/11.1.0/db_1)
(SID_NAME = prd)
)


TNS tanımlarınını yapılması:
* test ortamının tnsnames.ora dosyasına catalog ve prod veriabanlarının tns tanımları eklenir.

catalogdb =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = catdbserver)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = catalogdb)
)
)

PRD =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = prdserver)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = prd)
)
)

test ortamında init.ora'da düzenleme yapılır:

Controlfile’ların yeni path’i neresi olacaksa init.ora dosyasında düzenlenir. db ve log file'larının yerleri değiştirilecekse init.ora dosyasına ilgili convert satırları eklenir.

....

*.control_files='/app/oracle/oradata/test/controlfile01.bak','/app/oracle/oradata/test/controlfile02.bak'

DB_FILE_NAME_CONVERT=(/app/oracle/oradata/prod/,/app/oracle/oradata/test/)
LOG_FILE_NAME_CONVERT=(/app/oracle/oradata/prod/,/app/oracle/oradata/test/)
....

test ortamında passwordfile create edilir:
orapwd file=orapwprd password=syspass entries=10

test sistemine en son alınan produciton backup'ı kopyalanır:
scp /prd/dump/DBBACKUP/PRD_dbf_bck_690234592_64.rman oracle@testserver:/prd/dump/DBBACKUP
scp /prd/dump/DBBACKUP/PRD_archlog_bck_690235138_66.rman oracle@testserver:/prd/dump/DBBACKUP
scp /bnprd/dump/DBBACKUP/snapcf_prd.f oracle@testserver:/prd/dump/DBBACKUP


prod ortamında son alınan backup’tan sonra üretilen archive dosyalarının da backup’ı alınarak test ortamına gönderilir.

rman target / catalog rcowner/rcpass@catalogdb

RMAN> sql 'alter system archive log current';
RMAN> backup FORMAT '/prd/dump/DBBACKUP/%d_archlog_bck_%t_%s.rman' ARCHIVELOG ALL DELETE INPUT;


scp /prd/dump/DBBACKUP/PRD_archlog_bck_690235138_66.rman oracle@testserver:/prd/dump/DBBACKUP
scp /prd/dump/DBBACKUP/snapcf_prd.f oracle@testserver:/prd/dump/DBBACKUP

test ortamında SID'yi test olarak set edilip umount modda açılır:
startup nomount;


Rman ile prod ve catalog db'e bağlanılır:
rman target sys@prd catalog rcowner/rcpass@catalogdb AUXILIARY /

test ortamını backup'tan duplicate edilir:
DUPLICATE TARGET DATABASE TO test;


Bu işlemin başarılı ile bitmesinin ardından database test ortamı oluşturulmuştur. Güvenlik önlemi olsun diye mevcut database link'ler drop edilebilir. Aynı zamanda şifre bilgilerini de resetleyerek herhangibir şekilde production'a gitmek isteyenlerin yanlış veritabanına bağlanması önlenmiş olacaktır.

İşinize yaraması dileğiyle.

Add post to Blinklist Add post to Blogmarks Add post to del.icio.us Digg this! Add post to My Web 2.0 Add post to Newsvine Add post to Reddit Add post to Simpy Who's linking to this post?