21 Aralık 2009 Pazartesi

Changing the Current Schema

Çalıştığımız session içinde geçerli olan schema bilgisini değiştirmek için;

alter session set current_schema=SCHEMA_NAME; /*without quotes*/

Küçük bir uygulama için tıklayınız...

Çoşkan' a teşekkürler.

How to display Processor information in Sun Solaris

# which psrinfo
/usr/sbin/psrinfo

For a more detailed output use the verbose option.
sunsolaris# psrinfo -v

sunsolaris# which prtdiag
/usr/sbin/prtdiag

sunsolaris# which prtconf
/usr/sbin/prtconf


http://www.sunsolarisadmin.com/hardware/how-to-display-processor-information-in-sun-solaris/

6 Ekim 2009 Salı

Oracle 11g Güvenlik Özellikleri

Oracle 11g versiyonu ile yeni ve üst düzey güvenlik özellikleri getirdi. Özellikle yeni sürüme geçiş öncesinde iyice incelenmesi ve test edilmesi gereken özellikler. (Hatta can sıkabilecek derecede geliştirilmiş özellikler). Bu konuda yazılmış pek çok makale bulabilirsiniz, fakat bence en faydalılarından birine Arup Nanda' nın makalesine aşağıdaki linkten ulaşabilirsiniz.

http://www.oracle.com/technetwork/articles/sql/11g-security-100258.html




24 Eylül 2009 Perşembe

Oracle' da rol istisnaları

Oracle veritabanında (rol kullanımından kaynaklanan) karşılaştığım bazı özel durumları not etmek istiyorum. Aslında bunlar bug olarak düşünülebilir fakat bu tarz bugların çözümüne yönelik bir şey yapılmayabilir.

Örneğin DBA rolüne sahip bir kullanıcı bile teorik olarak CREATE ANY MATERIALIZED VIEW, CREATE PUBLIC DATABASE LINK yetkileri olmasına rağmen başka bir kullanıcı altına bir DB link veya Materialized View create edemez.

Aşağıda karşılaştığım istisnaları ve çözümlerini kısaca açıklamaya çalıştım. Zaman buldukça ve karşılaştıkça yeni istinasları da eklemeyi düşünüyorum.

--Nesne Hakları
Genel kural:
Bir kullanıcının yetkisi olan bir objeyi bir procedure/function/pkg/view içinde kullanabilmesi için nesne üzerinde direk hakkı olması gerekiyor.
Mesela kullanıcının tablo üzerindeki rol üzerinden gelen hakları kullanıcının create edeceği herhangi bir SP içinde geçersiz oluyor. Bu durumda tablo için doğrudan yetki talebine ihtiyaç var.
Örneğin kullanıcı role üzerinden yetkisi olduğu bir tabloyu bir prosedür içinde select edemez. kendi schemasındaki prosedür içinde o tabloyu sorgulayabilmek için kullanıcıya doğrudan select hakkı verilmesi gerekiyor. (uygulama kullanıcıları ile normal kullanıcıları ayırmak bu yüzden de gerekli)

--DBLINK

DB link create edebilmek için şu 2 yöntem kullanabiliriz.
1. DB linki oluşturmak istediğimiz kullanıcıya yetki verip o kullanıcı ile login olup, linki oluşturmak ve yetkiyi geri almak.
2. DB linki oluşturmak istediğimiz schemaya yetki verip db link create scriptini çalıştıracak bir prosedürü o şema altında oluşturmak, prosedürü çalıştırmak, prosedürü drop etmek ve yetkiyi geri almak.

--MVIEW
Metarialized Veiw create etmek için role den bağımsız CREATE ANY MATERIALIZED VIEW yetkisinin kullanıcımıza doğrudan verilmesi gerekli.


25 Ağustos 2009 Salı

Change Oracle Database Name and DBID with NID utility


Change Oracle Database Name and DBID with NID utility

--close database with immediate 
SHUTDOWN IMMEDIATE
STARTUP MOUNT

