joomla templates Data Warehouse Türkiye

Thu09082011

Last update07:32:32 PM GMT

Back Yardımcı Linkler Kitaplar Tarihe göre etiket öğelerini görüntüle: database
Cumartesi, 02 Nisan 2011 11:26

Canlı Bir Transportable Tablespace Operasyonu

19 Mart 2011Canlı Bir Transportable Tablespace Operasyonu Yazılarımdan da anlaşılacağı üzere bu aralar transportable tablespace’ le yakından ilgileniyorum. Bu konudaki yapmış olduğum tüm testleri ve production ortamlarımızda yapmış olduğumuz operasyonlarla ilgili detaylarıda sizinle buradan paylaşmaya çalışıyorum.  Şimdiye kadar tranportable tablespace ile ilgili çalışma mantığından, kıstlarından bahsettik. Neden bu konu üzerine bu kadar yoğunlaştığımdan bahsedeyim, ileride sizlerde benzer bir durumla karşılaşırsanız diğer yöntemler ile karşılaştırmada yardımcı olacaktır. Production ortamda kullandığımız bazı database’ lerimizi yeni alınmış olan (yeni sunucu ibm p795 serisi) sunucular üzerine taşımaya çalışıyoruz. İlk taşınacak olan database yaklaşık 3 tb  büyüklüğündeki bir database,  bu database’ i migrate etme işini bitirdik. Bugün bu taşıma işlemini transportable tablespace yöntemi kullanarak nasıl yaptığımızdan step by step bahsedeceğim ;  (Şunu belirtmemde fayda aşağıdaki stepler bizim taşımış olduğumuz database’ in özellikleri ile şekillenmiş adımlar yani bu database’ de materialized view yoktu, eğer olsaydı bir stepde bunun için olacaktı)

 • Öncelikle yeni sunucu üzerine db block size, nls ayarları ve sid’ i eski sunucu ile aynı olacak şekilde boş bir instance create edilir. (transportable tablespace gereği) 

 
Sys, ve system dışında SYSTEM tablespace’ inin altında user nesnesi olmaması gerekiyor. (system, sysaux, undo, temp gibi tbs’ ler taşınmayacağından dolayı)

 select owner,segment_name,segment_type, tablespace_name,bytes/1024/1024 boyut from dba_segments where tablespace_name = 'SYSTEM'and owner in (select distinct(owner) from dba_segments where tablespace_name = 'SYSTEM' and owner not in('SYS','SYSTEM','OUTLN') )


Taşınacak olan database’ deki tüm tablespace’ lerin aralarındaki ilişkiler check edilir.  Database’ i full olarak taşıdığımızdan dolayı UNDO, TEMP, SYS, SYSAUX şemalarını hariç geri kalan tüm schemaları taşıyoruz.  (Ben  tüm örneklerdeki tablespace isimlerini değiştirerek yazıyorum) Buradaki amaç bu tablespace’ lerin taşınmayacak olan yukarıda belirtilen  diğer tablespace’ ler ile herhangi bir ilişki olmaması.

 EXECUTE DBMS_TTS.TRANSPORT_SET_CHECK('USERS,DENEME,PROD', TRUE);

Procedur çalıştıkdan sonra aşağıdaki select ile kontrol ediyoruz. Sonucun no rows dönmesi gerekiyor. Eğer kayıt dönerse farklı tablepsace’ lerdeki nesneler olması gereken tablespace üzerine taşınır. (nesnelerin nasıl taşınabileceğini daha önceki yazılarından bulabilirsiniz)

 • İlişkileri test ettikden sonra transportable backup’ a hazırlık için expdp alınacağı directory oluşturulur. 
CREATE DIRECTORY  expdp AS '/s4/META_DATA_ISLEM';GRANT READ,WRITE ON DIRECTORY expdp TO SYSTEM;


Atlanmaması gereken bir önemli nokta transportable backup alınmadan önce mutlaka dba_recyclebin purge edilmelidir. Sql>Purge dba_recyclebin;

 • Backup öncesinde taşınacak olan tüm tablespace’ ler read only moda alınır. select 'alter tablespace '||name|| ' read only;' from v$tablespacewhere name not in('SYS','SYSTEM','UNDOTBS1','TEMP','SYSAUX')

Transportable export backupı alınır. expdp "'/ as sysdba'" directory=DWDATA_TT_EXPORT dumpfile=DWDATA_TT_EXPORT.dmp logfile=DWDATA_TT_EXPORT.log transport_tablespaces=USERS,DENEME,PROD

Package, sysnonym, link vs gibi nesnelerin diğer ortama taşınması içinde (bunların scriptleride alınıp manuel diğer tarafa atılabilir ancak private linkleri create  edebilmek için  private linki olan userların şifrelerini bilmeniz gerekir)  no rows  dump alıyoruz.  (burada no rows tablolarında ddl exportunu alacaktır,  bunlar için bir aksiyon almazsanız TABLE ACTION EXIST opsiyonu skip olduğundan var olan tabloyu görüp hata verip devam edecektir.

 Şunu da yapabilirsiniz EXCLUDE=TABLE derseniz tablolara hiç bakma geri kalanı import et de  diyebilirsiniz ki bu mantıklı bir seçim diye düşünüyorum ) Bununla ilgili bir not, exportu schema vermeyip full alıp diğer tarafa schema bazında atabilirsiniz. Atlama olma ihtimalini ortadan kaldırmak için faydası olacaktır.

 Böylelikle ihtiyaç halinde exportu sonrasında tekrar kullanabilirsiniz.expdp "'/ as sysdba'" DIRECTORY=expdp DUMPFILE= metadata_15032011.dmp LOGFILE=metadata_15032011.log  CONTENT=METADATA_ONLY  FULL=Y

Yine bir not, eski ortamda datafile’ lerinizi yeni ortamdaki path’ e taşırken datafile isimlerinizi mutlaka kontrol etmelisiniz, farklı dizinlerde aynı isimle yer alan datafile’ leriniz olabilir, Bunları migration öncesinde rename ile düzeltmeniz faydanıza olacaktır.  (eğer tüm datafile’ leri diğer tarafda aynı lokasyonda tutacaksanız) 

Datafile’ lerin taşınması için OS tarafı için CP scriptlerini oluşturmamız gerekiyor. 
V$datafile’ den name kolonundan datafile’ lerin adı ve pathleri alındıkdan sonra yazılacak bir scp veya rcp komutu ile bu adım yapılabilir. 

Oracle’ ın internel userları haricindeki tüm userlara ait create scriptleri,  role’ lerin create scriptleri oluşturulacak. (Buradan alınacak olan userların default tablespace’ leri not alınır, diğer tarafa create edildiği aşamada tablespace ‘ ler olmayacağı için tüm userların default tablespace’ ini USERS yapıp, işlem bittikden sonra eski haline geri alabilirsiniz. Create scriptleri için toad’ ın generate schema script menüsünü kullanabilirsiniz.  Deafult tablespace’ leri değiştirmek ve eskisinin backupını almak içinse aşağıdaki scriptleri kullanabiliriz.Default tablespace’ leri değiştirmek için; select 'alter user '||username|| ' default tablespace USERS;' from dba_users; Eskisindeki durumu backuplamak için (diğer tarafda işlem bittikden sonra userların default tablespace’ leri orijinal hallerine çevrilmelidir); select 'alter user '||username|| ' default tablespace '||default_tablespace|| ';' from dba_users

 • Eski sistemdeki public dblinkler ile public synonym’ lere ait create scriptleri oluşturulacak. (toad burda da kullanılabilir)

Eski sunucudaki tnsnames.ora dosyasındaki diğer database’ lere ait aliaslar değiştirilmeden diğer tarafa da kopyalanacak. (dblinklerde problem çıkmaması için)Buraya kadar ki olan kısımlar, yapılacak migration öncesinde yapmamız gereken ön hazırlıklardı.

Şimdi operasyona başlıyoruz ;

 • Yeni ortama role’ leri (içleri boş olacak şekilde oluşturuyoruz. Burada henüz hiçbir obje olmadığı için zaten oluşturamayız, ancak create user scriptlerinde role’ lerde olduğundan hata vermemesi için bunları baştan oluşturuyoruz) 

Profile’ leri create ediyoruz. 

Userları create ediyoruz. 

Datafile’ leri taşıyoruz. 

Datafile taşımaları bittikden sonra almış olduğumuz transportable exportu yeni ortama import ediyoruz. impdp system directory=META_DATA_ISLEM dumpfile=DWDATA_TT_EXPORT.dmp logfile=IMP_DWDATA_TT_EXPORT.log  transport_datafiles=/s1/users01.dbf,test01.dbf,prod01.dbf • İmport bittikden sonra no rows exportun importuna geçmeden önce public db linkler ile public synonym’ leri burada create ediyoruz. 

No rows exportu import ediyoruz. 

Artık tablespace’ lerimizi read write moda geri alabiliriz.Normal şartlar altında işimiz bu kadar, artık kontrollerimize başlıyabiliriz. • Yeni sunucunun ip’ si farklı olacağından (tabi diğer sunucuyu kapatıp onun ip’ sini yeni sunucuya vermediyseniz)  diğer sunuculardaki tnsnames.ora dosyalarındaki taşıdığımız instance’ a ait ip (veya hostname hangisini kullanıyor iseniz) bilgisini yenisi ile değiştirmemiz gerekecektir. 

Tüm userların eski ortamda default tablespace’ i ne ise burada da aynısı yapılır. (yukarıda bunun backup scriptini oluşturmuştuk zaten)  

Grantlar kontrol edilir. Eski ortam ile karşılaştırılır. 

User create aşamasından hata almamak için rolleri boş olarak create etmiştik, şimdi o rollerin içini dolduruyoruz.

Burada yapılacak en önemli testi en sona sakladım. Önce user bazında nesne sayılarını her iki ortamda karşılaştırıyoruz. Yenisinde eksik olmamalı. select owner, count(*) from dba_objects  group by owner  order by 1 ;• User bazında yaptığımız karşılaştırmada nesne sayıları eksik çıkan user var ise sadece bu userlar için object type’ ı bazında hangi nesnelerin eksik olduğuna bakılmalıdır. Neden o objenin eksik olduğu araştırılabilir. Eski ortamdan create scripti hazırlanıp yeni ortamda basılarak eksik nesneler tamamlanır. select object_type,count(*) from dba_objects  where owner = ‘NESNESI_EKSIK_OLAN_USER'   group by object_type  order by 1 ;Aslında kontroller sonrasında problem olmadığını düşündüğünüz anda artık yeni sunucu üzerinden database’ imizi diğer kullanıcılara açabiliriz. Bu işlemin süresini etkileyen en önemli kriter database’ inizin büyüklüğü ve iki sunucu arasındaki network bağlantısı olduğunu söyleyebilirim. Zira biz yaklaşık 3 tb’ lik bir database’i bu yöntemle (kontroller dahil)  2,5 saat gibi bir sürede bitirebildik. 

Mihration çalışmalarımız son hızıyla devam ediyor, taşınacak bir sonraki database’ imiz yaklaşık 6 tb, en son Prod database’ imiz ise 19 tb büyüklüğünde, orda da farklı bir durumla karşılaşır isem buradan sizlerle paylaşacağım.

Kategori Dba
Salı, 22 Mart 2011 14:26

SQLite

Bu yazı daha önce saltokunur.org e-dergide yayınlanmıştır.

Şu senaryodaki durum masaüstü uygulamalar geliştiren çaylak-tecrübeli tüm geliştiricilerin başına gelebilir. Benim başına geldi oradan biliyorum :)

 

Programcının Çilesi


