Hurriyet

31 Aralık 2013 Salı

PL\SQL Örnekleri: SID ve Serial# Bulunması - Tek Satırlık Değerlerin Değişkenlere Atanması

Buradaki örneğimizde SID ve SERIAL# bulmaktayız.SID ve SERIAL#'ı dışarıdaki bir sorgudan çekmekteyiz. Sorgudan değerlerimizi çektikten, bunları scriptimiz içinde yazdırabiliriz.

COLUMN SID NEW_VALUE abc  
COLUMN SERIAL# NEW_VALUE efg  
   
 select SID ,SERIAL# from v$session where SID=1703;  
   
   
 declare  
 begin  
   
 dbms_output.put_line('SID = '||:abc||' SERIAL#= ' || :efg);  
 end;  
 / 

Tek satırlık değerleri değişkenlere atamak için "COLUMN" dedikten sonra sorguda değerini alacağımız kolon adını yazıp new_value dedikten sonra kullanacağamız değişkene atarız. Aşağıdaki yapıda oluşturmuş oluruz.

- COLUMN sütun_adı NEW_VALUE değişken_adı -

PL\SQL Örnekleri: Veritabanı Versiyonu Kontrolü Örneği - Global Parametreler

Buradaki örneğimizde değişken kullanımını inceleyeceğiz. Değişkenimizi yarattığımız scriptin üzerinde tanımlarız. Böylece genel olarak kullanabiliriz. Genelden kastımız ise bunun büyük bir kod olduğunu düşünseydik yani büyük bir paket olduğunu varsaysaydık  diğer fonksiyonlarımız içerisinde de :v_version değişkenini kullanmak için böyle bir yol uygulayabiliriz. V_version parametresinin yanındaki ":" işareti ile de parametrenin global olduğunu beliritiriz.

Aşağıdaki kodda v$instance'dan çektiğimiz versiyon değerini v_version adlı parametreye atarız. Sonra bu parametreyi uygun bir şekilde substr fonksiyonuyla ayırdıktan sonra bununla ilgili kontrol işlemlerimizi yaparız.

1.script

 variable        v_version               varchar2(17);  
 declare 
 BEGIN  
   
   select version  
   into :v_version  
   from v$instance;  
   
 :v_version := substr(:v_version,1,9);  
   
 if :v_version < '8.1.6.0.0'   
 and :v_version > '4.0' then  
 dbms_output.put_line(chr(10));  
 dbms_output.put_line('RDBMS Version = '||:v_version);  
 dbms_output.put_line('ERROR - Versiyon çok düşük');  
 dbms_output.put_line(chr(10));  
 end if;  
   
 exception  
   
  when others then  
   dbms_output.put_line(chr(10));  
   DBMS_OUTPUT.PUT_LINE('ERROR - RDBMS Versiyon hatası '|| sqlerrm);  
     
 END;  
 / 

Global özelliğini göstermek için aşağıdaki kodumuzu ya SQL*PLUS'tan ya da Toad'dan f5 tuşuna basaraktan çalıştırıp görebiliriz. Aşağıdaki kodumuzda ilk script'imizde atadığımız v_version parametremizi ikinci scriptimiz içinde de direk kullanabiliriz.

İlk script de atanan değer aynı session içerisinde 2. scriptde de kullanılabileceğini göstermek için aşağıdaki scripti çalıştırabiliriz.

2.script
 declare  
   
 BEGIN  
   
   select MAX(version)  
   into :v_version  
   from v$instance;  
   
 :v_version := substr(:v_version,1,9);  
   
 if :v_version < '8.1.6.0.0'   
 and :v_version > '4.0' then  
 dbms_output.put_line(chr(10));  
 dbms_output.put_line('RDBMS Version = '||:v_version);  
 dbms_output.put_line('ERROR - Versiyon çok düşük');  
 dbms_output.put_line(chr(10));  
 end if;  
   
 exception  
   
  when others then  
   dbms_output.put_line(chr(10));  
   DBMS_OUTPUT.PUT_LINE('ERROR - RDBMS Versiyon hatası '|| sqlerrm);  

 END;  
 /  
   
 declare  
 begin  
   
 dbms_output.put_line('RDBMS Version = '||:v_version);  
 end;  
 /  






30 Aralık 2013 Pazartesi

Oracle Veritabanı: SYS_CONTEXT Nedir? - What is SYS_CONTEXT

Sys_context fonksiyonu bize alan adıyla eşleştirilmiş parametreyi verir. Syntax'ı aşağıdaki gibidir.

 select sys_context('alan_adı','parametre',uzunluğu) from dual;

Bu fonksiyon sayesinde daha önceden set edilmiş parametrelerle ihtiyacımız olabilecek temel bilgilere erişebiliriz.

En temel ihtiyacımız olabilecek parametreler:

-CURRENT_SCHEMA
-CURRENT_SCHEMA_ID
-DB_DOMAIN
-DB_NAME
-DB_UNIQUE_NAME
-HOST
-INSTANCE
-INSTANCE_NAME
-IP_ADDRESS
-ISDBA
-OS_USER
-SID
-TERMINAL
-SESSION_ID
-SESSION_USERID
-SESSION_USER
-SERVICE_NAME
-SERVER_HOST

Örnek kullanım:
select sys_context('USERENV','SID') from dual;  

Bütün tanımlı parametreler aşağıdaki linkte verilmiştir.
http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions165.htm

Referans:
http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions165.htm

Oracle Veritabanı: SQL*PLUS'taki En Genel Set Komutları - SQL*PLUS'ta Formatlama- Most General SQL*PLUS Set Commands - SQL*PLUS Formatting

Sqlplus'ta zaman zaman kullanmamız gereken bazı komutlar aşağıdadır. Bunlar sayesinde makinamızda otomatik iş tanımlayıp, sürekli kontrol sağlayıp kendimize mail attırabiliriz ve bunları düzenli bir şekilde attırtabiliriz.

   
   
 SET ECHO   ON   
 -- ECHO = ON sorguyu gösterir ve spool dosyalarına yazılır.  
 -- ECHO = OFF ile sorgu gösterilir ama spool dosyalarına yazılmaz..  
   
 SET TRIMOUT  ON   
 -- TRIMOUT = ON çıktıdan boşlukları çıkartır.  
   
 SET TRIMSPOOL ON   
 -- TRIMSPOOL = ON spool dosyasındaki boşlukları çıkartır.  
   
 SET HEADING  OFF   
 -- HEADING = OFF kolon adlarını çıktıdan çıkartır.  
   
 SET FEEDBACK OFF   
 -- FEEDBACK = ON ile çıktı sayısı hesaplanır.  
   
 SET PAUSE   OFF   
 -- PAUSE = ON ile komutlar işlendikten sonra "return" tuşuna basılması gerekir.  
   
 SET PAGESIZE 0    
 -- PAGESIZE = 0 ile bütün başlıklar ve sayfa aralıkları bastırılır.  
   
 SET LINESIZE 80   
 -- LINESIZE = sayfa genişiği genelde 80 dir.  
   
 SET VERIFY  OFF   
 -- VERIFY = ON verify ile değişkenlerin değeri sorgu öncesi ve sonrasında gösterilir.  
   
 --Spool etmek demek sql sorgularının çıktılarının bir dosyaya yazılması demektir.   
 --abc.log çıktılarımızı yazacağımız dosyadır.   
 --Bütün sorgularımız bittikten sonra da "spool off" ile dosyamızı kapatırız.  
 SPOOL abc.log  
   
 SELECT * FROM dual;  
   
 SPOOL OFF  

