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.
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
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
Oracle upgrade (from 10gR1 – 10gR2 to 11gR2)
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;
LOG_MINER Kurulumu, Konfigurasyonu ve Kullanımı ...
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.
LOBINDEX ve LOBSEGMENT’ lerin create, move, rebuild edilmesi
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
Database’ in DBID ve DB_NAME Değerini Değiştirmek (dbnewid, nid)
Ö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.
Automatic Workload Repository (AWR) Raporlarının Compare Edilmesi
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
Automatic Workload Repository (AWR) Nedir, Nasıl Alınır ?
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
(ORA-00313) Redolog grublarından biri (veya birkaçı) Kaybedildiğinde Yapılması Gerekenler
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.
Oracle Flashback ile Eski Datalara Erişmek(as of timestamp)
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 :