Hikâyemizde geliştiricimiz güzel bir program fikri bulur. Fikri gerçekleştirmek için platform, uygulama çatısı (Framework), programın yazılacağı dil... vb hazırdır. Geliştiricimiz programın işleyeceği verileri bir veri tabanında tutup, ilişkisel veri tabanlarının nimetlerinden faydalanmak istemektedir. İşte sorun da tam burada baş gösterir. Veri tabanı sunucusuna nasıl erişecektir? Uygulama masaüstü uygulama olduğu için çalışması için internet bağımlılığının olmaması gerekmektedir. Günümüz Türkiye şartlarında programı kullanan bütün bilgisayarların internete bağlı olamayacağı, olanların da zırt pırt kesilen bağlantı yüzünden programı adam gibi kullanamayacağı açıktır. Hem programcımız bu riski göze alıp, programı sürekli çevrimiçi olan veri tabanı (VT) sunucusuna bağlarsa, ücretsiz dağıttığı bir uygulama için bir VT sunucusu kiralamak zorunda kalacak, gelecekte belki programın kullanıcı kitlesi genişlediğinde o kadar veriyi tutacak VT sunucusu (VTS) bile bulamayabilecektir. Burada bir çözüm VTS'yi localhost'a kurup verileri bu şekilde işlemek olabilir. Ama şöyle bir gerçek var ki son kullanıcıların hepsi bir VT Yöneticisi değil. Düşünün bir kere dünyanın en çok kullanılan (bu yazıdan sonra aslında 2. olduğunu anlayacağınız :) MySQL'i uygulamanızla birlikte dağıttığınızı. Bugün en güncel MySQL 5.1 sürümü 104 MB, bir önceki 5.0 sürümü 22 MB [1]. Bu boyutta bir programı uygulama ile birlikte dağıtmak, kurulum dosyasını şişirmeye yarar, başka bir şeye değil. Hem MySQL'i kurduğumuzu düşünelim, kurmakla bitmiyor ki, root şifresi ayarlanacak, programın kullanacağı VT uygun karakter-kodlamayla oluşturulacak, MySQL hata verdiği zaman takip edilip düzeltilecek, dahası Windows güvenlik duvarı çalışmasına izin vermeyecek, gerekli olan port kullanımda olacak ve MySQL servisi başlatılamayacak. Biraz abartı gelebilir ama bu sorunlarım hepsi Windows üzerinde MySQL çalıştırılmak istenirken çok sık karşılaşılan sorunlar. Son kullanıcı bu sorunların hiçbiriyle baş edemez, onun için sadece "Next" vardır. "Next-Next-Next-(Bazen de Install :)"

Çözüm