--run "nid" command. end process of nid command database will be shutdown.
nid target=sys/oracle@RADB dbname=TSH2

--change db_name to new name in pfile
db_name =TSH2

--create a password file for new ORACLE_SID 
orapwd file=D:\oracle\product\11.1.0\db_1\database\pwdTSH2.ora password=oracle entries=10

--if os windows delete old service.
oradim -delete -SID RADB

--if os windows add service for new ORACLE_SID
oradim -new -SID TSH2

-- listener reload    
lsnrctl reload

--open database with resetlogs
STARTUP MOUNT

--if you want, you can rename database and redo file's name.

set linesize 200
select 'alter database rename file '''||name  ||''' to '''||replace(name, 'ORATST','ORCL')  ||''';' from v$datafile;
select 'alter database rename file '''||name  ||''' to '''||replace(name, 'ORATST','ORCL')  ||''';' from v$tempfile;
select 'alter database rename file '''||member||''' to '''||replace(member, 'ORATST','ORCL')||''';' from v$logfile;

ALTER DATABASE OPEN RESETLOGS;

2 Nisan 2009 Perşembe

Oracle - SESSIONS_PER_USER

Oracle veritabanında profil tanımları içinde bulununan SESSIONS_PER_USER değişkeni bir username ile veritabanında anlık login olabilecek session sayısı bilgisini atamak için kullanılır. Profile tanımında ayarlansa bile bu değişken default olarak etkili olmaz. Değişkenin etkili olması olabilmesi için RESOURCE_LIMIT initial parametresinin TRUE olarak ayarlanması gerekir.

Örnek profile tanımı:

CREATE PROFILE USER_PROF LIMIT CPU_PER_SESSION DEFAULT
CPU_PER_CALL DEFAULT
CONNECT_TIME DEFAULT
IDLE_TIME DEFAULT
SESSIONS_PER_USER 1
LOGICAL_READS_PER_SESSION DEFAULT
LOGICAL_READS_PER_CALL DEFAULT
PRIVATE_SGA DEFAULT
COMPOSITE_LIMIT DEFAULT
PASSWORD_LIFE_TIME 90
PASSWORD_GRACE_TIME 3
PASSWORD_REUSE_MAX 2
PASSWORD_REUSE_TIME 1
PASSWORD_LOCK_TIME DEFAULT
FAILED_LOGIN_ATTEMPTS 3;

Resource limit' i etkin hale getirmek için:

SQL> alter system set resource_limit=TRUE scope=both;

http://download.oracle.com/docs/cd/B19306_01/server.102/b14237/initparams183.htm#REFRN10188

30 Mart 2009 Pazartesi

RMAN DUPLICATE

Recovery Manager(RMAN) programının veri yedekleme yanında, veri kurtarma, taşıma konusunda bize sunduğu faydalı özelliklerinden biri de DUPLICATE özelliğidir.

Duplicate özelliği veritabanının tamamının veya bir kısmının kopyasını çıkarmamıza olanak sağlar.
Duplicate özelliğini kullanabilmek için;
- Veritabanının RMAN ile alınmış cross-check edilmiş bir backupının olması(full veya incremental)
- Belirli bir zamana gelebilmek için veritabanın archive modda çalışması ve güncel arşivlerimizin erişilebilir olması gerekir.

DUPLICATE ile online olarak veritabanımızı kopyalabilir veya istediğimiz tablespacelerden oluşan yeni bir veritabanı hazırlayabiliriz.

DUPLICATE ile aynı host üzerinde veya farklı hostlar üzerinde veritabanını kurmak mümkündür.
Host sistemlerin OS versiyonlarının ve tabiki oracle executable versiyonlarının aynı olması gerekir.

DUPLICATE ile yapabileceklerimiz
- Veritabanını online olarak kopyalamak.
- Daha önce aldığımız backupı ve geri dönüş planını test etmek.
- Drop edilen(purge dahil) veya truncate edilen bir tabloyu veya nesneyi kurtarmak.
- Standby db kurulumu.

olarak sayılabilir. Farklı senaryolarda farklı ihtiyaçlar için de elbetteki kullanılabilir.

Örnek olarak databasemizdeki bazı tablespaceler hariç diğer tüm datamızı belirli bir zamana döneceğimiz bir senaryo oluşturalım.

1 - Target db(yani source db) spfile ile başlatıldıysa önce bir pfile create edilir.

--productiona baglanip olusturalim
sqlplus /nolog
conn /as sysdba
create pfile=D:\oracle\product\10.2.0\oradata\AUX1\initAUX1.ora from spfile;
exit


2 - Pfile içindeki lokasyon parametreleri yeni lokasyonlara göre düzenlenir.
Datafilelar farklı bir lokasyona kopyalanacak ise ve datafile isimleri rename edilmeyecekse aşağıdaki iki parametrenin de pfile içinde set edilmesi gerekir.

DB_FILE_NAME_CONVERT=("D:\oracle\oradata\orcl", "D:\oracle\oradata\AUX1")
LOG_FILE_NAME_CONVERT=("D:\oracle\oradata\orcl","D:\oracle\oradata\AUX1")


Örneği Windows üzerinde yaptığımız için windows üzerinde db instance' ı başlatabileceğimiz servis girdisini oluşturuyoruz. Unix üzerinde bu kısma gerek yok.

oradim -new -sid AUX1 -intpwd oracle -startmode manual -pfile D:\oracle\product\10.2.0\oradata\AUX1\initAUX1.ora

3 - Hazırlanan pfile kullanılarak AUXILIARY instance (AUX1) nomount olarak başlatılır. Bu instance yeni kurmak isteğimiz database'e aittir.

4 - Her iki instance'ın RMAN tarafından erişilebilir olduğundan emin olmak için gerekli TNS ve listener tanımları yapılır. SYS userı için şifre dosyası ayarlanır.

5 - RMAN DUPLICATE scripti hazırlanır.

CONNECT TARGET system/system@proddb;
CONNECT CATALOG rman/rman@catalogdb;
CONNECT AUXILIARY SYS/oracle;

CONFIGURE CHANNEL DEVICE TYPE disk CLEAR;
CONFIGURE DEFAULT DEVICE TYPE TO disk;
CONFIGURE DEVICE TYPE disk PARALLELISM 3;

RUN {
# the DUPLICATE command uses an automatic disk channel
set until time "TO_DATE('03/11/2008 17:19:25','DD/MM/YYYY HH24:MI:SS')";

DUPLICATE TARGET DATABASE TO AUX1
SKIP TABLESPACE USERS
LOGFILE
GROUP 1 ('D:\oracle\oradata\AUX1\redo01m1.log',
'D:\oracle\oradata\AUX1\redo01m2.log') SIZE 20M REUSE,
GROUP 2 ('D:\oracle\oradata\AUX1\redo02m1.log',
'D:\oracle\oradata\AUX1\redo02m2.log') SIZE 20M REUSE;
}


6 - Scriptimizi çalıştırmadan önce pwd dosyası, tns ayarları, listener ayarları son kez kontrol edilir. Bu kısım özellikle büyük dblerde gereksiz zaman kaybını engellemek için önemlidir.

7 - Hazırlanan script çalıştırılır. Script neticesinde yeni instance' ın çalışır durumda hazır olmasını bekleyebiliriz.


Örneğimizde kullanmak amacıyla tablespace, schema ve tabloları aşağıdaki scriptler ile oluşturabiliriz.

Yapacaklarımız kısaca şöyle :
1 - Örnek datamızı oluşturacağız.
2 - RMAN ile control file dahil full yedek alacağız.
3 - Yedek alındıktan sonra silmek istediğimiz tabloyu drop edeceğiz.
4 - Hazırladığımız RMAN DUPLICATE scriptini çalıştıracağız.


conn /as sysdba
create tablespace tbs datafile 'D:\oracle\oradata\orcl\tbs01.dbf' size 10M;

create user ra identified by ra default_tablespace tbs;
grant connect, resource to ra;

drop table ra.silinecek purge;

create table ra.silinecek
(
id number,
ad varchar(20)
)
tablespace tbs;

insert into ra.silinecek values (to_char(sysdate, 'HH24SS'),'DD'||to_char(sysdate, 'HH24SS'));
insert into ra.silinecek values (to_char(sysdate, 'HH24SS'),'DD'||to_char(sysdate, 'HH24SS'));
insert into ra.silinecek values (to_char(sysdate, 'HH24SS'),'DD'||to_char(sysdate, 'HH24SS'));
insert into ra.silinecek values (to_char(sysdate, 'HH24SS'),'DD'||to_char(sysdate, 'HH24SS'));
insert into ra.silinecek values (to_char(sysdate, 'HH24SS'),'DD'||to_char(sysdate, 'HH24SS'));

commit;

drop table ra.kalacak purge;

create table ra.kalacak
(
id number,
ad varchar(20)
)
tablespace tbs;

insert into ra.kalacak values (to_char(sysdate, 'HH24SS'),'DD'||to_char(sysdate, 'HH24SS'));
insert into ra.kalacak values (to_char(sysdate, 'HH24SS'),'DD'||to_char(sysdate, 'HH24SS'));
insert into ra.kalacak values (to_char(sysdate, 'HH24SS'),'DD'||to_char(sysdate, 'HH24SS'));
insert into ra.kalacak values (to_char(sysdate, 'HH24SS'),'DD'||to_char(sysdate, 'HH24SS'));
insert into ra.kalacak values (to_char(sysdate, 'HH24SS'),'DD'||to_char(sysdate, 'HH24SS'));
insert into ra.kalacak values (to_char(sysdate, 'HH24SS'),'DD'||to_char(sysdate, 'HH24SS'));
insert into ra.kalacak values (to_char(sysdate, 'HH24SS'),'DD'||to_char(sysdate, 'HH24SS'));

commit;

select * from ra.silinecek;

select * from ra.kalacak;

--kayitlarimiz kontrol ettik ve hepsi yerli yerinde.

alter system switch logfile;
alter system switch logfile;
alter system switch logfile;
alter system switch logfile;
alter system switch logfile;
alter system switch logfile;
alter system switch logfile;

--redolar switch edildikten sonra RMAN den control file dahil full yedek alınır.

--Yedek aldıktan sonra ra.silinecek tablomuzu drop(purge ile) edebiliriz.

drop table ra.silinecek purge;


Scriptleri sorunsuz çalıştırdıktan sonra prod dbnin istediğimiz zamana kadar recovery edilmiş halini yeni dbmizde(AUX1) hazır olarak bulmayı umabiliriz.
teşekkürler.





26 Mart 2009 Perşembe

Kill inactive sessions in scheduled time



We needed kill for all inactive reporting users which has been inactive log an hour. This must have been a scheduled time in future. We can use such a below method for this purpose.

- Create schedular job that contaning running time.
- Put the below PL/SQL block in action side in that job.


As a result, sessions are automatically closed. Of course, this only applied to risk-free for users who selects. Users in a transaction with the closure of such a method is risky. You can desire select statement which using v$session view.



begin
FOR i IN (select username from dba_users where username like 'TEMP%')
LOOP
execute immediate 'alter user ' || i.username || ' account lock';
END LOOP;
FOR i IN (select sid, serial#, username from v$session where username like 'TEMP%')
LOOP
EXECUTE IMMEDIATE 'alter system kill session ' || '''' || i.sid || ',' || i.serial# || ''' immediate ';
END LOOP;
end;
/