Burada da yukarıdaki komutlarımızın örneklerini göstermeye çalışacağız. SQL script'imiz Oracle EBS'te(Oracle Applications'da) en son profil değerlerinin ne zaman değiştiğini gösteren bir SQL'dir

 sqlplus -s apps/apps <= SYSDATE  
  AND o.profile_option_name = t.profile_option_name  
  AND level_id = 10001  
  AND t.language='TR'  
  AND v.last_update_date>sysdate-30  
  AND t.LANGUAGE IN (SELECT language_code  
  FROM fnd_languages  
  WHERE installed_flag = 'B'  
  UNION  
  SELECT nls_language  
  FROM fnd_languages  
  WHERE installed_flag = 'B')  
  ORDER BY user_profile_option_name;  
   
   
 PROMPT "Bitti"  
 exit;  
   
 EOF  

Not: Script bir bash shell script'ine gömülmüştür.


Linesize Örnek:

Linesize sonuçların ekranda ne  kadar genişlikte gösterileceğini ortaya koyar.

Linesize bu örnekte 10 iken diğer örneğimizde 100'dür.
 USER_PROFI  
 ----------  
 ICX:Oturum  
 MO: Faaliy  
 POS: Müker  
 Uygulama Y  
 XXIS: GRC  
 İş Yönetim  

USER_PROFILE_OPTION_NAME  
 ----------------------------------------------------------------------------------------------------  
 ICX:Oturum Kesildi  
 MO: Faaliyet Birimi  
 POS: Mükerrer Vergi Mükellefi No'suna Sahip Tedarikçilere İzin Ver  
 Uygulama Yazılımları SSO Otomatik Bağlantı Kullanıcısı  
 XXIS: GRC Custom PLL  
 İş Yönetim Sistemi SSO - OID Kimlik Ekleme Olayını Etkinleştir 

Column Örneği: 

Column kolon_ismi format a10; şeklinde bir örnek yaparsak eğer script'imizde çalışacak olan sorgumuzun kolonu ekranda 10 birim büyüklüğünde gösterilir.

Script'imize bu 2 örneği de eklediğimiz zaman:

 column profile_option_value format a10;  
 column user_profile_option_name format a10;

Çıktımız  bu şekilde oluşmaktadır:

 USER_PROFI PROFILE_OP CREATION_ LAST_UPDA Created By  
 ---------- ---------- --------- --------- ----------------------------------------------------------  
 ICX:Oturum 30     30-OCT-04 11-MAR-14 AUTOINSTALL  
 MO: Faaliy 81     21-MAR-14 21-MAR-14 KURULUM  
 POS: Müker Y     26-FEB-14 26-FEB-14 KURULUM  
 Uygulama Y Y     19-MAR-14 19-MAR-14 SYSADMIN  
 XXIS: GRC 0     16-NOV-13 10-MAR-14 KURULUM  
 İş Yönetim Y     29-AUG-05 19-MAR-14 ORACLE12.0.0  

Yani sütunumuzun çıktıları maksimum 10 satır olmaktadır.



27 Aralık 2013 Cuma

Oracle Veritabanı: Veritabanında Şifre - Password

Authentication - Kimlik Doğrulama:

Kimlik doğrulama, veritabanında kaynak kullanmak veya dataları kullanmak isteyen kişilerin giriş yöntemlerinin incelenmesidir. 

Veritabanında Var Olan Şifre Korumaları:

-Şifreler veritabanında şifrelenmektedir. AES şifreleme standardına göre şifrelenmektedir.

-Şifrelerin complexiteleri değiştirelebilinir. Yani oluşturulacak şifrelerde bazı şartlar aranabilir. Örneğin içinde 2 harf 3 sayı olsun gibisinden.

-Denenen şifreler arasında deneme süresi konulur. Eğer kullanıcı ilk üç denemesinde bilemez ise diğer denemeler arasında zaman farkı konur. Bu zaman farkı sayesinde ekstradan deneme veya tekrar tekrar deneme engellenir.

-Veritabanındaki şifrelerde büyük küçük harf uyumu aranır.

-Girilen şifreler tersi olmayan fonksiyonlara sokulur.

Şifre Oluşturulması:

Bir kullanıcı yaratılması ve bu kullanıcıya şifre atanması aşağıdaki gibidir. Önce normal bir kullanıcı yaratılır. Sonra bu kullanıcıya şifre atanır.

 CREATE USER berke IDENTIFIED BY password;  
 GRANT CREATE SESSION TO berke IDENTIFIED BY password;    

Şifreyi değiştirmek için aşağıdaki sorguyu kullanabiliriz.

 ALTER USER berke IDENTIFIED BY password;

Şifre Yönetimi: 

Şifre yönetimi aşırı önemlidir. Eğer her çalışan için ayrı bir kullanıcı oluşturuluyorsa kullanıcılara atanan şifrelerin sürekliliği profillerle yönetilir. Kullanıcıların profillerindeki şifreyle ilgili özellikler aşağıdaki sayfada verilmiştir.

Profil içerisindeki password_parameters olarak belirttiğimiz parametreler:

-failed_login_attempts
-password_life_time
-password_reuse_time
-password_reuse_max
-password_lock_time
-password_grace_time
-password_verify_function

Yukarıdaki profil değerlerimizin neler olabileceği aşağıdaki dokümanda bulunmaktadır.
http://docs.oracle.com/cd/E11882_01/network.112/e36292/authentication.htm#DBSEG99805

Örnek Profil Yaratılması:

 DROP PROFILE "DEFAULT" CASCADE;  
   
 CREATE PROFILE "DEFAULT" LIMIT  
  SESSIONS_PER_USER UNLIMITED  
  CPU_PER_SESSION UNLIMITED  
  CPU_PER_CALL UNLIMITED  
  CONNECT_TIME UNLIMITED  
  IDLE_TIME UNLIMITED  
  LOGICAL_READS_PER_SESSION UNLIMITED  
  LOGICAL_READS_PER_CALL UNLIMITED  
  COMPOSITE_LIMIT UNLIMITED  
  PRIVATE_SGA UNLIMITED  
  FAILED_LOGIN_ATTEMPTS 10  
  PASSWORD_LIFE_TIME UNLIMITED  
  PASSWORD_REUSE_TIME UNLIMITED  
  PASSWORD_REUSE_MAX UNLIMITED  
  PASSWORD_LOCK_TIME UNLIMITED  
  PASSWORD_GRACE_TIME UNLIMITED  
  PASSWORD_VERIFY_FUNCTION NULL;  

Eğer bir grup çalışana bir tane kullanıcı veriliyorsa bu kullanıcıların güvenlik yönetimi kendi üzerlerinden yapılabilir; çünkü bu kullanıcıyla bunların güvenlik seviyeleri veya özellikleri değiştirilebilinir.

Kullanıcıların sahip oldukları şifre ve profil bilgilerini bu komutla bulabiliriz.

 select username,profile,account_status,lock_date,authentication_type from dba_users;

DBA'leri Şifrelerini Kullandırtarak Veritabanına Sokmak:

Oracle veritabanında SYSDBA ve SYSOPER yetkileri verilmiş kullanıcıların şifreleri veritabanına özgü dosyalarda korunmaktadırlar.

Oracle Veritabanı: Oracle Veritabanındaki Kullanıcıların Yönetimi - Oracle Database Management For Users

Oracle veritabanlarına bağlanmak için kullanıcılarımızın bulunması gerekir. Bu kullanıcılar bir uygulama tarafından da kullanılabilir, son kullanıcılar tarafından da. Oracle bu kullanıcıların erişimiyle ilgili çeşitli limitler koymamızı sağlıyor. Veritabanındaki kaynakları da limitleyebiliriz. Bu bilgileri saklayan tablolar sayesinde bunları görebiliriz.

Kullanıcıların Yaratılması:

Kullanıcıları yaratırken "create user" ifadesini kullanırız. Bir kullanıcıyı yaratmak için "create user" yetkisinin bulunması gerekir. Bu yetki çok önemli olduğu için herkeste bulunmamalıdır. Kullanıcı yarattıktan sonra da kullanıcılara verdiğimiz yetkilere dikkat etmeliyiz. Bu yüzden ya kendi belirlediğimiz rolleri vermeliyiz ya da çok belirli yetkileri vermeliyiz.

Örnek: Bir kullanıcının yaratılması

 CREATE USER berke  
  IDENTIFIED BY password  
  DEFAULT TABLESPACE users  
  QUOTA 100M ON users  
  TEMPORARY TABLESPACE temp  
  PROFILE default;  
 GRANT CREATE SESSION TO berke;  

Burada berke kullanıcısı yaratıldığında sadece bağlanma yetkisi verilir. Bu yüzden bağlanma dışında berke kullanıcısı hiçbir şey gerçekleştiremez. Eğer kullanıcımızı silmek istersek de drop ederiz.

 drop user berke ;

Bu kullanıcının yarattığı objeler var ise ve bunlar birbirlerine foreign key gibi bağlarla bağlılarsa o zaman aşağıdaki komut ile kullanıcımızı drop edebiliriz.

DROP USER berke CASCADE;

O sırada online bir kullanıcıyı drop edemeyiz. Bunun için öncesinde kullanıcımızı kill etmemiz gerekir. Örnek komut aşağıdaki gibidir.

 ALTER SYSTEM KILL SESSION '127, 55234';  

Komutu uyguladıktan sonra kullanıcımızı drop edebiliriz.

Kendi session'ımızla ilgili bilgileri aşağıdaki sorgularla bulabiliriz.

 select sys_context('USERENV','SESSION_USERID') from dual;  
 select sys_context('USERENV','SID') from dual;  


Default Tablespace:
Kullanıcıların yaratılması sırasında default tablespace yani kullanıcıların yarattığı veya yaratacağı  nesnelerin tutulacağı yerdir. Bu ayar direk "system" tablespace'i olarak ayarlanmıştır. Bu işlem tehlikeli olabilir. Çünkü sistemsel dosyalar "system" tablespace'inde saklanır. Buradaki dosyaların bozulma ihtimalinde veritabanı bozulabilir. O yüzden veritabanını yaratırken default tablespace olarak kullanılacak bir tablespace yaratmalıyız.

Kullanıcı yetkileriyle ilgili yazıyı buradan daha da detaylı şekilde okuyabiliriz.

Quota:
Quota ifadesiyle kullanıcılara tablespace'ler üzerinde nesne yaratma yetkisi verilir. Yukarıdaki örneğimizde yaratılacak nesnelerin boyutunun 100MB olarak belirlendiğini görmekteyiz. Bu durumu kullanıcının hareketlerini kısıtlamak anlamında kullanabiliriz. "Unlimited Tablespace" yetkisi ise kullanıcıya herhangi bir tablespace üzerinde istediği kadar miktarda nesne yaratmasını sağlar. Bu yüzden tehlikelidir.

Temporary Tablespace:
Temporary Tablespace ise kullanıcıların çalıştırdıkları SQL'ler sonucunda temporary segment'ler kullanılması gerekiyorsa ihtiyaç duyulur. Standart Temporary Tablespace, eğer genel bir temporary tablespace yoksa system tablespace'i olduğu için bu konuda önemlidir. Ayrıca herkesin ortak temporary tablespace'i kullanmasına izin vermek burada yer kalmamasına da neden olabilir. Bu da performansda düşüşe neden olur ve işlemlerin durmasına neden olabilir.

Profile:
Kullanıcılarımıza  profiller atayabiliriz. Profil olarak belirttiğimiz durum kullanıcıların kaynaklarının kısıtlanmasını sağlayan bir sınır topluluğudur. Peki profillerde atanan sınırlar nelerdir?  Aşağıdaki sorguyla profillerde atanan sınırları görebiliriz.

 SELECT * FROM DBA_PROFILES  
   ORDER BY PROFILE;  

Profillerle ilgili daha fazla bilgi için bu dokümanımıza bakabiliriz.

Kullanıcıların Değiştirilmesi:

Kullanıcılarımızı yarattıktan sonra bunlarla ilgili değişiklik yapmak için "Alter User" yetkisine sahip olmamız gerekir. "Alter User" yetkisiyle aşağıdaki özellikler değiştirilebilinir.


  ALTER USER berke   
  IDENTIFIED BY password   
  DEFAULT TABLESPACE users   
  QUOTA 100M ON users   
  TEMPORARY TABLESPACE temp   
  PROFILE default; 

Kullanıcıların Yetkilendirilmesi:

Yukarıdaki bazı yetkilerden bahsetmiştik. Kullanıcıların yerine göre bazı yetkilere ihtiyaç duyması kaçınılmazdır. Yarattığımız örnek kullanıcıya göre sadece session yaratma yetkisi vermiştik. Kullanıcı yetkileriyle ilgili bilgileri bu yazımızda da göstermiştik.
http://berkeoz1.blogspot.com/2013/09/oracle-veritaban-yonetimi-kullanc.html

Kullanıcılara verebileceğimiz bütün yetkiler burada bulunmaktadır.
http://docs.oracle.com/cd/B28359_01/server.111/b28286/statements_9013.htm#SQLRF54937


Kullanıcıların Gösterildiği Tablolar:

Bütün kullanıcıları buradan görebiliriz.

 select * from dba_users;  

Bu kullanıcılar belirli bir zaman sonra kilitlenebilir. Profilerinden dolayı veya başka, kilitleme yetkisine sahip birisi tarafından kilitlenme ihtimalleri vardır. Bunları aşağıdaki gibi açabiliriz.

 alter user kullanıcı_ismi account unlock; 

Daha genel bilgiyi buradan alabiliriz:
http://berkeoz1.blogspot.com/2013/09/oracle-veritaban-expired-ve-locked.html

Kullanıcılara Kaynak Ayrılması:

Sistem kaynaklarının kullanıcılara, gruplara veya profillere göre ayrılmasıyla sistem kaynakları daha güvenli bir şekilde yönetilebilinir. Tüketim daha kontrollü sağlanabilinir. Bu işlemin yapılması için "Database Resource Manager" adlı araç kullanılır. Bu işlem kaynakların çok kısıtlı olduğu sistemlerde daha da önemli hale gelmektedir. Kullanıcılar profillerini açtıkları sırada performansta bir düşüş gözlemlenebilir; çünkü veritabanına girişte bu kısıtlar kullanıcılara direk ayrılır.

Kullanıcı Kaynak Kısıtları ve Limitleri:

Veritabanından kontrol edebileceğimiz çeşitli kısıtlama tipleri vardır. Bunlar:

-Kullanıcı Session'ı seviyesinde
-Database Calls - Veritabanına Sorgular
-CPU Time
-Logical Reads
-Diğer Kaynakların Kısıtlanması

Kullanıcı Session'ı Limitleri:
Bir kullanıcı veritabanına her bağlandığında, bir session yaratılmış olur. Her session CPU kullanır ve belirli bir hafıza kullanır. Eğer kullanıcı bütün kaynaklarını kullanırsa gönderdiği ifade durdurulur ve hata verir. Hata verince de sadece commit veya rollback komutlarını verebilir.

Database Calls - Veritabanı Kullanım Limiti:
Veritabanına gönderilen sorguların kullandığı kaynakların ne kadar kullanılacağı ya da ne sıklıkla kullanılacağı sınırlanır.

CPU Limiti:
SQL'ler sonucu kullanılabilecek CPU'nun kısıtlanmasıdır.

Logical Reads:
Logical Reads hem diskten hem de memory'den okunan datalardır. Çok fazla kaynak tüketen bir sorgu veya sorgular topluluğu veritabanı kaynaklarını fazla sıkıştıracağı için bu logical read olarak tanımladığımız okuma türlerine kısıtlar koyabiliriz.

Diğer Kaynaklar:
Diğer kaynaklar olarak nitelediğimiz konular ise kullanıcıların arka arkaya açabileceği session sayısının kısıtlanması, bir session için idle time sınırlamasının yapılması, SGA miktarının ayarlanmasıdır.

Kullanıcılarla İlgili Daha Fazla Bilgiler:

Kullanıcılarımız sisteme bağlandığında bir session oluşturduğunu söylemiştik. Bu session'lar her bağlantıda bir id ile belirlenirler. Bu session id'imizi aşağıdaki linkten bulabiliriz.
http://berkeoz1.blogspot.com/2013/10/oracle-veritaban-sessionid-imizi-nasl.html

Bu session içerisinde yaptığımız sorgular başka session'lardaki kullanıcıların yaptığı sorguları etkileyebilir. Yani onları kilitleyebilir. Kilitlemesi de onların iş yapamaması ve beklemesi anlamına gelir.

Bloke eden session'ları aşağıdaki link'imizden bulabiliriz.
http://berkeoz1.blogspot.com/2013/09/oracle-veritaban-bloke-eden-sessionlarn.html

Kullanıcımızla ilgili nesneleri görmek istiyorsak aşağıdaki sorguyu kullanabiliriz.

SELECT OWNER, OBJECT_NAME FROM DBA_OBJECTS WHERE OWNER LIKE 'BERKE';

Kullanıcımızla ilgili diğer bütün bilgileri örnek olarak SID,Serial#,kullanıcı adımız,kullanıcı id'si gibi bütün bilgileri aşağıdaki SQL'imizle bulabiliriz.

 select * from v$session where sid= (select    
   sid    
  from    
   v$mystat    
  where    
   rownum <=1); 

Her kullanıcının ne kadar hafaıza kullandığını görmek için aşağıdaki sorguyu kullanabiliriz.

  SELECT sess.SERIAL#,sess.SID,USERNAME, VALUE || 'bytes' "Current UGA memory"  
   FROM V$SESSION sess, V$SESSTAT stat, V$STATNAME name  
 WHERE sess.SID = stat.SID  
   AND stat.STATISTIC# = name.STATISTIC#  
   AND name.NAME = 'session uga memory';  


24 Aralık 2013 Salı

Oracle Veritabanı: Oracle Error ORA-1031 Signalled During ...

Oracle veritabanında bazen gerçekleştirmek istediğimiz işlemlere yetkimiz yetmediğinde bu hata ile karşılaşırız. Bu hatayı aşmamız için ya DBA'lere başvurmalıyız ya da yetkisi olan bir kullanıcı ile bağlanmalıyız.




Oracle Veritabanı: Datafile Dosya Formatları ve İsimlendirme - Datafile Creation Formats and Naming Conventions

Datafile'ların oluşturulması ve yönetimiyle ilgili daha önceden böyle bir yazı yazmıştık. Burada datafile'larımızı oluştururken isimleri kendimiz belirtiyorduk. Eğer bunu otomatikleştirmek istersek yani datafile yaratma oranımız çok fazla ise isimlerini hiç uğraşmadan belirli parametrelerle yaratmak isteyebiliriz. Bu işlemi de bazı özel parametrelerle gerçekleştirebiliriz. Bu parametreler aşağıdaki gibidir.

Kısaltma Açıklama Sorgulama
%a  Veritabanı Activation ID
%d Veritabanının adı  select name from v$database;
%D Bugünün tarihini DD formatında gösterir. select to_char(sysdate,'DD') from dual;
%f Dosya Numarası
%F ID,Gün,Ay,Yıl,Sequence No: IIIIIIIIII-YYYYMMDD-QQ
%I  DBID select dbid from v$database
%N Tablespace adı verilir.
%n Veritabanı Adı_XXX Ör: Berkexxx


Daha genel bilgi için buradaki link'e tıklayabiliriz. Buradaki link'te ayrıca backup alınırken geçerli olabilecek diğer kısaltmalar da verilmiştir. Burada bizim öğrenmemiz gereken şey datafile üretilirken isimlerin otomatik ve özgün olarak yaratılmasını istiyorsak aşağıdaki örnekteki ifade yazabiliriz.

Create tablespace deneme datafile ‘/home/oracle/Desktop/deneme%F.dbf’ size 100M; 

Bu durumda yarattığımız datafile /home/oracle/Desktop klasörünün altında deneme1157106256_20131224-131 olarak yaratılır.

19 Aralık 2013 Perşembe

Oracle E-Business Suite: Sayfalara Erişimin İzlenmesi - Audit - Page Access Tracking

E-Business Suite'de daha önce nasıl audit yapılacağını göstermiştik. Bu yazılarımızda audit raporları çıkaran concurrent request'leri listelemiştik.

1-Oracle Applications Audit

2-Oracle Applications Audit 2

Şimdi işleyeceğimiz konu ise Oracle Applications'ın kendi Audit kaynakları. Bu kaynaklara "System Administrator" sorumluluğundan gideriz.


Burada "Applications Usage" fonksiyonuna gireriz.


Buradan "Configuration" sayfasına gidersek audit'lenecek sayfaları ve modülleri ayarlayabiliriz. Ayrıca hangi seviyede izleneceğini de belirtebiliriz.


Eğer bir önceki sayfada "Applications Usage" yerine "Reports" seçseydik aşağıdaki ekrana denk gelecektik.


Bu ekranda hangi modüle erişildiği, kaç kere erişildiği, hangi sorumlulukların kullanıldığı, hangi kullanıclar tarafından kullanıldığı gibi bilgilere erişebiliriz.





Oracle E-Business Suite: SYSADMIN Yetkisinin Verilmesi - Giving The SYSADMIN Responsibility To Users

Her kullanıcıya "sysadmin"  yetkisini verilmesi:

 select user_name, user_id  
 from fnd_user  
 where user_name like '&username'  
 /  
   
 insert into fnd_user_responsibility(  
 USER_ID,  
 APPLICATION_ID,  
 RESPONSIBILITY_ID,  
 LAST_UPDATE_DATE,  
 LAST_UPDATED_BY,  
 CREATION_DATE,  
 CREATED_BY,  
 LAST_UPDATE_LOGIN,  
 START_DATE,  
 DESCRIPTION,  
 WINDOW_WIDTH,  
 WINDOW_HEIGHT,  
 WINDOW_XPOS,  
 WINDOW_YPOS,  
 NEW_WINDOW_FLAG)  
 values (  
 &apps_user_id, -- change this to your APPS user_id and you will have SYSADMIN Responsibility  
 1,  
 20420,  
 sysdate,  
 0,  
 sysdate,  
 1,  
 1060,  
 sysdate,  
 'System Admin',  
 5.896,  
 5.427,  
 -.042,  
 -.24,  
 'R');  


Oracle E-Business Suite: Oracle Application Kurulumu ile ilgili Bilgiler SQL - Application Info SQL

Oracle E-Business Suite Kurulumu ile ilgili bilgileri gösteren script:

 prompt --> Determining information about this Product Group  
   
 select product_group_id, product_group_name, release_name,   
   product_group_type, argument1  
  from fnd_product_groups;  
   
 prompt --> Multi-Org installed?  
 select multi_org_flag from fnd_product_groups;  
   
 prompt --> Uygulamada birden çok dil yüklü mü?  
 select multi_lingual_flag from fnd_product_groups;  
   
 prompt --> Lisanslanmış Ürünler  
   
 select decode(a.APPLICATION_short_name,  
   'SQLAP','AP','SQLGL','GL','OFA','FA',  
   a.APPLICATION_short_name) apps,  
   o.ORACLE_username, fpi.status, fpi.install_group_num,  
   fpi.product_version, fpi.sizing_factor,   
   fpi.tablespace, fpi.index_tablespace, fpi.temporary_tablespace  
 from fnd_oracle_userid o, fnd_application a, fnd_product_installations fpi  
 where fpi.application_id = a.application_id(+)  
  and fpi.oracle_id = o.oracle_id(+)  
 order by 1,2  
 /  
   
 prompt --> Kayıtlı Uygulamalar
   
 select application_id, application_short_name,  
    basepath  
 from fnd_application  
 order by application_id  
 /  
   
 prompt --> Kayıtlı Oracle Schema'larını Bulmak için  
   
 select oracle_id, oracle_username, install_group_num, read_only_flag  
 from fnd_oracle_userid  
 order by 1  
 /  
   
 prompt --> Kurulu olan dilleri bulmak için  
   
 select decode(installed_flag,'I','Installed','B','Base','Unknown')   
   installed_flag,  
   language_code, nls_language from fnd_languages  
 where installed_flag in ('I','B')  
 order by installed_flag  
 /  

Aşağıdaki raporda kurulu uygulamaların düzenli bir şekilde gösterilmesi amacıyla yaratılmıştır.

SELECT report_headings.report_date,  
     report_headings.sid_name,  
     fa.application_id appn_id,  
     decode(fa.application_short_name,  
        'SQLAP', 'AP', 'SQLGL', 'GL', fa.application_short_name ) appn_short_name,  
     substr(fat.application_name,1,50)||  
        decode(sign(length(fat.application_name) - 50), 1, '...') Application,  
     fa.basepath Base_path,  
     fl.meaning install_status,  
     nvl(fpi.product_version, 'Not Available') product_version,  
     nvl(fpi.patch_level, 'Not Available') patch_level,  
     to_char(fa.last_update_date, 'DD-Mon-YY (Dy) HH24:MI') last_update_date,  
     nvl(fu.user_name, '* Install *') Updated_by  
  FROM applsys.fnd_application fa,  
     applsys.fnd_application_tl fat,  
     applsys.fnd_user fu,  
     applsys.fnd_product_installations fpi,  
     apps.fnd_lookups fl,  
     ( SELECT to_char(sysdate, 'DD-Mon-YY HH24:MI') report_date,  
         vd.name sid_name  
       FROM v$database vd ) report_headings   
  WHERE fa.application_id = fat.application_id  
   and fat.language(+) = userenv('LANG')  
   and fa.application_id = fpi.application_id  
   and fpi.last_updated_by = fu.user_id(+)  
   and fpi.status = fl.lookup_code  
   and fl.lookup_type = 'FND_PRODUCT_STATUS'  
 UNION ALL  
 SELECT report_headings.report_date,  
     report_headings.sid_name,  
     fa.application_id,  
     fa.application_short_name,  
     substr(fat.application_name,1,50)||  
        decode(sign(length(fat.application_name) - 50), 1, '...'),  
     fa.basepath,  
    'Not Available',  
    'Not Available',   
    'Not Available',  
     to_char(fa.last_update_date, 'DD-Mon-YY (Dy) HH24:MI'),  
     nvl(fu.user_name, '* Install *')   
  FROM applsys.fnd_application fa,  
     applsys.fnd_application_tl fat,  
     applsys.fnd_user fu,  
        ( SELECT to_char(sysdate, 'DD-Mon-YY HH24:MI') report_date,  
          vd.name sid_name  
       FROM v$database vd ) report_headings   
  WHERE fa.application_id = fat.application_id  
   and fat.language(+) = userenv('LANG')  
   and fa.last_updated_by = fu.user_id(+)  
   and fa.application_id not in   
     ( SELECT fpi.application_id  
       FROM applsys.fnd_product_installations fpi )  
  ORDER by 5 

Referanslar:

1-http://www.piper-rx.com/pages/reports_free/fadm001_10.trd

Oracle Veritabanı: Veritabanına Olan Bağlantının Uzatılması - Kullanıcı Profilleri - Sql*Net Dead Connection Detection and User Profiles

Veritabanına olan bağlantılarımızı uzatmak ya da kısaltmak istiyorsak bununla ilgili bir parametre bulunmaktadır. $ORACLE_HOME/network/admin/ altında bulunan sqlnet.expire_time parametresii 10 dakikaya ayarlarsak eğer sistem her 10 dakikada bir session'ı kontrol edip aktivite olup olmadığına bakar ve bunun sonucuna göre session'ı disconnect eder.



Ancak yukarıda bahsettiğimiz konu veritabanı bağlantısıyla ilgilidir.Veritabanına bir kere bağlandıktan sonra veritabanına bağlanan kullanıcının profilinde idle_time set edildiyse o süre sonunda time out olur. Yani bağlantının uzun olması bir işe yaramaz. Buradaki sorguyla "idle_time" konusuyla ilgili profil bilgileri yer alır.

SELECT PROFILE, LIMIT FROM DBA_PROFILES WHERE RESOURCE_NAME = 'IDLE_TIME';

Hangi kullanıcının hangi profili olduğunu görmek için ise aşağıdaki sorguyu kullanabiliriz.

select profile from dba_users where username='kullanıcının_ismi';

Bir kullanıcıya profil atamak için:

 alter user kullanıcı_ismi profile profil_ismi  

Profil yaratmak için:

Profil yaratabilmek için "create profile" yetkisine sahip olmak gerekir. Bu şekilde kullanıcılar için kaynak kısıtlamaları koyabiliriz. Profil yaratmak için "resource manager" kullanılması tavsiye edilir; ama dediğimiz gibi eğer elle yapacaksak profil yaratma işini  synatax aşağıdaki gibidir.

"Create profile profil_ismi limit resource_parameters;"

ya da

"Create profile profil_ismi limit password_parameters;"

Resource_parameters olarak belirtilen parametreler:

-sessions_per_user
-cpu_per_session
-cpu_per_call
-connect_time
-idle_time
-logical_reads_per_session
-logical_reads_per_call
-composite_limit
-private_sga

Bunların alabileceği değerler ise belirli bir sayı olabilir, "unlimited" veya "default" olabilir.

Password_parameters olarak belirttiğimiz parametreler:

-failed_login_attempts
-password_life_time
-password_reuse_time
-password_reuse_max
-password_lock_time
-password_grace_time
-password_verify_function

Bunların alabileceği değerler: değer,unlimited,default.

Örnek profil yaratma script'i:

 DROP PROFILE "DEFAULT" CASCADE;  
   
 CREATE PROFILE "DEFAULT" LIMIT  
  SESSIONS_PER_USER UNLIMITED  
  CPU_PER_SESSION UNLIMITED  
  CPU_PER_CALL UNLIMITED  
  CONNECT_TIME UNLIMITED  
  IDLE_TIME UNLIMITED  
  LOGICAL_READS_PER_SESSION UNLIMITED  
  LOGICAL_READS_PER_CALL UNLIMITED  
  COMPOSITE_LIMIT UNLIMITED  
  PRIVATE_SGA UNLIMITED  
  FAILED_LOGIN_ATTEMPTS 10  
  PASSWORD_LIFE_TIME UNLIMITED  
  PASSWORD_REUSE_TIME UNLIMITED  
  PASSWORD_REUSE_MAX UNLIMITED  
  PASSWORD_LOCK_TIME UNLIMITED  
  PASSWORD_GRACE_TIME UNLIMITED  
  PASSWORD_VERIFY_FUNCTION NULL;  

Profillerle ilgili  doküman: http://docs.oracle.com/cd/B28359_01/server.111/b28286/statements_6010.htm#SQLRF54211



18 Aralık 2013 Çarşamba

Oracle E-Business Suite: Session Timeout - Forms Timeout Olma Süresi Parametresi - Forms Session Timeout Parameter

Form'ların timeout olma süreleri "ICX Limit Time" ve "ICX Session Timeout" parametreleri tarafından kontrol edilmektedir. "ICX Limit Time" opsiyonu default olarak site seviyesinde 4 saate ayarlanmıştır.  Bunun anlamı kullanıcılar 4 saat sonra bir uyarı alacaklardır yaptıkları işlemlere bağlı kalmaksızın. "ICX Session Timeout" ise 30 dakikaya ayarlanmıştır. Forms veya web session altında hiçbir işlem yapmadan 30 dakika geçirilirse session bitirilir. Eğer bu süreyi 2 katına çıkartmak istiyorsak hem uygulama tarafından profil değerini 2 katına çıkarırız, hem de  "s_sesstimeout" parametresini context file'da değiştirdikten sonra autoconfig çalıştırılır.(Autoconfig Nasıl Çalıştırılır?) Bu işlem sonunda afterconfig.sh dosyasının da çalıştırılması gerekteğini unutmayalım.

Session Timeout Parametresi
Not: Context dosyası $INST_TOP/appl/admin/$CONTEXT_NAME.xml'dır.

ICX:TIMEOUT Profil Değerleri:

Buradaki bazı parametreler birbirlerini etkileyebilirler.

Parameter
Parametre
Tavsiye Edilen Değer
ICX:Session Timeout
Null
30 (dakika)
ICX: Limit Time
4 (saat)
4 (saat)
ICX: Limit Connect
1000
2000


· ICX:Session Timeout - Bu profil değeri dakika cinsinden bir kullanıcının hiçbir aktivite gerçekleştirmeden ne kadar süre inaktif olarak kalabileceğini belirler. Bu durumda kullanıcı geri geldiğinde şifre ve gerekli bilgiler girilerek session tekrar aktif hale getiriliebilinir. Bu parametrenin 30 dakikadan fazla süreye set edilirse JVM miktarı  yeterli olmayıp hata alabiliriz.

· ICX: Limit time - Bu profile ile bir bağlantının dayanabileceği maksimum süreyi belirtmiş oluruz. Bu süre içinde kullanıcı aktif olsa da bu süre sonunda session kesilir. 'ICX:Session Timeout'  null olarak belirlendiyse , , bir session en fazla ICX:Limit Time kadar dayanabilir.

· ICX: Limit connect - Limit Connect profili ile bir kullanıcının bir bağlantı sırasında yapabileceği maksimum bağlantı sayısını gösterir. Üzerinde oynanması tavsiye edilmez. Çünkü kullanıcı bağlandığında, EBS'de bununla birlikte kendi bağlantılarını yapmaktadır. O yüzden bazı değerler gözden kaçırılabilinir.

S_OC4J Timeout - S_Sesstimeout Error: 

Yakın zaman içerisinde bütün kullanıcıların formları belirli bir süre geçtikten sonra kapanmaktaydı. Forms_timeout ifadesi 2 saat olmasına rağmen form'lar hemen kapanıyordu. OC4J Session Timeout profili Forms Session Timeout'undan önce timeout olduğu için formlar erken kapnıyormuş. Bu yüzden parametrelerin eş veya birbirini etkilemeyecek değerlere set edilmesi gerekir.

17 Aralık 2013 Salı

Oracle Veritabanı: AWR Raporlarını Okumak - Reading AWR Reports

Awr raporlarını daha çok bir performans sorunu yaşadığımızda çıkarırız. Awr raporları ile veritabanındaki aktiviteleri rahatça görebiliriz. Bu raporlarda performansla ilgili bilgiler güzelce ayarlanmışlardır. Awr raporlarını çıkarırken 1 saatten daha uzun aralıkları kontrol etmemiz genel sorunları fark etmemiz için daha yararlı olur.

AWR Raporları Nasıl Yaratılmaktadır?

Her 60 dakikada bir veritabanında bir snapshot alınır. Snapshot da veritabanın durumu ile ilgili o andaki bilgiler toplanır. Sonrasında bu bilgiler data dictionary de depolanır. Bu snapshot'lar bir id ile işaretlenir.

AWR Raporu:

Veritabanında asıl olarak aradığımız sorun performans olduğu için sistemin ne için beklediğini görmek yani wait event'lerini araştırmak daha önemlidir. Process'ler beklediğinde genelde başka process'ler tarafından bekletildikleri için beklerler.

Raporun başlangıcında sistem ile ilgili genel bilgiler verilir. Sistemin kullandığı hafıza, bu hafızanın nerelere ayrıldığı, sistemdeki CPU kullanımı gibi bilgiler yer almaktadır.

Raporun içerisinde Wait Event'leriyle ilgili, Memory kullanımı ile ilgili ve diğer veritabanı içerisindeki ana modüllerdeki kullanım istatistikleri gösterilir.

Bazı incelediğimiz başlıklar aşağıdaki gibidir:

Load Profile:

Bu bölümde SQL'lerle ilgili profil bilgileri yer alınır. Üretilen redo log'lar fiziksel okuma ve yazmalar, transaction'lar, Parse edilen SQL sayıları ve bunların istatistikleri yer alır. Sisteme göre bunların sayılarının fazla mı az mı olduğunu tahmin edebiliriz. Aşağıdaki örneğimize bakaraktan sisteme girişilerin(logons) az olduğunu, transaction'ların fazla olmadığını, hard parse'ların minimum değerlerde olduklarını görebiliriz. Buradan da sistemin üzerindeki yükün çok fazla olmadığını anlayabiliriz.

DB Time: Kullanıcının veritabanında harcadığı zamandır. Bu değer kullanıcının background process'leriyle beklediği süreyi vermez. Kendi session'ımız için olan bekleme süresini görmek için  aşağıdaki gibi bir sorgu yazabiliriz.

select * from v$sess_time_model where stat_name='DB time' and SID=2;

Diğer bir sorgu ise bütün veritabanı için geçerlidir.bütün session'ların db_time'ının toplanmasıyla bulunur.

 select * from v$sys_time_model where stat_name='DB time'; 

DB CPU: Kullanıcının CPU'da geçirdiği zamandır. Değerler mikrosaniye cinsindendir.

Sequence Load Elapsed Time: Sequence'larda gelecek numaranın elde edilmesi için geçirilen zamandır. Eğer sequence'lar cache'lenirse bu miktar sıfırlanır.

Redo Size: Üretilen redo verileridir.

Logical Reads:

Physical Reads: I/O isteklerine neden olan okumalar. Veritabanı bloklarından direk okumalar

Block Changes: O aralıkta değiştirilen blok sayısı

Physical Writes: Bloklara yazma işlemleri

User Calls: Kullanıcılar tarafından gönderilen sorgular

Parses: Hard ve Soft parse'ların toplamı

Hard Parse: Cache'de olmayan ve tamamen yeni bir SQL parse'ı gerektiren sorgular. Bu sorgular analiz edilerek planları çıkartılır.

Soft Parse: Geçmiş Hard Parse edilmiş sorgulardan çıkartılırlar. Hard Parse'lara göre daha az kaynak tüketirler. Örneğin çalışanlar tablosu Cache'de yokken sorgulandıysa Hard Parse edilir. Sonrasında bu tabloyla ilgili başka bir bilgi istendiğinde bu sorgu artık Hard Parse edilmez. Daha önceki kullanımdan kalan bilgilerle Soft Parse edilir.

Failed Parse Elapsed Time: Parse hatasıyla sonunda fail eden sorgulardır.

Logons: Uygulamaya yapılan girişler

Executes: Çalıştırılan SQL'ler. Select ifadeleri için bu istatistiğin içine sonuçların getirilmesi de eklenir.

Background CPU Time: Veritabanının background process'leri tarafından harcanan zaman

Transactions: Yapılan Transaction'lar.

Not: Transaction Nedir?
Transaction olarak belirttiğimiz sorgular ya DML ifadeleridir ya da DDL ifadeleridir. DDL ifadeleri gönderildiğinde otomatik olarak commit edilirken, DML ifadeleri gönderildiğinde ertesinde commit veya rollback sorgularıda gönderilmelidirler ki transaction bitsin.

Bütün istatistikleri görmek için v$statname sorgusu kullanılmalıdır.

 select * from v$statname; 

Time Model Örneği:

Buradaki örneğimize göre SQL'lerin çalışma zamanı en fazla zaman alan işlem. Awr raporunun alındığı aralıkta PL/SQL prosedürünün çalıştırılması en fazla zaman alan 3. işlemdir.



Session'ımızdaki Toplanmış İstatistikler:
Buradan da session'ımızla ilgili istatistikleri awr raporu çıkarmadan görebiliriz.


select * from v$mystat a inner join v$statname b on a.statistic#=b.statistic#;

Session'ımızı başka session'larla karşılaştırmak istersek aşağıdakinin benzeri bir sorgu yazabiliriz. Bu sorgu kısaca session pga memory'si 30mb'dan büyük olan session'ları bulmak üzerinedir.

 select t.sid,username,name,value from   
 v$statname n,v$session s, v$sesstat t  
  where s.sid=t.sid   
  and n.statistic#=t.statistic#  
  and s.type='USER'  
  and s.username is not null  
  and n.name='session pga memory'  
  and t.value> 30000;  

Instance Efficency Percentages:

Bu bölümde memory'nin hangi bölümlerine ne kadar gidildiği belirlenir. Bu oranlar bir data parçasının hangi bölümde ne kadar çok bulunduğunu gösterir. Hepsinin değerleri %100'e yakın olmalıdır. Aşağıdaki örnek te Execute Parse % ve Parse CPU to Parse Elapsed % yüzdeleri aşağıdaki örnekte düşük olmalarının nedeni  parse etmeyle ilgili bir problem olabilir. Bind değişkenlerinin kullanılmaması veya Shared Pool'un yetersiz olması nedeniyle bu kadar düşük olabilir.

Buffer Hit: Bu oran aranan blokun diskten okuması yerine, buffer cachede kaç kere bulunduğunu gösterir.

Buffer Nowait: Data'nın yüzde kaç oranında hiç beklemeden bulunduğunu gösterir.

Library Hit: SQL ve PL/SQL'in  shared pool içerisinde yüzde kaç oranında bulunduğunu gösterir.

In-Memory Sort: Sort(Düzenleme) işlerinin disk yerine hafıza kısmında okumasının yapılmasının oranının kaç olduğunu gösterir.

Soft Parse: Shared Pool içerisine depolanmış SQL'in ne kadar çok kullanıldığını gösterir.

Latch Hit: Latch işlemlerinin hiç bekletilmeden ne kadar oranda erişildiğini gösterir.

Shared Pool Statistics:

Buradaki istatistikler hafızanın ne kadarının kullanıldığını göstermektedir. Hafızanın yüzde 90'ından fazlası kullanılıyorsa burada Shared Pool için ayrılan hafıza konusunda eksiklikler olduğu öngörülebilir.




Advisory Statistics:

Advisory İstatistiklerinde veritabanında kullanılan hafıza parçaları ile ilgili çeşitli tavsiye edilen hafıza miktarları ve hangi hafıza oranında artışların sisteme ne kadar etki edeceğini gösteren tablolar bulunur.


IO Stats:

IO Stats'da dosya okuma yazma işlemleriyle ilgili bilgiler bulunur. Hangi dosyalarını ne kadar okunduğu, hangi tablespace'lerde ne kadar okuma yapıldığı ve bunların oranlarr, hangi fonksiyonların okuma yazma işlemlerini nasıl ve ne kadar yaptığını  gösterir. Bu şekilde hangi dosya veya tablespace'lerde okuma yazma yoğunluğu olduğunu keşfedebiliriz.



Top 5 Timed Events:

Bu bölümde bütün session'lar için bekleme istatistikleri ve ne için beklenildiği ölçülür. En çok karşılaşılan Wait Event'leri sıralanmıştır. En önemli bölümdür. Wait Class bölümünde sorunun neyle ilgili olduğunu görebiliriz. Waits sütünu kaç kere bekleme gerçekleştiğini göstermektedir. Time sütunu ise veritabanında toplam ne kada CPU zamanı geçirildiğini gösterir.



Buradaki wait olaylarına göre nerelerde sıkışıklık olduğu görülebilinir. Veritabanında çok fazla okumamı var, yoksa okumalar mı yavaş gerçekleşiyor bunları görebiliriz. Wait Class'larına bakarak hangi konularla ilgili sorunlar olduğu bulunabilinir.

İlk 5 problem arasında Latch Wait'leri varsa bu araştırılması gereken sorundur. Veritabanı genel olarak yavaş ise  ve "CPU", "Db  file sequential read", "Db file scattered read" bilgilerini içeriyorsa  SQL'lerle ilgili bir sorun olma ihtimali vardır.

Db file scattered read: Bu wait event'i full table scans ve index fast full scan'leri gösterir. Bunu engellemek için index'lerin düzgün yaratılması ve tabloları sorgularken index scan'i tercih edecek şekilde düzenlenmiş sql'ler kullanılması gerekir. Full Table Scan'in gerçekleştiği tabloları görmek istersek Segment Statistics altında Segment By Physical Reads tablosuna bakabiliriz.

Db file sequential read:  Sequential read yapıldığında, scattered read'in tersi olarak index'lerle okuma yapıldığını gösterir. Bu işlemin çok olması uygulamanın yüksek bir istek sayısına sahip olduğunu gösterebilir.

Buffer busy wait: Belli bir blok'a olan erişimin fazla olması veya birden çok kaynak tarafından kullanılması "buffer busy wait" olayına neden olur.

Enq:TX - row lock contention: Herhangi bir SQL'in bir blok'u etkilemesi, modifiye etmesi durumunda bu blok üzerinde bir kilit konur. Bu kilit olarak belirttiğimiz lock'lar, başka bir SQL'den gelen istek sonrasında o SQL'in bekletilmesine neden olurlar. Diğer SQL'in işini bitirene kadar o blok üzerinde kilit yerleştirmesi, bu wait event'i tetikler.

SQL İstatistikleri:

Awr raporları SQL'lerle ilgili bir sürü rapor sunmaktadır.


Bu raporlarda çeşitli kriterlere göre elde edilmiş istatistikli SQL'ler konulara ayrılmıştır. En fazla CPU tüketenler, en fazla okuma yapanlar, en fazla parse edilmiş olanlar gibi konular vardır. Hangi konuyu düzeltmek istiyorsak o konudaki SQL'lere gitmeliyiz. O konularda değişiklikler yaptıktan sonra tekrar istatistik toplayarak sorunla ilgili gözlemler yapabiliriz. Örneğin sorunumuz Parse edilmiş sql'ler ise bunların parse edilmesini engellemek için tek bir kere sorgulayıp memory'e yerleştirebilir ve hep aynı şekilde sorgulanmasını sağlayabiliriz. Başka bir örnek verirsek eğer SQL ordered by Elapsed Time konusuna göre ayrılmış SQL'leri inceleyip bu SQL'lerle ilgili gözlemler yapıp bunların niye çok sürdüğünü, bir lock yüzünden mi bu kadar uzun sürdüğünü veya çok fazla mı fiziksel okuma yaptığını inceleyebiliriz.

Buradaki başlıklardan SQL ordered by CPU Time başlığı da çok kullanılan başlıklardandır. Burada en fazla kaynak tüketen SQL ve PL\SQL'ler gösterilmektedir. Buradaki SQL ve PL\SQL'leri veritabanına etkilerini azaltmak içindüzenleyebiliriz.

Referans:
http://mallinenisrihari.blogspot.com.tr/2012/02/awr-report-analysing.html
http://www.bash-dba.com/2011/09/how-to-read-awr-reports-1.html




16 Aralık 2013 Pazartesi

Oracle Veritabanı: Günlük Üretilen Archive Log Sayıları ile ilgili SQL - Daily Archivelog Production SQL

Aşağıdaki SQL sqlplus için formatlanmıştır. Bu sql ile günlük archivelog üretimi görülebilinir. Aşırı kullanışlı bir SQL. Bize kısaca commit'lerin yani I/O'ların en fazla ne zaman yoğunlaştığını gösteren bir görüntü verir.


 col MidN format 999  
 col 1AM format 999  
 col 2AM format 999  
 col 3AM format 999  
 col 4AM format 999  
 col 5AM format 999  
 col 6AM format 999  
 col 7AM format 999  
 col 8AM format 999  
 col 9AM format 999  
 col 10AM format 999  
 col 11AM format 999  
 col Noon format 999  
 col 1PM format 999  
 col 2PM format 999  
 col 3PM format 999  
 col 4PM format 999  
 col 5PM format 999  
 col 6PM format 999  
 col 7PM format 999  
 col 8PM format 999  
 col 9PM format 999  
 col 10PM format 999  
 col 11PM format 999  
 select to_char(first_time,'mm/dd/yy') logdate,  
 sum(decode(to_char(first_time,'hh24'),'00',1,0)) "MidN",  
 sum(decode(to_char(first_time,'hh24'),'01',1,0)) "1AM",  
 sum(decode(to_char(first_time,'hh24'),'02',1,0)) "2AM",  
 sum(decode(to_char(first_time,'hh24'),'03',1,0)) "3AM",  
 sum(decode(to_char(first_time,'hh24'),'04',1,0)) "4AM",  
 sum(decode(to_char(first_time,'hh24'),'05',1,0)) "5AM",  
 sum(decode(to_char(first_time,'hh24'),'06',1,0)) "6AM",  
 sum(decode(to_char(first_time,'hh24'),'07',1,0)) "7AM",  
 sum(decode(to_char(first_time,'hh24'),'08',1,0)) "8AM",  
 sum(decode(to_char(first_time,'hh24'),'09',1,0)) "9AM",  
 sum(decode(to_char(first_time,'hh24'),'10',1,0)) "10AM",  
 sum(decode(to_char(first_time,'hh24'),'11',1,0)) "11AM",  
 sum(decode(to_char(first_time,'hh24'),'12',1,0)) "Noon",  
 sum(decode(to_char(first_time,'hh24'),'13',1,0)) "1PM",  
 sum(decode(to_char(first_time,'hh24'),'14',1,0)) "2PM",  
 sum(decode(to_char(first_time,'hh24'),'15',1,0)) "3PM",  
 sum(decode(to_char(first_time,'hh24'),'16',1,0)) "4PM",  
 sum(decode(to_char(first_time,'hh24'),'17',1,0)) "5PM",  
 sum(decode(to_char(first_time,'hh24'),'18',1,0)) "6PM",  
 sum(decode(to_char(first_time,'hh24'),'19',1,0)) "7PM",  
 sum(decode(to_char(first_time,'hh24'),'20',1,0)) "8PM",  
 sum(decode(to_char(first_time,'hh24'),'21',1,0)) "9PM",  
 sum(decode(to_char(first_time,'hh24'),'22',1,0)) "10PM",  
 sum(decode(to_char(first_time,'hh24'),'23',1,0)) "11PM"  
 from v$log_history  
 group by to_char(first_time,'mm/dd/yy')  
 order by 1;  








Oracle E-Business Suite: Error - Oracle E-Business Suite'de Patch Sonrası Format Bozulması - Changed Format in Oracle E-Business Suite After An Applied Patch

Oracle E-Business Suite'de uyguladığımız bir patch sonrasında Application arayüzünde yazılar ve görüntüler kaydı. Bu bozukluk "Dashboard" sayfasında ve "IProcurement" sayfasında kendisini gösterdi. Bununla ilgili araştırdığım dokümanlara göre uygulamayı kapattıktan sonra  "$OA_HTML/cabo/styles/cache" ve "$OA_HTML/cabo/images/cache" dosyaları backup'lanır.

 cd $OA_HTML/cabo/styles  
 cp -R cache cache_bck  

 cd $OA_HTML/cabo/images/cache  
 cp -R cache cache_bck 


Backupladıktan  sonra buradaki cache dosyası içerisindekiler silinir.

 cd $OA_HTML/cabo/styles/cache  
 rm -rf c*  
 cd $OA_HTML/cabo/images/cache  
 rm -rf c*  

Bu işlem sonrasında format ve font bozuklukları giderilmiş olunur. Bu işlem sonrasında uygulama açılıp tekrar login olunulduğunda hala hataya denk geliyorsak browser cache'ınden değil de tekrar sunucundan uygulamayı başlatmamız gerekir. Bunuda "ctrl+f5" ile yapabiliriz. Bu şekilde tekrardan, browser cache'ıne bakmadan bağlantıyı çalıştırmış oluruz. Eğer bu işlemde sorunu düzeltmiyorsa sorunu support.oracle.com'da aramamız gerekir.

13 Aralık 2013 Cuma

Oracle E-Business Suite: Error - Gönderilmeyen E-Postalar - Unsent Worklow E-Mail

Oracle E-Business Suite'de gönderilemeyen e-postalar için bir uyarı ekranı vardır. Bu uyarı ekranı System Administrator sorumluluğu altında Dashboard seçeneğindeki Performance tab'ı altında görülebilinir. (System Administrator>Dashboard>Performance). Bu Performance tab'ı altında Activity adlı parça altında "Unsent Workflow E-Mail" olarak gözüken kısım da bu belirttiğimiz uyarı bilgisi yer alır. Bu uyarı aşağıdaki gibidir.



Bu örneğimizde 5 tane gönderilememiş e-posta olduğu gözükmektedir. Bunu veritabanından da görmek istersek aşağıdaki ekrandaki sorguyu kullanabiliriz.

 select * from wf_notifications where mail_status='MAIL' and end_date is not null and status='CLOSED';



Bu uyarıyı düzeltmek için veritabanında bir sorgu girmemiz gerekir.

 update wf_notifications  
 set mail_status = 'SENT'  
 where end_date is not null  
 and status = 'CLOSED'  
 and MAIL_STATUS = 'MAIL';  
   
 commit;  

Yukarıdaki sorguyu çalıştırdığımızda en başta belirttiğimiz ekrandaki uyarı 0'lanır.

Wf_Notifications Altındaki Gönderilecek Mailler:

Eğer bir mail notification'ın statüsü OPEN ve mail_status MAIL ise bununla ilgili bir mail gönderilecek demektir.

  select notification_id,status,mail_status,begin_date from WF_NOTIFICATIONS where status = 'OPEN' and mail_status = 'MAIL';

Gönderilmemesi İstenen Mailler:

Mail_status'leri Mail olanları Sent olarak değiştirirsek bunlarla ilgili mail atılmaz.

update WF_NOTIFICATIONS set mail_status = 'SENT' where mail_status = 'MAIL';

Workflow Mail'lerinin İptal Edilmesi:

Workflow'ların iptal edilmesini sağlamak için aşağıdaki kodu kullanmamız gerekir. Ancak dikkatli kullanılmalıdır çünkü o an çalışan workflow'lar da iptal edilebilinir. O yüzden bir şart belirtilmelidir.

 DECLARE   
 ln_sayi number;   
 BEGIN   
  ln_sayi := 0;   
   for rec in   
 (select * from apps.wf_notifications where status = 'OPEN' and Mail_status='MAIL' and begin_date

Yukarıdaki kodda bu şart başlangıçtan 7 gün öncesi için belirtilmiştir. 7 gündür açık olan bir notification maili hala mail status'unde gözüküyorsa o zaman bu notification kapatılır.

Wf_Notifications Queue(Sıra) Düzenlemesi:

Şimdi belirteceğimiz sql'i çalıştırarak bekleyen mailleri silip sadece gönderilecek mailleri sırada tutabiliriz.  Bu şekilde yanlış bir işlem yapıp eğer mail miktarını arttırmış olursak bunu bu şekilde düzenleyebiliriz.

 sqlplus apps/apps_pwd @$FND_TOP/patch/115/sql/wfntfqup APPS APPS_PWD APPLSYS
Not:Apps_pwd; apps kullanıcısının şifresidir.


12 Aralık 2013 Perşembe

Oracle Veritabanı: Fazladan Kullanılan Yerin Geri Kazanılması - Reclaiming Wasted Space

Fazladan kullanılmış olarak belirlenen yerler zaman içinde çok fazla update, delete, insert ifadeleriyle birlikte oluşan boş bloklardır. Bu bloklar tekrar yerleştirilirse daha önceden boş olarak gözükmeyen yerler veritabanı tarafından görülmeye başlanacaktır. Bu boşluklar fragmante edilmiş boş alanlar olarak tanımlanmaktadırlar.

Boş Bloklar Nasıl Oluşmaktadırlar?

Tabloya gelen transaction'lar datafile'lara kayıt ekledikçe bloklar bunlara göre arka arkaya düzenlenirler. Bu düzenleme sırasında bazı bloklar silinip, tabloya yeni ve daha büyük kayıtlar geldiğinde bu bloklar kullanılamazlar. Bu bloklar kullanılamamalarına rağmen boş durumdadırlar. Tablonun bu parçalanmış durumu hem harcanmış disk alanına hemde veritabanında performans kaybına yol açmaktadır.

Nasıl Düzeltililir?

Bu durumu düzeltmek için "online segment shrink"  işlemi gerçekleştirilir. Bu işlem ile boş alanlar birleştirilir ve kayıtların yazılacağı blok sınırını düşürür. Yani aynı extent içine daha fazla kayıt eklenebilir, daha fazla yer kazanılır.

Boş Alanlar Nasıl Bulunur?

Kullanılamayan boş alanları bulmak için "Segment Advisor" kullanılır. Bu araç hem Enterprise Manager'dan, hem veritabanından çalıştırılabilinir. Segment Advisor daha önceden çalıştıysa aşağıdaki sorgu bize Segment Advisor'ın bakıp bulduğu tablolardan hangisinde ne kadar yer kazanılabileceği ya da o tablolarda ne yapılması gerektiğini gösterir.

 SELECT segment_name,  
       round(allocated_space/1024/1024,1) alloc_mb,  
       round( used_space/1024/1024, 1 ) used_mb,  
         round( reclaimable_space/1024/1024) reclaim_mb,  
         round(reclaimable_space/allocated_space*100,0) pctsave,  
       recommendations  
    FROM TABLE(dbms_space.asa_recommendations())  
   where segment_owner = user  

Bir Tablespace'de Bulunan Tablo ve Index'ler İçin Boş Bloklar Var Mıdır?

Bu procedure'umuzu Toad'da DBMS Output açık olarak çalıştırırsak bize belirli bir tablespace'deki tablo ve index'lerde bulunabilecek boş bloklarla ilgili bilgi verebilir.


DECLARE  
  v_total_blocks  NUMBER;  
  v_total_bytes  NUMBER;  
  v_unused_blocks NUMBER;  
  v_unused_bytes  NUMBER;  
  v_file_id    NUMBER;  
  v_block_id    NUMBER;  
  v_last_block   NUMBER;  
  v_used      NUMBER;  
  v_owner     VARCHAR2(12);  
  v_segment    VARCHAR2(80);  
  v_type      CHAR(1);  
   
  CURSOR index_c is  
  SELECT owner, index_name  
   FROM sys.dba_indexes  
   WHERE tablespace_name = upper('&ts_name');  
   
  CURSOR table_c is  
  SELECT owner, table_name  
   FROM sys.dba_tables  
   WHERE tablespace_name = upper('&ts_name');  
   
 BEGIN  
  DBMS_OUTPUT.ENABLE(100000);  
  v_type := '&type';  
  IF (v_type = 'i' or v_type = 'I') THEN  
    OPEN index_c;  
    FETCH index_c into v_owner, v_segment;  
    WHILE index_c%FOUND LOOP  
       --  
       DBMS_SPACE.UNUSED_SPACE(v_owner, v_segment, 'INDEX', v_total_blocks, v_total_bytes,  
                   v_unused_blocks, v_unused_bytes, v_file_id, v_block_id, v_last_block);  
       --  
       DBMS_OUTPUT.PUT_LINE(CHR(10));  
       DBMS_OUTPUT.PUT_LINE('Index Name          = '||v_segment);  
       DBMS_OUTPUT.PUT_LINE('Total Blocks         = '||v_total_blocks);  
       DBMS_OUTPUT.PUT_LINE('Total Bytes         = '||v_total_bytes);  
       DBMS_OUTPUT.PUT_LINE('Unused Blocks        = '||v_unused_blocks);  
       DBMS_OUTPUT.PUT_LINE('Unused Bytes         = '||v_unused_bytes);  
       v_used := v_total_blocks - v_unused_blocks;  
       DBMS_OUTPUT.PUT_LINE('Used Blocks         = '||v_used);  
       v_used := v_total_bytes - v_unused_bytes;  
       DBMS_OUTPUT.PUT_LINE('Used Bytes          = '||v_used);  
       DBMS_OUTPUT.PUT_LINE('Last used extents file id  = '||v_file_id);  
       DBMS_OUTPUT.PUT_LINE('Last used extents block id  = '||v_block_id);  
       DBMS_OUTPUT.PUT_LINE('Last used block       = '||v_last_block);  
       fetch index_c into v_owner, v_segment;  
    END LOOP;  
    CLOSE index_c;  
  ELSIF (v_type = 't' or v_type = 'T') THEN  
   OPEN table_c;  
     FETCH table_c into v_owner, v_segment;  
     WHILE table_c%FOUND LOOP  
       --  
       DBMS_SPACE.UNUSED_SPACE(v_owner, v_segment, 'TABLE', v_total_blocks, v_total_bytes,  
                   v_unused_blocks, v_unused_bytes, v_file_id, v_block_id, v_last_block);  
       --  
       v_used := v_total_bytes - v_unused_bytes;  
       DBMS_OUTPUT.PUT_LINE(CHR(10));  
       DBMS_OUTPUT.PUT_LINE('Table Name          = '||v_segment);  
       DBMS_OUTPUT.PUT_LINE('Total Blocks         = '||v_total_blocks);  
       DBMS_OUTPUT.PUT_LINE('Total Bytes         = '||v_total_bytes);  
       DBMS_OUTPUT.PUT_LINE('Unused Blocks        = '||v_unused_blocks);  
       DBMS_OUTPUT.PUT_LINE('Unused Bytes         = '||v_unused_bytes);  
       v_used := v_total_blocks - v_unused_blocks;  
       DBMS_OUTPUT.PUT_LINE('Used Blocks         = '||v_used);  
       v_used := v_total_bytes - v_unused_bytes;  
       DBMS_OUTPUT.PUT_LINE('Used Bytes          = '||v_used);  
       DBMS_OUTPUT.PUT_LINE('.  KBytes         = '||v_used/1024);  
       DBMS_OUTPUT.PUT_LINE('.  MBytes         = '||(v_used/1024)/1024);  
       DBMS_OUTPUT.PUT_LINE('Last used extents file id  = '||v_file_id);  
       DBMS_OUTPUT.PUT_LINE('Last used extents block id  = '||v_block_id);  
       DBMS_OUTPUT.PUT_LINE('Last used block       = '||v_last_block);  
       fetch table_c into v_owner, v_segment;  
    END LOOP;  
    CLOSE table_c;  
  END IF;  
 END;  
 /  


Segment Advisor Nedir?

"Automatic Segment Advisor" bir maintanence task'idir. Yani maintenance aralıklarında çalışan bir işlemdir. Bu işlem bazı veritabanı objelerini inceler. Bu objeler seçilmeden önce belirli kriterlere bakılır.

Bu kriterler:
-Tablespace'in belirli bir seviyeyi geçmiş olması
-Çok fazla aktif olan segment'ler(Yukarıda belirttiğimiz gibi update,delete,insert ifadeleri çok gerçekleşen tablolar)
-En fazla büyüyen segment'ler

Buna göre seçilen objeler maintenance aralıkları boyunca incelenirler.

Elle Segment Advisor'ı Çalıştırmak:

Segment Advisor maintenance aralıklıklarında otomatik olarak çalıştırdığımız için bazen elle çalıştırmamız gerekebilir. Merak ettiğimiz bir tablespace'i incelemek istiyorsak, elle çalıştırmamız gerekir.

Elle çalıştırabilmek için 2 yöntem vardır. Bir tanesi "Enterprise Manager"'dan "Segment Advisor Wizard"'a gidip istediğimiz tablespace'i veya tabloyu seçip "Run Segment Advisor"'ı seçebiliriz. Diğer yöntem de PL\SQL job'ı çalıştırmak olacaktır.

PL\SQL ile Segment Advisor çalıştırılması örneği:

 create or replace procedure segment_advisor_calistirmak  
   authid current_user  
  as  
    obj_id number;  
   begin  
    dbms_advisor.create_task (  
     advisor_name   => 'Segment Advisor',  
     task_name    => 'segment_advisor' );  
    
    dbms_advisor.create_object (  
     task_name    => 'segment_advisor',  
     object_type   => 'TABLE',  
     attr1      => berke,  --Kullanıcı ismi
     attr2      => 'employees',   --Tablo ismi
     attr3      => NULL,  
     attr4      => NULL,  
     attr5      => NULL,  
     object_id    => obj_id);  
    
    dbms_advisor.set_task_parameter(  
     task_name    => 'segment_advisor',  
     parameter    => 'recommend_all',  
     value      => 'TRUE');  
    
    dbms_advisor.execute_task('segment_advisor');  
   end;  
   /  

Yukarıdaki örnekte PL\SQL ile bir procedure oluşturmuş oluyoruz. Bu procedure'de belirli bir tablo ismi ve kullanıcı ismi vermiş bulunuyoruz. Bu şekilde her seferinde bu procedure'ı çağırdığımızda aynı tabloyla ilgili segment tavsiyeleri almış oluruz. Bu procedure'ı parametreli hale getirirsek de istediğimiz tabloyu veya tablespace'i inceleyecek hale getirmiş oluruz. Sonrasında aşağıdaki gibi çalıştırabiliriz.

Not: segment_advisor_calistirmak yukarıdaki prosedürümüzün adıdır.

exec segment_advisor_calistirmak;  

Bu procedure çalıştırıldıktan sonra bunların sonuçlarını görmek için 3 tane yöntem vardır.

-Enterprise Manager ile
-DBA_ADVISOR_* view'ları ile
-DBMS_SPACE.ASA_RECOMMANDATIONS prosedürünü

Shrink Etme İfadesi Nedir?

Tablolar için genel olarak küçültme ifadesini vermeden önce o tablo için "row movement" özelliği açık olmalıdır.

 "alter table tablo_adı enable row movement;"  

Sonrasında ise

"alter table tablo_adı shrink space compact;"  

ve

  "alter table tablo_adı shrink space;"  


Shrink İşleminin Sonuçlarını Nasıl Görebilirim?

Shrink edeceğimiz dosyanın boyutunu görmek için dba_tables tablosu sorgulanır.

 select blocks from dba_tables where table_name='TABLO_ADI';  

Bu şekilde tablomuzun şu an kapsadığı boyutu görebiliriz.

Shrink işlemini gerçekleştirdikten sonra da aşağıdaki gibi şu anki istatistikleri görebiliriz.

 analyze table tablo_adı compute statistics;  
   
 analyze table tablo_adı estimate statistics sample 10 percent;

O istatistikleri güncelledikten sonra tekrar aynı sorguyu çektiğimizde tablonun küçülme seviyesini görebiliriz.

 select blocks from dba_tables where table_name='TABLO_ADI';  

Buna istinaden dba_segments'den tablo boyutunu da inceleyebiliriz.

select bytes/1024/1024 as 'MB' from dba_segments where segment_name='tablo_adı';


Not: Ayrıca buradaki yazımıza da bakabiliriz. (Günlük Kontroller - Tablespace)


Referans:
http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:54178027703899
http://docs.oracle.com/cd/B28359_01/server.111/b28310/schema003.htm#ADMIN11608
http://myorastuff.blogspot.com.tr/2008/07/how-do-we-reclaim-wasted-space-in-table.html
http://www.bestremotedba.com/2010/05/11/reclaim-wasted-space-in-10g/