Bu sorunun bir çözümü şu olabilir. Tecrübeli programcıların bile "Benden-Uzak-Allah'a-Yakın-Olsun" dediği, verileri bir dosyaya kaydetmek. Evet, çözüm basit gibi gözükse de programın işleyeceği verilerin yapısı karmaşıklaştıkça (bir VT'deki foreign key, trigger, function gibi yapıların getirdiği kolaylıkları düşünün) bunları bir dosya yapısına dökmek çoğu zaman geliştiricileri projelerinden soğutuyor. İşte bu ahval ve şerait içinde şöyle dediğinizi duyar gibiyim: "Keşke şöyle ne internete, ne sunucuya ne de ayara ihtiyaç duyan bir küçük program-kütüphane (library) olsa da, verileri VT biçiminde bir dosyaya kaydetse..."

Aslında yukarıda tırnak içinde yaptığım tanım SQLite için en basit ve anlaşılır tanım oldu. SQLite sunucu olmadan çalışan, hafif, küçük (tek bir dosya ve 500 KB den az), hiçbir ayara ihtiyaç duymayan, hızlı, SQL komutları kullanarak veri alış-verişi yapabilen bir ANSI-C kütüphanesidir. Kullanımı ise çok basittir. SQLite'ın kütüphane dosyasına (sqlite3.dll) SQL komutları gönderirsiniz, o da bu komutları işler ve bir VT dosyasına kaydeder. İstediğiniz zaman da SELECT sorguları çekerek bu dosyadan verilerinizi alabilirsiniz. Bu işlemler için ne bir ayar ne de bir kurulum gereklidir.

SQLite

SQLite, ilk olarak D. Richard Hipp tarafından geliştirilmeye başlandı ve 17 Ağustos 2000 tarihinde ilk sürümü yayınlandı. [2] İlk yayınlandığından bugüne kadar ki geçen zaman içinde temel VT işlemlerinin neredeyse tamamını gerçekleştirebilecek şekilde geliştirildi. Bu yazı yazıldığında en güncel sürümü 3.6.17 idi.

SQLite sadece bir C Kütüphanesi olduğu için, taşınabilirliği çok yüksektir. Günümüzün bilinen tüm platformlarında çalışabilir. Windows, Mac OS X, Linux, BSD, Solaris, UNIX, AmigaOS, Symbian, z/OS 1. [2]Gelecekte başka bir Veri Tabanı Yönetim Sistemi (VTYS)'ne geçilmek istendiğinde basit bir SQL sorgusuyla tüm veri alınıp rahatça diğer bir VTYS’ye geçilebilir.

Lisanslama

SQLite "Halka Açık" bir yazılımdır. Dağıtımı “Public Domain[3] altında yapılmaktadır. Kaynak kodu açıktır. Yani SQLite'i istediğiniz gibi kullanabilir, kodunu değiştirebilir (uygulamanızın kullanmayacağı özellikleri kaldırıp yeni özellikler ekleyebilir), ücretsiz-ticari, açık-kapalı kaynak bütün uygulamalarda hiçbir kısıtlama altına girmeksizin kullanabilir, SQLite ile geliştirdiğiniz bir uygulamadan gelir de elde edebilirsiniz.

Teknik Özellikler [2]

Teknik özelliklerinden bahsetmek gerekirse SQLite için boyundan büyük işler başarıyor diyebiliriz.

  • En Fazla VT dosyası boyutu: 32 TB
  • Bir Tablodaki En Fazla Sütun Sayısı: 32767
  • En Fazla Metin (String-Char) Veri Boyutu: 1 GB
  • En Fazla Blob (Binary) Veri Boyutu: 1 GB
  • En Fazla Number (Int-Double) Veri Boyutu: 64 bit

SQLite’in bir güzel özelliği de tam Unicode desteği sağlamasıdır. UTF-8 ve UTF-16 kodlamayı destekler.

SQLite transactional (işlemsel) bir VT kütüphanesidir. Sık kullanılan birçok ilişkisel SQL cümleciğini destekler. Bunlar: Union, Intersect, Except, Inner join, Outer join, Inner select, Merge join. Ayrıca VT içinde Trigger tanımlamaya da izin verir.

Tarih (date) veri tipini ve data domain, cursor, function, procedure gibi işlemleri desteklememesi SQLite’in şu anki sürümü itibariyle eksik yönleri.

SQLite'in en geniş dağıtıma ulaşmış VT motoru olduğu tahmin ediliyor. Bugün birçok program, işletim sistemi, cep telefonu, PDA hatta Mp3 oynatıcılar bile gömülü olarak SQLite kullanıyor. SQLite siz farkına bile varmadan çoktan bilgisayarınıza girmiş olabilir. Örnek vermek gerekirse, Firefox (120 milyon kopya) internet geçmişinizi tutmak için bir SQLite VT'si kullanıyor. Eğer Windows ortamında Firefox kullanıyorsanız "C:\Program Files\Mozilla Firefox" dizini altında "sqlite3.dll" dosyasını bulabilirsiniz. Ya da bir müzik oynatıcı olan AIMP2 şarkı listelerini yine SQLite VT'sinde tutuyor. Bunun Linux dünyasındaki karşılığı ise KDE kullanıcılarının çok iyi bildiği amorak. Yine amorak playlist'lerini SQLite VT'sinde saklıyor. Örnekler çoğaltılabilir, bugün PHP5 (20 milyon kopya) varsayılan olarak SQLite desteğiyle geliyor. Solaris (10 milyon kopya) sistemi boot ekmek için,  Philips mp3 çalarlar yine playlist'leri saklamak için, Skype (100 milyon kopya), iPhone da SMS’leri saklamak için hep gömülü olarak SQLite kullanıyor. Tüm bu dağıtımların toplamının yaklaşık 300 milyon olduğu tahmin ediliyor. Bu da SQLite’i dünyanın en geniş dağıtımlı SQL motoru yapıyor. [4]

Kullanımı

SQLite harici uygulama olarak çalıştırılacaksa Linux'ta konsoldan ya da Windows'ta komut satırından "SQLite3 vt_dosyasi_adi" komutuyla çalıştırılır. vt_dosyasi_adi dosyası yoksa SQLite kendi oluşturur. Bundan sonra (;) ile biten SQL komutlarını programa girerek normal bir VT sunusu gibi kullanılır.

SQLite’in VT hakkında bilgi veren ve üzerinde çeşitli işlemler yapan, komut satırından çalıştırılan bazı özel komutları da vardır. [8]

  • · Veritabanındaki tabloları görmek: sqlite> .tables
  • · Veritabanı konsolundan çıkmak: sqlite> .exit
  • · Kolon adlarını almak: sqlite> pragma table_info()
  • · Yardım: sqlite> .help
  • · Select çıktısına format vermek:
  • · Otomatik artan kolonun son değerini ele almak: sqlite> select last_insert_rowid();
  • · Veritabanını dışa aktarmak: sqlite> .dump
  • · Veritabanını sql scriptine aktarır:
  • · Konsolda veritabanını kopyalamak:
  • · SQL script ile veritabanında tablolar oluşturmak:

SQLite kütüphanesi bir program içinde gömülü olarak kullanılacaksa "#include " ile SQLite'in başlık dosyası kaynak koda eklenir. sqlite3_open() ile VT dosyası açılır, sqlite3_exec() ile SQL komutu işletilir ve sqlite3_close() ile VT bağlantısı kapatılır. [5]

SQLite'i gömülü olarak kullanmak için ille de C bilmeniz gerekmiyor. SQLite'in bilinen programlama dillerinin neredeyse tamamı için (C#, D, Delphi, Fortran, Java, Perl, PHP, Python, Ruby, Smalltalk…) sarıcı (wrapper) API’leri bulunuyor.[6] Böylece istediğiniz dilde uygulama geliştirirken SQLite’i kullanabiliyorsunuz.

Hız Karşılaştırmaları [7]

SQLite diğer VTYS'lerle karşılaştırıldığında INSERT sorgularında biraz geride kalıyor ama SELECT sorgularında çok daha hızlı sonuçlar veriyor.

Aşağıda SQLite 2.7.6, PostgreSQL 7.1.3 ve MySQL 3.23.41 kullanılarak yapılan hız testlerinin sonuçları yer alıyor. Süreler saniye cinsindendir. SQLite’in Nosync değerleri thread senkronlaması kapatılarak alınmıştır.

25000 INSERT Bir sorguda

100 SELECT indeksiz

1000 UPDATE indeksiz

SELECT’ten INSERT

DELETE indeksli

5000 SELECT indexli

PostgreSQL

4.900

3.629

1.739

61.364

1.316

4.614

MySQL

2.184

2.760

8.410

1.537

2.262

1.270

SQLite

0.914

2.494

0.637

2.787

2.068

1.121

SQLite (nosync)

0.757

2.526

0.638

1.599

0.752

1.162

SQLite üzerinde daha geniş araştırma yapmak isteyenler www.sqlite.org daki wiki'de kullanım, yönetim, bakım hakkında çok yararlı makaleler bulabilirler.

Kaynaklar

[1] www.mysql.com

[2] http://en.wikipedia.org/wiki/Comparison_of_relational_database_management_systems

[3] http://en.wikipedia.org/wiki/Public_Domain

[4] http://sqlite.org/mostdeployed.html

[5] M. Ali Vardar, Linux ve UNIX Sistemler İçin Açık Kaynak Kodlu Yazılım Geliştirme, Temmuz 2008

[6] http://www.sqlite.org/cvstrac/wiki?p=SqliteWrappers

[7] http://www.sqlite.org/speed.html

[8] http://gurcanyavuz.wordpress.com/2009/04/15/sqlite-veritabani/

Hamza Apaydın

Kategori Dba

Oracle zaman içerisinde yeni sürümlerini piyasaya sürdükçe bizlerde zamanı geldikçe kullandığımız oracle versiyonlarımızı bir üst sürüme upgrade etmek durumunda kalıyoruz. Oracle son 3 versiyonuna destek verdiğinden dolayı metalink üzerinden destek alıyorsanız kullandığınız versiyonunuz mutlaka 9i veya sonrası olmak zorunda, ki çok yakın bir tarihde 9i’ ninde desupported olacağını tahmin etmek zor olmasa gerek.

Bugün bu upgrade işlemi ile ilgili olarak öncesinde ve sonrasında yapılması gerekenleri anlatmaya çalışacağım.

Aşağıdaki örnekde 10gR1 – 10gR2 den 11gR2 ye upgrade işlemini kapsamaktadır.

İlk olarak upgrade edeceğimiz database’ in compatible seviyesini kontrol ediyoruz. Tüm upgrade’ ler için izlenmesi gereken bir yol vardır. Kimi sistemleri tek seferde istediğiniz versiyona upgrade edemiyor olabilirsiniz. Örneğin kullandığınız versiyon 9.2.0.3 ise bunu önce 9.2.0.8’ e sonrasında 11gR2 ye upgrade edebilirsiniz. Dolayısıyla bu kısım önemli ;

SELECT name, value FROM v$parameter

WHERE name = 'compatible';

NAME VALUE

compatible 10.1.0.5.0

Upgrade aşamaları ile ilgili hangi versiyondan hangisine geçebileceğinizi aşağıdaki tablolardan öğrenebilirsiniz.

Source Database                 Target Database 

9.2.0.8 or higher          è            11.2.x

10.1.0.5 or higher      è            11.2.x

10.2.0.2 or higher      è            11.2.x

11.1.0.6 or higher       è            11.2.x

Source Database                       Upgrade Path for             Target Database 

Target Database 

7.3.3 (or lower)               è      7.3.4 -> 9.2.0.8         è          11.2.x

8.0.5 (or lower)               è            8.0.6 -> 9.2.0.8         è     11.2.x

8.1.7 (or lower)                è     8.1.7.4 -> 10.2.0.4     è     11.2.x

9.0.1.3 (or lower)            è            9.0.1.4 -> 10.2.0.4     è   11.2.x

9.2.0.7(or lower)             è     9.2.0.8                      è   11.2.x

Öncelikle 11gR2 softwareinin farklı bir path’ e kuruyoruz. (sadece software, instance create etmiyoruz)

Kurulumu oracle userı yapıyoruz.

Upgrade yapacağımız database’ de read-only tablespace olup olmadığı kontrol edilir. Eğer olanlar var ise bunları upgrade işlemi bittikden sonra bir kereliğine read-write yapıp sonrasında tekrar read-only moda çekilebilir. Aynı şekilde offline olanlar var ise bir kereliğine online yapılıp datafile headerlarının güncellenmesi sağlanır. Sonra tekrar eski haline çekilebilir.

select * from dba_tablespaces where status <> 'ONLINE';

Oracle’a ait tüm nesnelerin VALID durumda olmaları gerekir. Bunun için aşağıdaki scriptlerden faydalanılabilir;

select substr(comp_name,1,40) comp_name, schema, status, substr(version,1,10) version from

dba_registry order by comp_name;

select substr(object_name,1,40) object_name,substr(owner,1,15) owner,object_type from

dba_objects where status='INVALID' order by owner,object_type;

select owner,object_type,count(*) from dba_objects where status='INVALID' group by
owner,object_type order by owner,object_type ;

Eğer invalid durumda nesne çıkar ise $ORACLE_HOME/rdbms/admin adresindeki utlrp.sql dosyası hiç invalid nesne kalmayıncaya kadar tekrar tekrar çalıştırılır. B işlemler upgrade yapılacak olan oracle versiyonunun home path’ inden yapılır.

$ sqlplus / as sysdba
SQL> @utlrp.sql 

SYS ve SYSTEM şemalarında aynı isimli nesne olup olmadığı kontrol edilir. Bunun için aşağıdaki sorgu çalıştırılır.

select object_name, object_type from dba_objects where object_name||object_type in  

(select object_name||object_type from dba_objects where owner = 'SYS') and owner = 'SYSTEM'; 

Sonuç olarak sadece aşağıdaki nesneler çıkmalıdır. Bunların dışından nesne çıkarsa Metalink1030426.6’a bakılır.

OBJECT_NAME                         OBJECT_TYPE
------------------------------                   -------------------
AQ$_SCHEDULES                       TABLE
AQ$_SCHEDULES_PRIMARY     INDEX
DBMS_REPCAT_AUTH               PACKAGE
DBMS_REPCAT_AUTH               PACKAGE BODY 

Upgrade öncesi kontrol aracı (Pre-Upgrade Information Tool) çalıştırılır. Bunun için sırasıyla ;

1. ORACLE_HOME(yeni)/rdbms/admin adresindeki utlu112i.sql ve utltzuv2.sql dosyaları geçici bir alana kopyalanır.

2. Geçici dizine girilir.

3. SQL*Plus(eski) ile veritabanına SYSDBA ayrıcalıklarıyla bağlanılır.

4. Spool açılır. SQL> SPOOL upgrade_info.log

5. Araç çalıştırılır. SQL> @utlu112i.sql

6. Bitince spool kapatılır. SQL> SPOOL OFF

7. upgrade_info.log kontrol edilip tüm WARNING’ler kontrol edilir.

WARNING: --> Database contains schemas with objects dependent on network packages.

Upgrade öncesi kontrol aracında (Pre-Upgrade Information Tool) yukarıdaki uyarı çıkmış ise kontrol edilir.

Veritabanında XML DB özelliğinin olup olmadığı aşağıdaki SQL ile kontrol edilir.

select comp_name "Component" from dba_registry;

XMLDB özelliği var ise, (bu component kullanılıyor ise) aşağıdaki SQL ile de hangi kullanıcıların bağımlılığı var diye kontrol edilir;

SELECT * FROM DBA_DEPENDENCIES

WHERE referenced_name IN ('UTL_TCP','UTL_SMTP','UTL_MAIL','UTL_HTTP','UTL_

INADDR') AND owner NOT IN ('SYS','PUBLIC','ORDPLUGINS');

Sorgudan çıkan kullanıcılar upgrade sonrası network access control list’lere (ACLs) gerekli yetkileri vermek üzere bir kenara not alınır. Zira bu kullanıcılar upgrade sonrası çalıştırılacak bir prosedürde kullanılacaktır. Yukarıdaki script web servisi kullanan kullanıcıları tespit ediyor, sonrasında uygulama sahibinden kullanılan tüm webservicelerin adresleri ve portları alınmalıdır. Upgrade sonrasında bu userlara network ACL yetkisi verilecektir.

Mevcut veritabanının tutarlılığı metalink Note 556610.1’dan indirilen  dbupgdiag.sql scripti çalıştırılarak kontrol edilir.

Metalink üyeliği olmayıpda test etmek isteyen arkadaşlar için scripti isterlerse gönderebilirim.

( Bu e-Posta adresi istek dışı postalardan korunmaktadır, görüntülüyebilmek için JavaScript etkinleştirilmelidir ) adresinden iletişime geçebilir varsa diğer sorularınızı da iletebilirsiniz.

Çalıştırmak için;

$ sqlplus / as sysdba
SQL> @dbupgdiag.sql

Eğer bu script invalid nesne döndürürse, (eski)$ORACLE_HOME/rdbms/admin adresindeki utlrp.sql dosyası hiç invalid nesne kalmayıncaya kadar tekrar tekrar çalıştırılır.

$ sqlplus / as sysdba
SQL> @utlrp.sql 

Sonra kontrol etmek için dbupgdiag.sql scripti tekrar çalıştırılır.

$ sqlplus / as sysdba
SQL> @ dbupgdiag.sql

Upgrade sonrasında CONNECT rolü sadece CREATE SESSION sistem yetkisi içerecek şekilde güncellenecektir. Eski versiyonlarda CONNECT rolünde başka yetkiler de vardı. Mevcut veritabanında CONNECT rolüne hangi yetkiler verilmiş tespit etmek için;

SELECT GRANTEE,PRIVILEGE FROM DBA_SYS_PRIVS WHERE GRANTEE ='CONNECT'; 

CREATE SESSION’dan başka yetki çıkarsa, CONNECT rolü atanmış kullanıcılardan upgrade sonrası bu yetkilerin gideceği hatırlanmalıdır. Dolayısıyla aşağıdaki script çalıştırılarak CONECT rolü hangi kullanıcılara atanmış tespit edilir. Gerekli önlemler alınarak upgrade sonrası hangi kullanıcıya hangi yetki atanacak tespit edilir. 

Aşağıdaki script ile CONNECT rolü CREATE SESSION sistem yetkisi haricinde hangi yetkilerde var ise onlara tekrar atamak için otomatik Grant scripti üretir. Bu scripti upgrade bittikden sonra çalıştıracağız.

select 'GRANT ' || a.privilege || ' TO ' || b.grantee ||';' from

(SELECT PRIVILEGE FROM DBA_SYS_PRIVS WHERE GRANTEE ='CONNECT') a,

(SELECT grantee FROM dba_role_privs WHERE granted_role = 'CONNECT' and grantee NOT IN (

'SYS', 'OUTLN', 'SYSTEM', 'CTXSYS', 'DBSNMP', 'LOGSTDBY_ADMINISTRATOR', 'ORDSYS',

'ORDPLUGINS', 'OEM_MONITOR', 'WKSYS', 'WKPROXY', 'WK_TEST', 'WKUSER', 'MDSYS', 'LBACSYS', 'DMSYS', 'WMSYS', 'EXFSYS', 'SYSMAN', 'MDDATA',

'SI_INFORMTN_SCHEMA', 'XDB', 'ODM')) b where a.privilege<> 'CREATE SESSION' ;

9.2 veya 10.1 sürümünden 11.2’ye geçerken database link’lerin şifreleri encrypt edilir. Yani upgrade sonrasında SYS.LINK$ tablosundan şifreleri göremeyiz. Herhangi bir sorundan dolayı veritabanını downgrade yapacak olursak bunun için şifreleri encrypt edilmiş dblink’leri drop etmemiz, işlemden sonra yeniden create etmemiz gerekir. lTabi bunun için de tüm bu işlemlerden önce dblink’lerin create scriptlerinin yedeğini almış olmamız gerekir. Bunun için aşağıdaki scripti kullanabilirsiniz ;

SELECT 'CREATE '||DECODE(U.NAME,'PUBLIC','public ')||'DATABASE LINK '||CHR(10)

||DECODE(U.NAME,'PUBLIC',Null, 'SYS','',U.NAME||'.')|| L.NAME||chr(10)

||'CONNECT TO ' || L.USERID || ' IDENTIFIED BY "'||L.PASSWORD||'" USING

'''||L.HOST||''''

||chr(10)||';' TEXT

FROM SYS.LINK$ L, SYS.USER$ U

WHERE L.OWNER# = U.USER#;

Time zone değeride kontrol etmemiz gereken diğer önemli bir konu.

11GR2’de TIME ZONE dosyasının versiyonu 11’dir. Mevcut veritabanının TIME ZONE dosya versiyonunu aşağıdaki script ile öğrenebiliriz.

select * from v$timezone_file; 

Zaten Upgrade öncesi kontrol aracı (Pre-Upgrade Information Tool) aşağıdaki uyarıyı vermiş ise mevcut veritabanının TIME ZONE dosyasının eski olduğunu öğrenmiş oluruz.

Example :
WARNING: -->Database is using a timezone file older than version 11.
.... After the release migration, it is suggested that DBMS_DST package
.... be used to upgrade the 11.1.0.6.0 database timezone version
.... to the latest version which comes with the new release. 

Eski TIME ZONE dosyasını upgrade sonrasında güncelleriz. Upgrade işlemi bittikden sonra bununla ilgili yapılacaklardan o kısımda hahsedeceğim. 

Mevcut veritabanının National Characterset’i (NLS_NCHAR_CHARACTERSET) aşağıdaki SQL ile kontrol edilir.

select value from NLS_DATABASE_PARAMETERS where parameter = 'NLS_NCHAR_CHARACTERSET';

UTF8 veya AL16UTF16 değilse, Note 276914.1’a bakılır. Burdaki adımlar takip edilir.

Upgrade öncesinde data dictionary tablo istatistiklerinin alınması tavsiye edilir. Zira bu sayede upgrade süresi kısaltacaktır. Çünkü upgrade sırasında istatistiği olmayan data dictionary tablolarının istatistiği alınır.

Upgrade öncesi kontrol aracı (Pre-Upgrade Information Tool) logunda hangi tabloların istatistiğinin eksik olduğu çıkar. Aşağıdaki script ile tüm data dictionary tablolarının istatistiği alınır. Tabi bu işlemin upgrade öncesinde yapılması son derece faydalı olur.

$ sqlplus /as sysdba
SQL> EXEC DBMS_STATS.GATHER_DICTIONARY_STATS; 

Oracle Database Vault varsa upgrade öncesinde kapatılması gerekir. Upgrade sonrasında tekrar açılır.

Spesifik bir konu olduğu için bu kısma girmeden kullanacaklar için metalink linklerini yazıyorum sadece.

Note 453903.1 - Enabling and Disabling Oracle Database Vault in UNIX
Note 453902.1 - Enabling and Disabling Oracle Database Vault in WINDOWS

Kontrol etmemiz gereken bir diğer adımımız Data Dictionary’de corruption olup olmadığıdır. Aşağıdaki scripti sysdba yetkili bir userla çalıştırmamız yeterli olacaktır.

Set verify off
Set space 0
Set line 120
Set heading off
Set feedback off
Set pages 1000
Spool analyze.sql

SELECT 'Analyze cluster "'||cluster_name||'" validate structure cascade;'
FROM dba_clusters
WHERE owner='SYS'
UNION
SELECT 'Analyze table "'||table_name||'" validate structure cascade;'
FROM dba_tables
WHERE owner='SYS'
AND partitioned='NO'
AND (iot_type='IOT' OR iot_type is NULL)
UNION
SELECT 'Analyze table "'||table_name||'" validate structure cascade into invalid_rows;'
FROM dba_tables
WHERE owner='SYS'
AND partitioned='YES';

spool off 

Bu işlemin ardından analyze.sql isimli bir dosya oluşur. Aşağıdaki işlemde bu dosya kullanılır.

(Hala upgrade işlemine başlamadığımız için upgrade scriptlerde geçen $ORACLE_HOME ibaresi eski oracle hpme dizinini kastetmektedir.)

$ sqlplus "/ as sysdba"
SQL> @$ORACLE_HOME/rdbms/admin/utlvalid.sql
SQL> @analyze.sql 

İkinci komutun çıktısı dinamik olarak takip edilmelidir. Zira herhangi bir log dosyası oluşturmaz. (dilerseniz bunuda bir txt file’ e yazdırabilirsiniz)

Tamamlanması gereken Materialized View refresh’lerin olup olmadığı aşağıdaki SQL ile kontrol edilip bitmeleri beklenir.

SELECT DISTINCT(TRUNC(last_refresh)) FROM dba_snapshot_refresh_times;

Kategori Dba

Log miner database’ in kurulumu ile birlikte gelen ve bir package yardımıyla create edilen bir opsiyon olarak düşünebiliriz. Yapabilirlikleri aslında kimi zaman herhangi bir geri dönüş operasyonuna kalkışmadan hızlı bir şekilde yapılmış olan bir hatayı düzeltebilmemize olanak sağlar. 

Log miner database seviyesinde yapılan bir takım işlemlerin geri alınabilmesi için izlenilen bir yöntemdir. Kullanımı ile ilgili olarak genelde  yanlışlıkla yapıldığı düşünülen bir DML işlemini geri almak için kullanılabilir diyebiliriz.

Log Miner’ ın kurulumu ve konfigure edilmesi ;

Log Miner’ ın çalışması için  SUPPLEMENTAL_LOG_DATA_MIN değerinin database’ de açık olması gerekmektedir. Aşağıdaki gibi kontrol edebilirsiniz ;

SQL> select SUPPLEMENTAL_LOG_DATA_MIN from v$database;


SUPPLEMENTAL_LOG_DATA_MIN

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

NO

Sonucun NO dönmesi durumunda aşağıdaki şekilde Alter edebiliriz ;

SQL> ALTER DATABASE ADD SUPPLEMENTAL LOG DATA;
Database altered.

Sonrasında log_miner’ ın ihtiyaç duyduğu nesnelerin create edilmesi için aşağıdaki dizindeki sql dosyası çalıştırılır.

SQL>@$ORACLE_HOME/rdbms/admin/dbmslm.sql

Paket yaratıldı.

Erişim Yetkisi verme başarılı.

Aşağıdaki yetkinin ilgili kullanıcıya

GRANT EXECUTE_CATALOG_ROLE TO kamil;

Grant complete.

Package kolay erişim için public synonym tanımlanabilir. (schema name’ i kullanılarak da erişilebilir.)

CREATE PUBLIC SYNONYM DBMS_LOGMNR FOR SYS.DBMS_LOGMNR;

Synonym created. 

Log_miner’ ın redologları okuması için log_miner’ a tanıtılması, eklenmesi gerekmektedir. Bunun için önce loglarımıza bakalım ;

SQL> SELECT distinct member LOGFILENAME FROM V$LOGFILE;

LOGFILENAME

C:\ORACLE\10GR2\ORADATA\TEST\REDO02.LOG

C:\ORACLE\10GR2\ORADATA\TEST\REDO01.LOG

C:\ORACLE\10GR2\ORADATA\TEST\REDO03.LOG

Log_miner package’ ina okuması için dahil etmek için;

BEGIN DBMS_LOGMNR.ADD_LOGFILE

('C:\ORACLE\10GR2\ORADATA\TEST\REDO01.LOG'); 

DBMS_LOGMNR.ADD_LOGFILE 

('C:\ORACLE\10GR2\ORADATA\TEST\REDO02.LOG'); 

DBMS_LOGMNR.ADD_LOGFILE 

('C:\ORACLE\10GR2\ORADATA\TEST\REDO03.LOG'); 

END;

/

PL/SQL procedure successfully completed. 

Bakacağı son archive’ ı görmek için ;

SELECT NAME FROM V$ARCHIVED_LOG
WHERE FIRST_TIME = (SELECT MAX(FIRST_TIME) FROM V$ARCHIVED_LOG);



NAME

C:\ORACLE\10GR2\FLASH_RECOVERY_AREA\TEST\ARCHIVELOG\2011_02_08\O1_MF_1_11_6O2RV9M1_.ARC

C:\ORACLE\10GR2\FLASH_RECOVERY_AREA\TEST\ARCHIVELOG\2011_02_08\O1_MF_1_12_6O2RVHG5_.ARC

Log_Miner kurulumu tamamlanmış oldu, şimdi start ediyoruz ;

BEGIN
DBMS_LOGMNR.START_LOGMNR
(options => 
dbms_logmnr.dict_from_online_catalog);
END;
/
 

PL/SQL procedure successfully completed. 

Sonuçları Select etmek içinse  v$logmnr_contents view’ ini kullanabiliriz.

SELECT   username,

TO_CHAR (timestamp, 'mm/dd/yy hh24:mi:ss') timestamp,

seg_type_name,

seg_name,

table_space,

session# SID,

serial#,

operation,

sql_redo,

sql_undo,

session_info

FROM   v$logmnr_contents

Şimdi bir test yapalım, user_test adında bir userımız var, bu userla önce bir tablo create edelim, sonrasında içerisinde data insert edelim. En son olarak da yaptığımız bu işlemin yanlış olduğunu varsayıp nasıl düzeltebileceğimize bakalım.

create table log_miner_test as select * from dba_tables where rownum < 2 ; 

Table created. 

insert into log_miner_test select * from log_miner_test ; 

1 row created. 

commit 

Commit complete. 

v$logmnr_contents  tablosundan select ediyoruz.

SELECT   username, 

TO_CHAR (timestamp, 'mm/dd/yy hh24:mi:ss') timestamp, 

seg_type_name, 

seg_name, 

table_space, 

session# SID, 

serial#, 

operation, 

sql_redo, 

sql_undo, 

session_info 

FROM   v$logmnr_contents 

where seg_name = 'LOG_MINER_TEST' 

and username = 'USER_TEST' 

Selectin çıktısı olarak sql_redo, sql_undo ve session_info kısımlarını ayrı olarak ekliyorum ; 

USERNAME 

TIMESTAMP 

SEG_NAME 

TABLE_SPACE 

SID 

SERIAL# 

OPERATION 

USER_TEST

02.08.2011 17:59

LOG_MINER_TEST

128

49

DDL

USER_TEST

02.08.2011 18:00

LOG_MINER_TEST

TEST_TBS

128

49

INSERT

Sql_redo;

insert into "USER_TEST"."LOG_MINER_TEST"("OWNER","TABLE_NAME","TABLESPACE_NAME","CLUSTER_NAME","IOT_NAME","STATUS","PCT_FREE","PCT_USED","INI_TRANS","MAX_TRANS","INITIAL_EXTENT","NEXT_EXTENT","MIN_EXTENTS","MAX_EXTENTS","PCT_INCREASE","FREELISTS","FREELIST_GROUPS","LOGGING","BACKED_UP","NUM_ROWS","BLOCKS","EMPTY_BLOCKS","AVG_SPACE","CHAIN_CNT","AVG_ROW_LEN","AVG_SPACE_FREELIST_BLOCKS","NUM_FREELIST_BLOCKS","DEGREE","INSTANCES","CACHE","TABLE_LOCK","SAMPLE_SIZE","LAST_ANALYZED","PARTITIONED","IOT_TYPE","TEMPORARY","SECONDARY","NESTED","BUFFER_POOL","ROW_MOVEMENT","GLOBAL_STATS","USER_STATS","DURATION","SKIP_CORRUPT","MONITORING","CLUSTER_OWNER","DEPENDENCIES","COMPRESSION","DROPPED") values ('SYS','CON$','SYSTEM',NULL,NULL,'VALID','10','40','1','255','65536',NULL,'1','2147483645',NULL,'1','1','YES','N','2786','12','0','0','0','20','0','0','         1','         1','    N','ENABLED','2786',TO_DATE('30/08/2005', 'DD/MM/RRRR'),'NO',NULL,'N','N','NO','DEFAULT','DISABLED','YES','NO',NULL,'DISABLED','YES',NULL,'DISABLED','DISABLED','NO');

sql_undo;

delete from "USER_TEST"."LOG_MINER_TEST" where "OWNER" = 'SYS' and "TABLE_NAME" = 'CON$' and "TABLESPACE_NAME" = 'SYSTEM' and "CLUSTER_NAME" IS NULL and "IOT_NAME" IS NULL and "STATUS" = 'VALID' and "PCT_FREE" = '10' and "PCT_USED" = '40' and "INI_TRANS" = '1' and "MAX_TRANS" = '255' and "INITIAL_EXTENT" = '65536' and "NEXT_EXTENT" IS NULL and "MIN_EXTENTS" = '1' and "MAX_EXTENTS" = '2147483645' and "PCT_INCREASE" IS NULL and "FREELISTS" = '1' and "FREELIST_GROUPS" = '1' and "LOGGING" = 'YES' and "BACKED_UP" = 'N' and "NUM_ROWS" = '2786' and "BLOCKS" = '12' and "EMPTY_BLOCKS" = '0' and "AVG_SPACE" = '0' and "CHAIN_CNT" = '0' and "AVG_ROW_LEN" = '20' and "AVG_SPACE_FREELIST_BLOCKS" = '0' and "NUM_FREELIST_BLOCKS" = '0' and "DEGREE" = '         1' and "INSTANCES" = '         1' and "CACHE" = '    N' and "TABLE_LOCK" = 'ENABLED' and "SAMPLE_SIZE" = '2786' and "LAST_ANALYZED" = TO_DATE('30/08/2005', 'DD/MM/RRRR') and "PARTITIONED" = 'NO' and "IOT_TYPE" IS NULL and "TEMPORARY" = 'N' and "SECONDARY" = 'N' and "NESTED" = 'NO' and "BUFFER_POOL" = 'DEFAULT' and "ROW_MOVEMENT" = 'DISABLED' and "GLOBAL_STATS" = 'YES' and "USER_STATS" = 'NO' and "DURATION" IS NULL and "SKIP_CORRUPT" = 'DISABLED' and "MONITORING" = 'YES' and "CLUSTER_OWNER" IS NULL and "DEPENDENCIES" = 'DISABLED' and "COMPRESSION" = 'DISABLED' and "DROPPED" = 'NO' and ROWID = 'AAAMmXAAHAAAAKNAAA';

session_info;

login_username=USER_TEST client_info= OS_username=WINDB\Administrator Machine_name=CB\WINDB OS_terminal=WINDB OS_process_id=4720:488 OS_program_name=toad.exe

görüldüğü üzere yapmış olduğumuz insert işlemine karşılık sorunu düzeltmek adına delete scriptini verdi, delete işlemi yapmış olsaydık insert scriptini verecekti.

Son olarak log miner’ ın çalışma şeklinden biraz bahsetmek gerekirse, ana mantığı redologları okumaktan geçiyor sonrasında ise çıkan archive’ lar üzerinden okumaya devam ediyor. Dolayısıyla geçmişe dönük ne kadar archive’ ınız var ise o kadar geriye gidebilirsiniz demektir.

Kategori Dba

Tablo ve indexler üzerinde DDL işlemlerinin nasıl yapılacapı konsunda zaman zaman yazılar yazıyoruz. Örneğin tablo ve indexlerin farklı bir tablespace taşınması ile ilgili 

(http://kamilturkyilmaz.blogspot.com/2010/10/tablo-ve-indexlerin-tasnmas_25.html) bir yazı yazmıştım. Burada ise logsegment ve logindexleri anlatmaya çalışacağım.  

Aslında burada bahsedilmesi gereken en önemli konu lobs ların taşınması olduğunu düşünüyorum. Dolayısıyla naşıl taşıyabiliriz sorusuna cevap ararken diğer yapılacak işlemlerinde sırasıyla üzerinden geçmeyi planlıyorum.  

Öncelikle üzerinde çalışabileceğimiz lob alan içeren bir tablo create edelim. 

CREATE TABLE deneme_lob ( 

ad VARCHAR2(30), 

soyad VARCHAR2(30), 

resim1 BLOB, 

resim2 BFILE, 

resim3 clob); 

Table created 

Create edilen her lob alanı için otomatik olarak bir logsegmenti ile lobindexi create edilir. Create etmiş olduğumuz tabloya ilişkin lob alanları sorguladığımızda da bunları görebiliyor oluruz. 

SELECT  segment_name , 

segment_type , 

tablespace_name tbs_name 

FROM user_segments 

WHERE segment_name like 'SYS_LOB%' 

OR segment_name like 'SYS_IL%' 

SEGMENT_NAME                                           SEGMENT_TYPE    TBS_NAME 

SYS_IL0000051350C00005$$                       LOBINDEX               TEST1 

SYS_LOB0000051350C00005$$                   LOBSEGMENT       TEST1 

SYS_IL0000051350C00003$$                        LOBINDEX               TEST1 

SYS_LOB0000051350C00003$$                   LOBSEGMENT       TEST1 

Bu örneğimizde create edilen tablomuz test1 tablespace2 inde yer alıyor. Şimdi tablo üzerinde oynamadan son durumda hangi nesnenin nerde saklandığını tekrar kontrol edelim ; 

SELECT  owner, segment_name seg_name, 

segment_type seg_type, 

tablespace_name tbs_name 

FROM dba_segments  

WHERE owner = 'KAMIL' 

OWNER        SEG_NAME                                                SEG_TYPE              TBS_NAME 

KAMIL            DENEME_LOB                                          TABLE                       TEST1 

KAMIL            SYS_IL0000051350C00005$$                LOBINDEX               TEST1 

KAMIL            SYS_LOB0000051350C00005$$           LOBSEGMENT        TEST1

KAMIL            SYS_IL0000051350C00003$$                LOBINDEX               TEST1

KAMIL            SYS_LOB0000051350C00003$$           LOBSEGMENT        TEST1

Tüm nesnelerimiz TEST1 tablesspace’ inde.

Tablomuza yeni bir lob alan ekleyelim;

alter table deneme_lob

add (resim4 blob)

ekledik, şimdi bir tane alan ekleyelim ancak bu farklı bir tablespace’ de store ediliyor olsun ;

alter table deneme_lob

add (resim5 blob)

lob (resim5) store as resim5_seg

(tablespace test2)

Kontrol ediyorum ;

SELECT   owner,

segment_name seg_name,

segment_type seg_type,

tablespace_name tbs_name

FROM   dba_segments

WHERE   owner = 'KAMIL'

OWNER        SEG_NAME                                                     SEG_TYPE              TBS_NAME

KAMIL            DENEME_LOB                                                TABLE                       TEST1

KAMIL            SYS_IL0000051350C00005$$                     LOBINDEX               TEST1

KAMIL            SYS_LOB0000051350C00005$$                LOBSEGMENT        TEST1

KAMIL            SYS_IL0000051350C00003$$                     LOBINDEX               TEST1

KAMIL            SYS_LOB0000051350C00003$$                LOBSEGMENT        TEST1

KAMIL            SYS_IL0000051350C00006$$                     LOBINDEX               TEST1

KAMIL            SYS_LOB0000051350C00006$$                LOBSEGMENT        TEST1

KAMIL            SYS_IL0000051350C00007$$                     LOBINDEX               TEST2

KAMIL            RESIM5_SEG                                                  LOBSEGMENT        TEST2

Tamam yeni alanımız istediğimiz gibi test2 tablespace’ inde store edilecek şekilde create edilmiş oldu.

Şimdi test1 tablespace' inde yer resim1 alanına ait lob segmentlerini test3 tablespace' ine taşıyalım.

ALTER TABLE deneme_lob

MOVE LOB(resim1) STORE AS (TABLESPACE test3)

Table altered.

SELECT   owner,

segment_name seg_name,

segment_type seg_type,

tablespace_name tbs_name

FROM   dba_segments

WHERE   owner = 'KAMIL'

OWNER        SEG_NAME                                                   SEG_TYPE  TBS_NAME

KAMIL            DENEME_LOB                                             TABLE                       TEST1

KAMIL            SYS_IL0000051350C00005$$                        LOBINDEX                  TEST1

KAMIL            SYS_LOB0000051350C00005$$                    LOBSEGMENT           TEST1

KAMIL            SYS_IL0000051350C00003$$                        LOBINDEX                  TEST3

KAMIL            SYS_LOB0000051350C00003$$                    LOBSEGMENT           TEST3

KAMIL            SYS_IL0000051350C00006$$                        LOBINDEX                  TEST1

KAMIL            SYS_LOB0000051350C00006$$                    LOBSEGMENT           TEST1

KAMIL            SYS_IL0000051350C00007$$                        LOBINDEX                  TEST2

KAMIL            RESIM5_SEG                                              LOBSEGMENT           TEST2

Evet, resim alanına ait tüm lob segmentler test3 tablespace’ ine taşınmış oldu. Yukarıdaki örneklerde tablo’ nun tablespace’ ine dokunmadan sadece lob alanlarının tablespace’ lerini değiştirmiştik. Şimdi resim4 alanı ile beraber tablonun tablespace’ inide değiştirellim ;

ALTER TABLE deneme_lob

MOVE TABLESPACE test4 LOB (resim4) STORE AS (TABLESPACE test4)

Kontrol edelim ;

SELECT   owner,

segment_name seg_name,

segment_type seg_type,

tablespace_name tbs_name

FROM   dba_segments

WHERE   owner = 'KAMIL'

OWNER        SEG_NAME                                                SEG_TYPE              TBS_NAME

KAMIL            DENEME_LOB                                          TABLE                       TEST4

KAMIL            SYS_IL0000051350C00005$$                      LOBINDEX                 TEST1

KAMIL            SYS_LOB0000051350C00005$$                  LOBSEGMENT          TEST1

KAMIL            SYS_IL0000051350C00003$$                      LOBINDEX                 TEST3

KAMIL            SYS_LOB0000051350C00003$$                  LOBSEGMENT          TEST3

KAMIL            SYS_IL0000051350C00006$$                      LOBINDEX                 TEST4

KAMIL            SYS_LOB0000051350C00006$$                  LOBSEGMENT          TEST4

KAMIL            SYS_IL0000051350C00007$$                      LOBINDEX                 TEST2

KAMIL            RESIM5_SEG                                            LOBSEGMENT          TEST2

Resim4 alanı ile birlikte tablonun tablespace’ inide değiştirmiş olduk.

Lobindexlerin nasıl rebuild edilebileceğinden bahsedelim, bilindik rebuild index komutu ile lobindexleri rebuild etmek istediğimizde aşağıdaki gibi hata alırız. Lobindexleri rebuild etmek istiyorsak (bulundukları tablespace’ e)  move komutu

taşımak suretiyle rebuild etmiş oluruz.

Alter index SYS_IL0000051350C00005$$ rebuild tablespace test1

Error at line 1

ORA-02327: LOB veri türündeki ifade için dizin yaratılamaz

Kategori Dba

Özellikle Rman ile bir database’ in backupını başka bir ortama kurduğumuzda database’ in dbid ve db_name değerleri asıl ortamda ne ise burda da aynı olur. Dolayısıyla bu şekilde yeni bir database create ettikden sonra elimizdeki bu yeni ortamın bu değerlerini değiştirmek isteyebiliriz. (özelliklede rman catalog database’ i kullanarak database’ lerimizin backupını alıyorsak, dbid bizim için son derece önemli olacaktır)


Şimdi değişikliğe başlamadan önce dbid ve db_name’ in şu anki değerlerine bakalım (bu değerleri sonradan işlem yapılırken de görebiliriz) ;

SQL> select dbid, name from v$database;
DBID                NAME
----------         ----------
4271840000     KTEST

Öncelikle aşağıdaki dizinde init ve spfile dosyasının olduğundan emin olun. İlgili dizin ;

Linux ortam üzerinde çalışıyorsanız ;

cd $ORACLE_HOME/dbs

Windows üzerinde çalışıyorsanız;

cd $ORACLE_HOME/database

Sonra database’ imizi immediate ile kapatıyoruz.

C:\Documents and Settings\oracle>sqlplus "/as sysdba"
SQL*Plus: Release 11.2.0.1.0 Production on Wed Feb 2 22:39:01 2011
Copyright (c) 1982, 2010, Oracle. All rights reserved.
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
With the Partitioning, Oracle Label Security, OLAP, Data Mining and Oracle Database Vault options
SQL> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.

SQL> startup mount
ORACLE instance started.
Total System Global Area 627732480 bytes
Fixed Size 1376408 bytes
Variable Size 184553320 bytes
Database Buffers 436207616 bytes
Redo Buffers 5595136 bytes
Database mounted.
SQL>

Mount ile database’i start ettikden sonra, komut satırından aşağıdaki komutu çalıştırıyoruz. Bu konuttaki “nid” bizim dbid ve db_name’ i değiştirmemizi sağlayacak olan komutumuz, target kısmı database’ in şu anki sys userı ve onun şifresi @ kısmı ise database’ imizin db_name’ini, dbname = parametresi ise database’ in yeni name’ mini ifade etmektedir.

nid

C:\Documents and Settings\oracle>nid DBNAME=KAMIL
DBNEWID: Release 11.2.0.1.0 - Production on Wed Feb 2 22:40:29 2011
Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved.
Connected to database KTEST (DBID=4271840000)
Connected to server version 11.2.0
Control Files in database:
C:\ORACLE11GR2\ORADATA\KTEST\CONTROL01.CTL
C:\ORACLE11GR2\FLASH_RECOVERY_AREA\KTEST\CONTROL02.CTL
Change database ID and database name KTEST to KAMIL? (Y/[N]) => Y
Proceeding with operation
Changing database ID from 4271840000 to 3000141920
Changing database name from KTEST to KAMIL
Control File C:\ORACLE11GR2\ORADATA\KTEST\CONTROL01.CTL - modified
Control File C:\ORACLE11GR2\FLASH_RECOVERY_AREA\KTEST\CONTROL02.CTL - modified
Datafile C:\ORACLE11GR2\ORADATA\KTEST\SYSTEM01.DB - dbid changed, wrote newname
Datafile C:\ORACLE11GR2\ORADATA\KTEST\SYSAUX01.DB - dbid changed, wrote newname
Datafile C:\ORACLE11GR2\ORADATA\KTEST\UNDOTBS01.DB - dbid changed, wrote new name
Datafile C:\ORACLE11GR2\ORADATA\KTEST\USERS01.DB - dbid changed, wrote new name
Datafile C:\ORACLE11GR2\ORADATA\KTEST\TEMP01.DB - dbid changed, wrote new name
Control File C:\ORACLE11GR2\ORADATA\KTEST\CONTROL01.CTL - dbid changed, wrote new me
Control File C:\ORACLE11GR2\FLASH_RECOVERY_AREA\KTEST\CONTROL02.CTL - dbid changed, wrote new name
Instance shut down
Database name changed to KAMIL.
Modify parameter file and generate a new password file before restarting.
Database ID for database KAMIL changed to 3000141920.
All previous backups and archived redo logs for this database are unusable.
Database is not aware of previous backups and archived logs in Recovery Area.
Database has been shutdown, open database with RESETLOGS option.
Succesfully changed database name and ID.
DBNEWID - Completed succesfully.

Yukarıdaki mesajları başarıyla almış olmamız gerekiyor.
Bundan sonraki kısımda ;

Database’ i nomunt modda açıyoruz.

SQL> startup mount
ORACLE instance started.
Total System Global Area 627732480 bytes
Fixed Size 1376408 bytes
Variable Size 184553320 bytes
Database Buffers 436207616 bytes
Redo Buffers 5595136 bytes

Yapılan bu değişikliği aşağıdaki Alter ile de system üzerinden spfile’ e yazdırıyoruz.

SQL> ALTER SYSTEM SET DB_NAME=KAMIL SCOPE=SPFILE;
System altered.

Şimdi immediate ile tekrar kapatıyoruz ;

SQL> shutdown immediate
ORA-01507: database not mounted
ORACLE instance shut down.

Aslında bundan sonraki kısım klasik database operayonları gibi düşünebiliriz. Database’in name’ I değiştiğinden dolayı ona uygun bir password file create etmemiz gerekiyor. Ek olarak spfile dosyamızın adını da yeni SID’ imizi içerek şekilde rename edeceğiz.

orapwd file=C:\oracle11gR2\product\pwdKAMIL.ora password=oracle entries=5

Ben bu çalışmamı windows bir sunucu üzerinde yaptığımdan dolayı ..\database\ dizinindeki spfileKTEST.ora dosyasının adını spfileKAMIL.ora olacak şekilde rename ediyorum.

Yine windowslar için unutulmaması gereken bir nokta database ilk create ederken windows servisleride create ettiğinden dolayı (oracle servisleri SID bazında create edilmekte) bu servisleri de değiştirmemiz gerekiyor. Yani eski SID’ li servis tanımı silinip yerine yeni SID’ li servis tanımını eklememiz gerekiyor.

Eski tanımı silmek için ;

C:\Documents and Settings\oracle>oradim -delete -sid KTEST
Instance deleted.

Yenisini eklemek içinse;

C:\Documents and Settings\oracle>oradim -new -sid KAMIL -intpwd oracle –startmode a -pfile C:\oracle11gR2\product\spfileKAMIL.ora
Instance created.

Yapılan bu değişiklikden listener’ ında etkilenmesi için stop / start yapıyoruz.

C:\Documents and Settings\oracle>lsnrctl stop
LSNRCTL for 32-bit Windows: Version 11.2.0.1.0 - Production on 02-FEB-2011 23:29:07
Copyright (c) 1991, 2010, Oracle. All rights reserved.
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=dataguart)(PORT=1521)))
The command completed successfully

C:\Documents and Settings\oracle>lsnrctl start
LSNRCTL for 32-bit Windows: Version 11.2.0.1.0 - Production on 02-FEB-2011 23:29:12
Copyright (c) 1991, 2010, Oracle. All rights reserved.
Starting tnslsnr: please wait...
TNSLSNR for 32-bit Windows: Version 11.2.0.1.0 - Production
System parameter file is c:\oracle11gR2\product\network\admin\listener.ora
Log messages written to c:\oracle11gr2\diag\tnslsnr\dataguart\listener\alert\log.xml
Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=dataguart)(PORT=1521)))
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=dataguart)(PORT=1521)))
STATUS of the LISTENER
------------------------
Alias LISTENER
Version TNSLSNR for 32-bit Windows: Version 11.2.0.1.0 - Produ
ction
Start Date 02-FEB-2011 23:29:16
Uptime 0 days 0 hr. 0 min. 5 sec
Trace Level off
Security ON: Local OS Authentication
SNMP OFF
Listener Parameter File c:\oracle11gR2\product\network\admin\listener.ora
Listener Log File c:\oracle11gr2\diag\tnslsnr\dataguart\listener\alert\log.xml
Listening Endpoints Summary...
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=dataguart)(PORT=1521)))
Services Summary...
Service "CLRExtProc" has 1 instance(s).
Instance "CLRExtProc", status UNKNOWN, has 1 handler(s) for this service...
The command completed successfully
C:\Documents and Settings\oracle>