13 Mart 2009 Cuma

Oracle Block change tracking

Oracle 10g ile gelen yeni ve kullanışlı bir özellik.
Normal şartlarda RMAN incremental backup alırken RMAN tüm blokları tarayarak bir önceki backuptan sonra bloğun değişip değişmediğine bakar ve eğer değişmişse yedeğini alır.
Burada en büyük zaman kaybına sebep olan şey RMAN ın bir bloğun değişip değişmediğini
anlaması için tüm blokları taramak zorunda kalmasıdır.

10g ile gelen bu yeni özellik ile blok değişimleri bir tracking file da tutulur.
Böylece RMAN sadece bu dosyayı inceleyerek yedek alması gereken bloklara karar verir ve tüm blokları okumak zorunda kalmaz. Bu şekilde backup zamanından ciddi anlamda kar edebiliriz.

Block tracking file tek bir dosyadır.
Default olarak DB_CREATE_FILE_DEST altında tutulur. İstenirse farklı bir lokasyonda saklanabilir.
RAC database için tracking file ortak storage üzerinde olmalıdır.

--baslatmak icin

SQL> alter database enable block tracking file;

--default lokasyonda bir tracking file açar

SQL> alter database enable block tracking using file '/disk/filename.f' reuse;

--belirttiğimiz lokasyonda tracking file açar. resuse parametresi mevcut dosyayı ezer.