Buraya kadar herşey yolunda, artık yeni spfile’ imiz ile database’ imizi açabiliriz. Ancak database’ i startup ile açmayacağız. Database’ in dbid ve name’ I değiştiğinden dolayı, bu database’ den alınmış olan backuplar artık kullanılamaz duruma gelmiştir çünkü artık dbid ve name’ ler farklı, dolayısıyla database’ in hayata sıfırdan yeni bir başlangıç yapması için open RESETLOGS ile açmamız gerekiyor (başka türlü açılamaz) ;

SQL> startup mount
ORACLE instance started.
Total System Global Area 627732480 bytes
Fixed Size 1376408 bytes
Variable Size 184553320 bytes
Database Buffers 436207616 bytes
Redo Buffers 5595136 bytes
Database mounted.
SQL> alter database open resetlogs ;
Database altered.

Şimdi yeni dbid ve name değerlerimizi kontrol edelim.

SQL> select dbid, name from v$database;
DBID                NAME
----------          ---------
3000141920     KAMIL

Database’ in sadece DBID’ sini veya DB_NAME’ ini de değiştirebilirsiniz, şöyleki ;

Sadece DBID değiştirmek isterseniz ;

nid çalıştırmanız yeterli olacaktır. Bu komut sadece dbid’ yi değiştirecektir ve name aynı kalacaktır. Burada db_name’ dokunmadığımız için spfile veya pasword file üzerinde vir değişiklik yapmamıza gerek yok, sadece open RESETLOGS ile açmamız yeterli olacaktır.

Sadece DB_NAME’ i değiştirmek istersenizde

nid SETNAME=YES komutunu çalıştırmamız yeterli olacaktır. BU komutta dbid’ ye dokunmadan sadece name’ I değiştirecektir. Diğer adımlar yukarıdakiler ile aynı.

Bu işleme aslında çok sık olmasa da rman’ le create ettiğimiz yeni database’ imizi başka bir projede PROD olarak kullanmamız gerektiğinde veya kullanılan bir database farklı bir projede kullanılacaksa ona uygun bir name verilmek istendiğinde kullanılabilirsiniz.

Kategori Dba

Bundan önceki yazımda AWR’ ın kullanımı ile giriş yaparak, AWR aracılığı ile snaphotları nasıl create, drop ederizden bahsettik. Şimdi alınan bu snaphotlara ait raporları nasıl compare ederiz buna bakacağız. Özetle şunu yapmaya çalışıyoruz aslında database’ de yaşanan bir performans probleminin ne boyutta olduğuna veya aynı dönemi kapsayan başka bir aralığa göre problemin neden kaynaklandığını, yoğunluk olarak hangi alanlarda artış olduğunu görebilmek ve içinde bulunduğumuz durumu daha iyi yorumlayabilmek için karşılaştırma yapabiliriz. 