--Block change tracking disable etmek için

SQL> alter database disable block change tracking;


Block change tracking disable edildiği zaman o ana kadar alınan incremental backuplar
geçersiz olur yeniden Level 0 backup alınması gerekir.

Tracking file başka bir lokasyona taşınabilir. Bunun için

1- database kapatılır

SQL> Shutdown immediate;

2- dosya fiziksel olarak yeni lokasyonuna taşınır.

cp old_file new_file

3- database mount modda açılır, dosya rename edilir ve database açılır

SQL> startup mount;
SQL> ALTER DATABASE RENAME FILE 'ora_home/dbs/change_trk.f' TO '/new_disk/change_trk.f';
SQL> alter database open;

Database açıkken de tracking disable edilip yeni lokasyonda tracking açılabilir. fakat
bu durumda önceki backuplar geçersiz olur.

teşekkürler.

3 Şubat 2009 Salı

String Aggregation Techniques

"Sütun olarak kaydedilmiş değerleri nasıl tek satır olarak yan yana ekleriz"in anlatıldığı güzel bir makale.

String Aggregation Techniques (oracle-base.com)

asktom.oracle.com


Bu da benim hazırladığım küçük bir örnek

Tablolar:

CREATE TABLE PERSONEL
(
ID NUMBER,
AD VARCHAR2(20),
MESLEK NUMBER
)
;