Şöyle bir problem olduğunu varsayalım. Her gün saat 09:00 ile 11:00 arasında database’ imizin performansı stabil iken, gün içerisinde bu saatler aralığında performansın ciddi bir şekilde düştüğünü varsayalım. Buradaki sorunu tespit içinde dün ile bugün aynı saatler aralığını gösteren AWR raporlarını compare etmeye çalışalım. (bu işlemi konsol üzerinden grafik ekranda çok rahatlıkla yapabilirsiniz ancak biz ortada bir problem var iken konsolun çalışmama riskini gözönünde bulundurarak komut satırından yapmaya çalışacağız) 

Bu işlemler için dba yetkisi gerektiğini tekrar hatırlatalım. 

Komut satırından scriptimizin yer aldığı awrddrpt.sql dosyasını çalıştırıyoruz.

@$ORACLE_HOME/rdbms/admin/awrddrpt.sql 

Sonrasında yapılan işlemlerle ilgili loglarıda ekliyorum ; 

SQL> @$ORACLE_HOME/rdbms/admin/awrddrpt.sql 

Current Instance 

~~~~~~~~~~~~~~~~ 

DB Id DB Id DB Name Inst Num Inst Num Instance

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

2656835042 2656835042 TEST                 1 1 TEST

Specify the Report Type 

~~~~~~~~~~~~~~~~~~~~~~~ 

Would you like an HTML report, or a plain text report? 

Enter 'html' for an HTML report, or 'text' for plain text 

Defaults to 'html' 

Enter value for report_type: text 

Type Specified: text

Instances in this Workload Repository schema 

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 

DB Id Inst Num DB Name Instance Host

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

* 2656835042 1 TEST          TEST          tester

Database Id and Instance Number for the First Pair of Snapshots 

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 

Using 2656835042 for Database Id for the first pair of snapshots 

Using 1 for Instance Number for the first pair of snapshots

Specify the number of days of snapshots to choose from 

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 

Entering the number of days (n) will result in the most recent 

(n) days of snapshots being listed. Pressing without

specifying a number lists all completed snapshots. 

Enter value for num_days: 2 

Listing the last 2 days of Completed Snapshots 

Snap

Instance DB Name Snap Id Snap Started Level

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

TEST TEST     6480 22 Feb 2011 00:00      1

                       6481 22 Feb 2011 01:00      1

                       6482 22 Feb 2011 02:00      1

                       6483 22 Feb 2011 03:00      1

                       6484 22 Feb 2011 04:00      1

                       6485 22 Feb 2011 05:00      1

                       6486 22 Feb 2011 06:00      1

                       6487 22 Feb 2011 07:00      1

                       6488 22 Feb 2011 08:00      1

                       6489 22 Feb 2011 09:00      1

                       6490 22 Feb 2011 10:00      1

                       6491 22 Feb 2011 11:00      1

                       6492 22 Feb 2011 12:00      1

                       6493 22 Feb 2011 12:48      1

                       6494 22 Feb 2011 12:48      2

                       6496 22 Feb 2011 14:00      1

                       6497 22 Feb 2011 15:00      1

                       6498 22 Feb 2011 16:00      1

                       6499 22 Feb 2011 17:00      1

                       6500 22 Feb 2011 18:00      1

                       6501 22 Feb 2011 19:00      1

                       6502 22 Feb 2011 20:00      1

                       6503 22 Feb 2011 21:00      1

                       6504 22 Feb 2011 22:00      1

                       6505 22 Feb 2011 23:00      1

                       6506 23 Feb 2011 00:00      1

                       6507 23 Feb 2011 01:00      1

                       6508 23 Feb 2011 02:00      1

                       6509 23 Feb 2011 03:00      1

                       6510 23 Feb 2011 04:00      1

                       6511 23 Feb 2011 05:00      1

                       6512 23 Feb 2011 06:00      1

                       6513 23 Feb 2011 07:00      1

                       6514 23 Feb 2011 08:00      1

                       6515 23 Feb 2011 09:00      1

                       6516 23 Feb 2011 10:00      1

                       6517 23 Feb 2011 11:00      1

                       6518 23 Feb 2011 12:00      1

                       6519 23 Feb 2011 13:00      1

                       6520 23 Feb 2011 14:00      1

                       6521 23 Feb 2011 15:00      1

                      6522 23 Feb 2011 16:00      1

Specify the First Pair of Begin and End Snapshot Ids

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Enter value for begin_snap: 6489

First Begin Snapshot Id specified: 6489


Enter value for end_snap: 6491

First End Snapshot Id specified: 6491


Instances in this Workload Repository schema

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

DB Id Inst Num DB Name Instance Host

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

* 2656835042 1 TEST          TEST          tester

Database Id and Instance Number for the Second Pair of Snapshots

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Using 2656835042 for Database Id for the second pair of snapshots

Using 1 for Instance Number for the second pair of snapshots


Specify the number of days of snapshots to choose from

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Entering the number of days (n) will result in the most recent

(n) days of snapshots being listed. Pressing without

specifying a number lists all completed snapshots.


Enter value for num_days2: 2

Listing the last 2 days of Completed Snapshots


                               Snap

Instance DB Name Snap Id Snap Started Level

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

TEST TEST    6480 22 Feb 2011 00:00      1

                     6481 22 Feb 2011 01:00      1

                     6482 22 Feb 2011 02:00      1

                     6483 22 Feb 2011 03:00      1

                     6484 22 Feb 2011 04:00      1

                     6485 22 Feb 2011 05:00      1

                     6486 22 Feb 2011 06:00      1

                     6487 22 Feb 2011 07:00      1

                     6488 22 Feb 2011 08:00      1

                     6489 22 Feb 2011 09:00      1

                     6490 22 Feb 2011 10:00      1

                     6491 22 Feb 2011 11:00      1

                     6492 22 Feb 2011 12:00      1

                     6493 22 Feb 2011 12:48      1

                     6494 22 Feb 2011 12:48      2

                     6496 22 Feb 2011 14:00      1

                     6497 22 Feb 2011 15:00      1

                     6498 22 Feb 2011 16:00      1

                     6499 22 Feb 2011 17:00      1

                     6500 22 Feb 2011 18:00      1

                     6501 22 Feb 2011 19:00      1

                     6502 22 Feb 2011 20:00      1

                     6503 22 Feb 2011 21:00      1

                     6504 22 Feb 2011 22:00      1

                     6505 22 Feb 2011 23:00      1

                     6506 23 Feb 2011 00:00      1

                     6507 23 Feb 2011 01:00      1

                     6508 23 Feb 2011 02:00      1

                     6509 23 Feb 2011 03:00      1

                     6510 23 Feb 2011 04:00      1

                     6511 23 Feb 2011 05:00      1

                     6512 23 Feb 2011 06:00      1

                     6513 23 Feb 2011 07:00      1

                     6514 23 Feb 2011 08:00      1

                     6515 23 Feb 2011 09:00      1

                     6516 23 Feb 2011 10:00      1

Kategori Dba

Bugün database' in performansı ile ilgili belli aralıklarla alınmakta olan snapshotların, bizler için ne ifade ettiğinden, nasıl alınabileceğinden, çalışma şeklinden ve nasıl configure edileceğinden bahsetmek istiyorum.

Automatic Workload Repository (AWR), problemi tespit etmek ve self-tuning yapabilmek amacıyla istatistik toplar. Toplanan bu istastikler ise hem memoryde hem de veritabanında saklanır.

AWR istatistikleri neleri içerir, nelerden oluşur ;

*     * Erişim ve kullanım istatistiklerini belirlemek için Object İstatistikleri,

*     * Session bazında, zaman modelli istatistikleri (ki alınan bu istatistikleri V$SYS_TIME_MODEL ve V$SESS_TIME_MODEL viewlerinden görebiliriz.)

*     * Bazı system ve session istatistiklerini, (bu istatistikleride V$SYSSTAT and V$SESSTAT viewlerinden izleyebiliriz)

*     * System üzerinde çalışma süresi ve CPU kullanımında top olan sql statmentları ile ilgili istatistikleri,

*     * ASH istastikleri, son sesessionlara ait işlemler ile ilgili istastikleri

İçerir.

Database istatistikleri AWR aracılığıyla toplanır ve defaultunda enable olarak gelir ve bu opsiyon Statistics_level inital parametsiyle kontrol edilir. Awr’ ın çalışabilmesi için  statistic_level parametresi mutlaka TYPICAL veya ALL  olarak set edilmelidir. Defaultunda Typical olarak geldiği içinde AWR’ ın defaultu enable’ dır.  Bu değer BASIC olarak set edildiğinde artık database’ in istatistikleri toplanmayacağı anlamına gelmektedir. (AWR disable olacağından) Bu parametrenin BASIC olması performans açısından da (tabloların zaman içerisinde structure’ ları, size’ ları, indexleri değişeceğinden, çalışan sql’ lere ait execution planları da zamanla yanlış ve yavaş çalışmaya başlayacağından) olumsuz sonuçlar doğuracaktır. Dolayısıyla bu önerilen bir durum değildir. AWR,  database’ in istatistiklerini belirli periyodlarda otomatik olarak alır, eğer statistics_level parametresi BASIC ise yani AWR disable ise, manuel olarak DBMS_WORKLOAD_REPOSITORY package’ ı kullanılarak AWR istatistikleri alabilirsiniz. Ancak system istatistiklerinin büyük bir kısmı (segment istatistikleri ve memory advisor bilgileri gibi) disable olacağından  anlık olarak alınmaya çalışılan istatistikler tam olmayabilir.

Ne olduğundan bahsettik, şimdi biraz da Automatic Workload Repository ile ilgili kavramlar üzerinde duralım biraz, sonrasında yönetimi ile devam edeceğiz ;

*     * Snapshots ;

Snapshots, ADDM tarafından performans karşılaştırmaları yapmak için kullanılan, belirli bir zaman aralığına ait verilerin history bilgisini turarlar. Oracle’ ın kurulumu ile birlikte default olarak her saat başında otomatik olarak çalışır ve saat başında alınan bu snapshot’ larıda 8 gün boyunca saklar.  Saat başında otomatik olarak alınmasının yanında, istenildiği anda manuel olarak da snapshot alınabilir. AWR tarafından alınan snapshotlar, Automic Database Diagnostic Monitor (AADDM) tarafında da otomatik olarak incelenmektedir.

AWR raporları, iki dönem arasındaki performansı karşılaştırarak, performans kaybına yol açan sql statementlarının tespit edilmesine yardımcı olur. Oracle 10g ile birlikte tanışmış olduğumuz AWR ve ADDM, kullanıcılardan performans ile ilgili şikayetlerin arttığı zamanlarda sorunun tespiti açısından ciddi rol oynamaktadırlar.

*     * Baselines ;

Baseline, belli bir zaman aralığındaki performans ile ilgili dataları içerir.

*     * Adaptive Thresholds

Adaptive thresholds’ lar performans ile ilgili sorunları tespit ve monitor etmeye yardımcı olur. Bunu, tanımlayacağınız thresholdlar da otomatik olarak warning/critical alert seviyeleri bazında yapabiliriz.

   Atomatic Workload Repository Yönetimi 

*      * Snapshot Yönetimi

Oracle database kurulumu ile birlikte default olarak her saat başı otomatik olarak snaphot’ ların alınmaktadır. Alınan bu snapshotların saklanmasıda default olarak 8 gün dür. İhtiyaç halinde DBMS_WORKLOAD_REPOSITORY package’ı ile manuel olarak snapshot create, drop veya edit edebiliriz. Bu package kullanabilmek için user’ ın DBA yetkisine sahip olmalıdır. Manuel olarak snapshot create – drop edilmesi işlemi özellikle enterprise manager konsolu kullanamadığımız durumlarda (ki kimiz zaman sistemde yaşanan problemlerden dolayı zaman zaman konsolu kullanamayabiliyoruz) ciddi önemli olduğu durumlarla karşılaşabiliriz. Dolayısıyla sadece bu işlem için değil, database seviyesinde yapacağımız tüm işlemlerin sql komutları ile nasıl yapıldıklarını bilmemiz zaman zaman hayati önem taşıyabiliyor.

Manuel olarak bahsettiğimiz bu işlemleri şimdi sırası ile nasıl yapabileceğimize bakalım;

(aşağıda belirtilen işlemlerin aynısı konsol üzerinden de yapılabilir ben burada sadece konsolu kullanmadan nasıl yapabileceğimiz üzerinde duracağım)

Manuel Snapshot create etmeye çalışalım; 

BEGIN

DBMS_WORKLOAD_REPOSITORY.CREATE_SNAPSHOT ();

END;

/

PL/SQL procedure successfully completed

Yukarıdaki scriptte snapshot kısmında sonraki “()” alanı doldurmadan direk çalıştırdık. Buraya TYPICAL  veya ALL da yazabilirdik. Null  olarak gönderdiğimizde statistic_level parametreniz ne olarak set etmişseniz onu dikkate alıyor.

Şimdi almış olduğum son snapshot’ ı drop etmek isteyelim ; 

BEGIN

DBMS_WORKLOAD_REPOSITORY.DROP_SNAPSHOT_RANGE (low_snap_id => 6495,

high_snap_id => 6495, dbid => 2656835042);

END;

/

PL/SQL procedure successfully completed

Bu şekilde sadece seçmiş olduğunuz snapshotı drop edebileceğiniz gibi bir aralık içerisindeki tüm snapshotlarıda drop edebilirsiniz.

Snapshot ayarlarını modify etmeye çalışalım ; 

BEGIN

DBMS_WORKLOAD_REPOSITORY.MODIFY_SNAPSHOT_SETTINGS( retention => 43200,

interval => 30, topnsql => 100, dbid => 3310949047);

END;

/

PL/SQL procedure successfully completed

Yapılan bu değişikliği şöyle tanımlayabiliriz; retention parametresi ile alınan snapshotların saklanma süresi 43200 dakikaya yani 30 güne, interval 30 ile snapshot alınma sıklığı 30 dak’ ya, topnsql 100 ile snapshotlara dikkate alınanacak top sql sayısı 100’ e set edilmektedir. Dbid parametresi ise üzerinde işlem yapmakta olduğunuz database’ in dbis’ sini ifade etmektedir. (select dbid from v$database ile bulunabilir)

Snapshot ayarları ile ilgili yapmış olduğunuz bu değişiliklerin history’ si neDBA_HIST_WR_CONTROL view’ ini select ederek görebilirsiniz.

select * from  sys.DBA_HIST_WR_CONTROL

DBID                SNAP_INTERVAL                      RETENTION                             TOPNSQL

2040370613    +00 01:00:00.000000              +07 00:00:00.000000               DEFAULT

AWR ile tüm testleri 11gR2 ortamında yaptığımdan dolayı farklı versiyonlarda bu selectin sonuçu farklı çıkacaktır. (örneğin 10gR2 de topnsql alanı olmayacaktır)

*     * Baseline Yönetimi

Baseline’ lar sistemin optimum olarak çalıştığı bir dönemde create edilip problem oluştuğu dönemde nelerin problem teşkil ettiğini yani iki dönem arasındaki farkı ne olarak görebilmek için alınır. (veya yoğun dönemlerde oluşturulup başka bir aralık ile karşılaştırmamıza olanak sağlar) Baseline’ da iki şekilde create edebiliriz. Konsol üzerinden ve DBMS_WORKLOAD_REPOSITORY package’ ını kullanarak. Package ile nasıl create, drop veya modify baseline yapabiliriz bunlara bakalım kısaca;

  create etmek için ; 

öncelikle hangi aralığa ait snapshotları kullanarak baseline create edeceğiz buna kara veriyoruz. Aşağıdaki sql’ den mevcut snapshotlara bakabiliriz;

select * from DBA_HIST_SNAPSHOT ;

sonra ;

BEGIN

DBMS_WORKLOAD_REPOSITORY.CREATE_BASELINE (start_snap_id => 6517,

end_snap_id => 6518, baseline_name => 'deneme baseline',

dbid => 2656835042, expiration => 30);

END;

PL/SQL procedure successfully completed

Artık oluşturmuş olduğumuz yeni baseline’ nıda ;

select * from DBA_HIST_BASELINE  

view’ inde görebiliyoruz. 

Create scriptinde expiration parametresini null gönderirseniz asla expire olmayacak demiş olursunuz.bizim bu örneğimizde 30 olarak set etmiş olduk.

Drop etmek için ;  