Insert into PERSONEL (ID, AD, MESLEK) Values (1, 'ramazan', NULL);
Insert into PERSONEL (ID, AD, MESLEK) Values (2, 'ahmet', NULL);
COMMIT;


CREATE TABLE GRUP
(
ID NUMBER,
AD VARCHAR2(20)
);

Insert into GRUP (ID, AD) Values (1, 'istanbul');
Insert into GRUP (ID, AD) Values (2, 'ankara');
Insert into GRUP (ID, AD) Values (3, 'trabzon');
COMMIT;


CREATE TABLE GRUPUYE
(
GK NUMBER,
PK NUMBER
);

Insert into GRUPUYE (GK, PK) Values (1, 1);
Insert into GRUPUYE (GK, PK) Values (2, 1);
Insert into GRUPUYE (GK, PK) Values (3, 1);
Insert into GRUPUYE (GK, PK) Values (1, 2);
COMMIT;


SQL>
1 SELECT pk,
2 LTRIM(MAX(SYS_CONNECT_BY_PATH(ad,','))
3 KEEP (DENSE_RANK LAST ORDER BY curr),',') AS gruplar
4 FROM (SELECT g.pk,
5 g.ad,
6 ROW_NUMBER() OVER (PARTITION BY g.pk ORDER BY ad) AS curr,
7 ROW_NUMBER() OVER (PARTITION BY g.pk ORDER BY ad) -1 AS prev
8 FROM (select pk, ad from grupuye, grup
9 where gk=id) g)
10 GROUP BY pk
11 CONNECT BY prev = PRIOR curr AND pk = PRIOR pk
12* START WITH curr = 1

PK GRUPLAR
---------- --------------------------------------------------
1 ankara,istanbul,trabzon
2 istanbul