Aynı mantıkda, hangi baseline’ i drop etmek istediğimize DBA_HIST_BASELINEtablosundan bakıp karar veriyoruz. (tabi eğer bilmiyorsak) 

Sonra; 

BEGIN

DBMS_WORKLOAD_REPOSITORY.DROP_BASELINE (baseline_name => 'deneme baseline',

cascade => FALSE, dbid => 2656835042);

END;

PL/SQL procedure successfully completed

Ile drop edebiliriz. 

Daha önce alınmış olan bir baseline’ nın adını rename etmek için ; 

BEGIN

DBMS_WORKLOAD_REPOSITORY.RENAME_BASELINE (

old_baseline_name => 'deneme baseline',

new_baseline_name => 'dene baseline',

dbid => 2656835042);

END;

PL/SQL procedure successfully completed

Ile yapabiliriz. 

İşinize yarayacağını düşündüğüm bazı Automatic Workload Repository ile ilgili wievler ; 

V$ACTIVE_SESSION_HISTORY = Database’ deki active sessionlara ait bilgilerin turulduğu view,

DBA_HIST_ACTIVE_SESS_HISTORY = memorydeki en son system aktivitelerine ait bilgileri içerir,

DBA_HIST_BASELINE = database’ deki baseline’ leri listeler,

DBA_HIST_BASELINE_DETAILS = baseline’ lar hakkında detaylı bilgileri içerir,

DBA_HIST_BASELINE_TEMPLATE = system tarafından generate edilen baseline template’ leri hakkında bilgiler içerir,

DBA_HIST_DATABASE_INSTANCE = database environment’ ları hakkında bilgileri içeir,

DBA_HIST_SNAPSHOT = database’deki snapshotlar hakkında bilgileri içerir,

DBA_HIST_WR_CONTROL = AWR’ ın kontrol ayarları ile ilgili bilgileri içerir.

AWR raporu create etmek için ; 

Yine konsolu kullanmadan awr raporu create etmek için aşağıdaki adımları izleyebiliriz. Tabi bunları yapan kullanıcının dba yetkisine sahip olması gerektiğini de unutmayalım.

Sql komut satırıdan aşağıdaki sql dosyasını çağırıyoruz;

@$ORACLE_HOME/rdbms/admin/awrrpt.sql

[ admin]$ sqlplus "/as sysdba"

SQL*Plus: Release 11.2.0.1.0 Production on Wed Feb 23 14:43:32 2011

Copyright (c) 1982, 2009, Oracle.  All rights reserved.

Connected to:

Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production

With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL>

SQL>

SQL> @$ORACLE_HOME/rdbms/admin/awrrpt.sql;

Current Instance

~~~~~~~~~~~~~~~~

DB Id            DB Name         Inst Num          Instance

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

2656835042   TEST                 1                     TEST

Specify the Report Type

~~~~~~~~~~~~~~~~~~~~~~~

Would you like an HTML report, or a plain text report?

Enter 'html' for an HTML report, or 'text' for plain text

Defaults to 'html'

Enter value for report_type: html

Type Specified:  html

Instances in this Workload Repository schema

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

DB Id            Inst Num DB Name      Instance     Host

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

* 2656835042        1   TEST          TEST          tester1

Using 2656835042 for database Id

Using          1 for instance number

Specify the number of days of snapshots to choose from

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Entering the number of days (n) will result in the most recent

(n) days of snapshots being listed.  Pressing without

specifying a number lists all completed snapshots.

Enter value for num_days: 1

Listing the last day's Completed Snapshots

Snap

Instance     DB Name        Snap Id    Snap Started    Level

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

TEST     TEST      6506 23 Feb 2011 00:00      1

                           6507 23 Feb 2011 01:00      1

                           6508 23 Feb 2011 02:00      1

                           6509 23 Feb 2011 03:00      1

                           6510 23 Feb 2011 04:00      1

                           6511 23 Feb 2011 05:00      1

                           6512 23 Feb 2011 06:00      1

                           6513 23 Feb 2011 07:00      1

                           6514 23 Feb 2011 08:00      1

                           6515 23 Feb 2011 09:00      1

                           6516 23 Feb 2011 10:00      1

                           6517 23 Feb 2011 11:00      1

                           6518 23 Feb 2011 12:00      1

                           6519 23 Feb 2011 13:00      1

                           6520 23 Feb 2011 14:00      1

Specify the Begin and End Snapshot Ids

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Enter value for begin_snap: 6519

Begin Snapshot Id specified: 6519

Enter value for end_snap: 6520

End   Snapshot Id specified: 6520

Specify the Report Name

~~~~~~~~~~~~~~~~~~~~~~~

The default report file name is awrrpt_1_6519_6520.html.  To use this name,

press to continue, otherwise enter an alternative.

Enter value for report_name: deneme_awr

Using the report name deneme_awr

Report written to deneme_awr

SQL>

awrrpt.sql’ i komut satırından başlatııkdan sonra sırası ile istenilen bilgileri giriyoruz. Bu bilgileri sırasıyla açıklayalım ;

Enter value for report_type: html

(rapor çıktısının formatını belirliyoruz, text veya html giriyoruz)

Enter value for num_days: 1

(snapshot id’ si seçmek için kaç günlük snapshotları görmek istediğimizi söylüyoruz)

Enter value for begin_snap: 6519

Enter value for end_snap: 6520

(alacağımız raporun hangi snapshotları dikkate alması gerektiğini söylüyoruz)

Enter value for report_name: deneme_awr

(raporun ismini set ediyoruz. Hangi dizinde çalıştırdıysanız o dizin altına belirlediğiniz isimle dosyayı create ediyor)

 

RAC kullanıyorsanız çalıştıracağınız file’ in ismi  awrgrpt.sql olacaktır. (@$ORACLE_HOME/rdbms/admin/awrgrpt.sql)

 

Spesifik bir instance için AWR raporu create etmek için çalıştırılması gereken file awrrpti.sql olacaktır.  

(@$ORACLE_HOME/rdbms/admin/awrrpti.sql)

Bu awrrpti.sql çalıştırıldığından yukarıdakinden farklı olarak sizden hangi instance için almanız gerekiyor ise o instance ait dbis bilgisini girmenizi isteyecektir.

 

Instances in this Workload Repository schema

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

DB Id    Inst Num DB Name      Instance     Host

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

3309173529        1 MAIN         main         examp1690

3309173529        1 TINT251      tint251      samp251

Rac kullanıpda, spesifik bir instance için AWR raporu create etmek için çalıştırılması gereken file awrgrpti.sql olacaktır.  

(@$ORACLE_HOME/rdbms/admin/awrgrpti.sql)

 

Burada da istenilen bilgiler yukarıdaki örnekdeki gibi girilmesi gerekmektedir.  

Şimdi işi biraz daha detaylandırıp snapshot içerisinde bizim için problemli olduğunu düşündüğümüz sadece bir sql için awr raporu almaya çalışalım. Bunun için kendi test ortamımda şöyle bir case oluşturdum. 06y3gf61vurz7 id’ li bir sql’ im var ve sabah 08 – 09 arasında sistemde kaynaklanan yoğunluğun bu sql’ den kaynaklandığını düşünelim ve araştıralım ;

Yaptığım işleme ait log ;

[]$ sqlplus "/as sysdba"

SQL*Plus: Release 11.2.0.1.0 Production on Wed Feb 23 15:20:14 2011

Copyright (c) 1982, 2009, Oracle.  All rights reserved.

Connected to:

Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production

With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL> @$ORACLE_HOME/rdbms/admin/awrsqrpt.sql

Current Instance

~~~~~~~~~~~~~~~~

DB Id    DB Name      Inst Num Instance

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

2656835042 TEST                 1 TEST

Specify the Report Type

~~~~~~~~~~~~~~~~~~~~~~~

Would you like an HTML report, or a plain text report?

Enter 'html' for an HTML report, or 'text' for plain text

Defaults to 'html'

Enter value for report_type: text

Type Specified:  text

Instances in this Workload Repository schema

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

DB Id     Inst Num DB Name      Instance     Host

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

* 2656835042  &nbs

Kategori Dba

Database’ in olmazsa olmaz koşullarından biri en 2 gruplu bir redolog grubunuzun olmasıdır. Redolog’ lar sistemin son ana döndürülmesinde kritik bir önem taşıdığından dolayı groupların memberlanması son derece önemlidir. Redologların nasıl memberlanacağı ile ilgili http://kamilturkyilmaz.blogspot.com/2010/11/redolog-group-tanmlama-degisiklik-yapma.html 

gerekli bilgiyi daha önceki yazımda detaylı olarak anlatmıştım. Redologlarınız member’ lı değilse ve herhangi birini kaybetdiyseniz  veritabanını kurtarmak için aşağıdaki işlemleri yapmamız gerekir. Ancak burada unutumaması gereken nokta; commit edilmemiş tüm transactionların geri getirilemeyeceği yani veri kaybı yaşanacağıdır.  

Benzer bir case’ i oluşturabilmek için database’ imizi shutdown immediate ile kapatıyoruz.

SQL> shutdown immediate;

Veritabanı kapatıldı.

Veritabanı kullanıma kapatıldı.

ORACLE anı kapatıldı.

SQL>

Redologlardan birini, yer aldığı dizinden siliyorum; Şimdi bu haliyle database’ i açmayı deniyorum (hatayı görebilmek için) ;

SQL> startup

ORACLE anı başlatıldı.

Total System Global Area  612368384 bytes

Fixed Size                  1250428 bytes

Variable Size             222301060 bytes

Database Buffers          381681664 bytes

Redo Buffers                7135232 bytes

Veritabanı kullanıma açıldı.

ORA-00313: 1 günlük grubunun (thread 1) üyeleri açılamadı

ORA-00312: çevrimiçi günlük 1, thread 1:

'C:\ORACLE\10GR2\ORADATA\TEST\REDO01.LOG'

Database redologlardan redo01.log dosyasını bulamadığı için açamadı. Ve mount modda kaldı. (hatırlayınız; database’ e startup komutu verildiğinde son aşaması datafile’ leri ve redologları açtığı nokta idi, bu aşamayı geçemediğinden dolayı mount modda kalıyor.)  Kontrol etmek için ;

SQL> select open_mode from v$database;

OPEN_MODE

----------

MOUNTED

Bu durumdan kurtulmak için şimdi komut satırından database’ i recover ediyoruz. Bu işlem ile kayıp olan redolog dosyası otomatikl olarak daha önce olduğu lokasyona aynı isimle system tarafından otomatik olarak create ediliyor. Bu işlemi “recover database until cancel” komutu ile yapmamızın nedeni gelebildiğimiz kadar son noktaya gelmeye çalıştığımızdan dolayıdır.

SQL> recover database until cancel;

Ortam kurtama tamamlandı.

Bu işlemi başarıyla gerçekleştirdikden sonra yine unutlmaması gereken bir nokta incomplete recovery işlemlerinden sonra mutlaka database’ i open resetlogs komutu ile açabilmemizdir. Zaten open ile açmayı denediğinizde aşağıdaki hatayı alırsınız.

SQL> alter database open ;

alter database open

*

1 satırında HATA:

ORA-01589: veritabanı açma için RESETLOGS veya NORESETLOGS seçeneği  kullanılmalı

Rsetlogs ile açıyoruz.

SQL> alter database open resetlogs;

Veritabanı değiştirildi.

Bu şekilde database’ imizi kurtarmış olduk.  Bu işlemi yapabilmek için database’ in archive modda olmasına gerek yoktur.  Çünkü bu problemi düzeltmek için archive loglara ihtiyaç bulunmamaktadır.

Bu tarz disaster durumlarında veri kaybı çoğu zaman kabul edilebilir bir nokta olmakdan çıkıyor, dolayısıyla yazımın başında belirtmiş olduğum gibi önlemlerimizi zamanında ve doğru bir şekilde alıyor olmamız gerekiyor.

Kategori Dba

Merhaba arkadaşlar,

Bu yazımda Oracle’ın flashback özelliğini kullanarak değiştirdiğimiz veya sildiğimiz verilere nasıl erişeceğimizi anlatacağım.

Önce örneğimiz için aşağıdaki gibi bir tablo oluşturalım :

Kategori Dba

Sayfa 1 / 5