Oracle Fusion Middleware 11g Online Launch

Wednesday, 01.07.2009 – djoka_l

Zabeležite u svoje kalendare 9. juli 8:30 (GMT+1). Tokom uvodnog izlaganja, Charles Phillips i Thomas Kurian će Vas upoznati sa Fusion Middleware 11g, nakon čega će biti održana Q&A sesija.
Za učešće na ovom događaju već se prijavilo preko 2300 ljudi, i to će biti najveći launch događaj u Oracle-u do sada. Svi zainteresovani će konferenciju moći da prate direktno sa svog računara, bez potrebe da bilo gde putuju.
Više informacija o dogadjaju, kao i formular za registraciju možete pronaći ovde


Praćenje sesija koristeći trigger kod prijave

Friday, 26.06.2009 – msutic

Ovdje u firmi imamo Web aplikaciju koja se često spaja na bazu, izvrši nekoliko naredbi i odspaja nakon nekoliko sekundi. Vrlo je teško uhvatiti te sessije kako bi doznali što Web aplikacija točno radi na bazi. Kako bi si pomogao u tome kreirao sam trigger koji se okida kod prijave sessije i pokreće praćenje. Informacije o “trace” datoteci zapisuje u info tablicu.

Dakle, prvo ću kreirati tablicu:

SQL> CREATE TABLE logon_audit_info
(
logon_time DATE         ,
username   VARCHAR2(100),
tracefile  VARCHAR2(100)
);

Potom ću kreirati trigger koji će hvatati sesije pokrenute od strane korisnika “MSUTIC”. Naravno vi ćete umjesto “MSUTIC” koristiti naziv korisnika kojeg vaša Web aplikacija koristi za spajanje na bazu. “MSUTIC” je ovdje korišten samo u testne svrhe.

CREATE OR REPLACE TRIGGER audit_login_trigger
AFTER LOGON ON DATABASE
DECLARE
l_user        dba_users.username%TYPE   := USER;
l_sql         VARCHAR2 (500);
l_tracefile   VARCHAR2 (100);
l_time        DATE;
BEGIN
l_sql :=
'alter session set events '
|| CHR (39)
|| '10046 trace name context forever, level 12'
|| CHR (39);
l_time := SYSDATE;

IF (l_user = 'MSUTIC')
THEN
EXECUTE IMMEDIATE l_sql;

SELECT    pa.VALUE
|| '/'
|| LOWER (SYS_CONTEXT ('userenv', 'instance_name'))
|| '_ora_'
|| p.spid
|| '.trc'
INTO l_tracefile
FROM v$session s, v$process p, v$parameter pa
WHERE pa.NAME = 'user_dump_dest'
AND s.paddr = p.addr
AND s.audsid = SYS_CONTEXT ('USERENV', 'SESSIONID');

INSERT INTO logon_audit_info
(logon_time, username, tracefile
)
VALUES (l_time, l_user, l_tracefile
);

COMMIT;
END IF;
END;
/

I sad mali test.

$ sqlplus /nolog

SQL*Plus: Release 11.1.0.7.0 - Production on Fri Jun 26 14:22:47 2009

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

SQL> connect msutic@test11
Enter password: ******
Connected.
SQL> select count(*) from test;

COUNT(*)
----------
1

SQL> exit

Izvršio sam “select count(*) from test” i odmah se odjavio.

SQL> set lines 200
SQL> col logon_time for a20
SQL> col username for a15
SQL> col tracefile for a150
SQL> select * from logon_audit_info;

SQL> select to_char(logon_time,'dd.mm.yyyy hh24:mi:ss'),username,tracefile from logon_audit_info;

TO_CHAR(LOGON_TIME, USERNAME        TRACEFILE
------------------- --------------- ------------------------------------------------------------
26.06.2009 14:25:59 MSUTIC          /oracle/diag/rdbms/test11/test11/trace/test11_ora_31218.trc

Kao što vidite lokacija “trace” datoteke mi se zapisala u tablicu.
Pa da provjerimo jeli to ispravna “trace” datoteka.

$vi /oracle/diag/rdbms/test11/test11/trace/test11_ora_31218.trc
...
...
*** 2009-06-26 14:26:07.877
WAIT #0: nam='SQL*Net message from client' ela= 8173860 driver id=1952673792 #bytes=1 p3=0 obj#=-1 tim=1246019167877543
=====================
PARSING IN CURSOR #2 len=25 dep=0 uid=84 oct=3 lid=84 tim=1246019167868491 hv=297253644 ad='3ac91a38' sqlid='7b2twsn8vgfsc'
select count(*) from test
END OF STMT
PARSE #2:c=0,e=0,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,plh=1950795681,tim=1246019167868491
EXEC #2:c=0,e=0,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,plh=1950795681,tim=1246019167868491
WAIT #2: nam='SQL*Net message to client' ela= 2 driver id=1952673792 #bytes=1 p3=0 obj#=-1 tim=1246019167878005
FETCH #2:c=0,e=0,p=0,cr=7,cu=0,mis=0,r=1,dep=0,og=1,plh=1950795681,tim=1246019167868491
STAT #2 id=1 cnt=1 pid=0 pos=1 obj=0 op='SORT AGGREGATE (cr=7 pr=0 pw=0 time=0 us)'
STAT #2 id=2 cnt=1 pid=1 pos=1 obj=76970 op='TABLE ACCESS FULL TEST (cr=7 pr=0 pw=0 time=0 us cost=3 size=0 card=1)'
WAIT #2: nam='SQL*Net message from client' ela= 265 driver id=1952673792 #bytes=1 p3=0 obj#=-1 tim=1246019167878544
FETCH #2:c=0,e=0,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=0,plh=1950795681,tim=1246019167868491
WAIT #2: nam='SQL*Net message to client' ela= 2 driver id=1952673792 #bytes=1 p3=0 obj#=-1 tim=1246019167878647
...
...

Znači imam ispravnu “trace” datoteku i mogu napraviti detaljnu analizu.
Nakon što vam trigger više neće biti potreban ne morate ga brisati, već ga se može samo deaktivirati pa kad idući put bude potrebno neke sesije pratiti samo ćete ga ponovo aktivirati.

alter trigger audit_logon_trigger disable;

Automatsko brisanje starih “trace” datoteka

Friday, 26.06.2009 – msutic

Vrlo često se zna dogoditi da primijetite mnogo “trace” datoteka u “user” i “background dump” direktorijima. Na primjer Oracle 11.1.0.6 kreira “trace” datoteku skoro za svaku sesiju, te se nakon nekog vremena direktorij u kojem su pohranjene “trace” datoteke napuni sa mnoštvom *.trc i *.trm datoteka. Kako Oracle 11.1.0.6 baca sve sistemske i korisničke “trace” datoteke u isti direktorij to otežava potražnju za osobnim 10046 ili 10053 “trace” datotekama.

Najvjerojatnije se generiranjeg tog mnoštva datoteka može reducirati omogućavanjem/onemogućavanjem određenih parametara, te planiram detaljnije proučiti dokumentaciju vezano za taj problem. Do tad će mi poslužiti mala skripta koju sam napisao u svrhu brisanja starih “trace” datoteka. Skriptu možete koristiti za verzije Oracle baza od 8i+.

Za brisanje *.trc i *.trm datoteka sam koristio XARGS unix naredbu kako bi izbjegao grešku “Argument list too long” koja se javlja u slučajevima kad imam puno datoteka za izbrisat.

$ ls -l|wc -l
14029
$ rm *.trc *.trm
-bash: /bin/rm: Argument list too long

Skripta:

#!/bin/sh

#################################################################
## BRISANJE TRACE DATOTEKA STARIJIH OD 7 DANA ###################
#################################################################

# Postavite Oracle okruženje
export ORACLE_BASE=/oracle
export ORACLE_SID=test11
export ORACLE_HOME=$ORACLE_BASE/product/11.1.0
export PATH=$ORACLE_HOME/bin:$PATH:$ORACLE_HOME/OPatch:/sbin:/usr/local/bin

# Izvucite user i background dump lokacije
sqlplus /nolog<< EOF > /tmp/xy.temp
  connect system/oracle@test11  # OVDJE IZMJENITE LOGIN PARAMETRE
  column xxxx format a10
  column value format a80
  set lines 132
  SELECT 'xxxx' ,value FROM  v\$parameter WHERE  name = 'background_dump_dest'
  /
  SELECT 'yyyy' ,value FROM  v\$parameter WHERE  name = 'user_dump_dest'
  /
  exit
EOF

ERR=`less "/tmp/xy.temp"|egrep -c "ORA-|ERROR|no listener"`;
if [ $ERR != 0 ]
  then
   exit 1;
fi;

less /tmp/xy.temp | awk '$1 ~ /xxxx/ {print $2}' > /tmp/bkg_dump_dest.temp
read BCKDMP_DIR < /tmp/bkg_dump_dest.temp

less /tmp/xy.temp | awk '$1 ~ /xxxx/ {print $2}' > /tmp/usr_dump_dest.temp
read USRDMP_DIR < /tmp/usr_dump_dest.temp

# Brisanje svih trace datoteka starijih od 7 dana
find $BCKDMP_DIR  \( -name \*.trc -o -name \*.trm \) -type f -mtime +7 -print|xargs rm -f
find $USRDMP_DIR  \( -name \*.trc -o -name \*.trm \) -type f -mtime +7 -print|xargs rm -f

# Ciscenje privremenih datoteka
rm -f /tmp/bkg_dump_dest.temp
rm -f /tmp/usr_dump_dest.temp
rm -f /tmp/xy.temp

Kako bi omogućili automatsko izvršavanje skripte svakoga dana potrebno je dodati “cron” zapis:

0 8 * * * /home/oracle/scripts/clean_old_trcs.sh

(Moja se skripta izvršava svakoga dana u 8:00)

Da bi vam skripta funkcionirala potrebno je prilagoditi Oracle okruženje i login parametre prema vlastitim potrebama.


ORA-01476 -> CASE + Analytic function + TO_NUMBER = novi bug

Thursday, 25.06.2009 – Dejan

Kao što sam već nedavno pisao, prilikom programiranja jedne procedure, dobijao sam konstantno exception sa greškom “ORA-01476: divisor is equal to zero“, iako NE BI TREBALA da se pojavi u tom slučaju. Ponoviću opet onaj test case iz prethodnog posta:

Konkretnije rečeno, greška se javlja pri ugniježđenom korištenju analitičkih funkcija (npr. SUM() OVER() i td.) i funkcije TO_NUMBER(string) kada string sadrži nulu (‘0’) i to u slučaju kada se radi operacija dijeljenja:

create table ora01476(
 num_id      number,
 string_col  varchar2(64)
 );
 
insert into ora01476
select numval, stringval
  from (select column_value as stringval 
          from table (sys.ODCIVarchar2List('0','1','2','3'))
       ) strings,
      (select column_value as numval
        from table(sys.odcinumberlist(0, 1,2,3,4))
      ) numbers;
      
commit;

Nakon ovog upita:

     
select CASE 
         WHEN num_id = 0 OR string_col='0'
         THEN 0
         ELSE sum(num_id / TO_NUMBER(string_col)) over(partition by num_id)
       END as result
  from ora01476;

javlja se greška:

ORA-01476: divisor is equal to zero

Pošto sam sumnjao da se radi o bugu, otvorio sam novi Service Request na MetaLinku. Stručnjaci iz Oraclea su utvrdili da je u pitanju novi bug i dodijelili su mu broj 8630202 . Trenutno se vrši bug screening, pa ću prenijeti novosti, kada ih bude bilo …


Recenzija knjige: Troubleshooting Oracle Performance

Wednesday, 24.06.2009 – Dejan

Čuo sam već od nekoliko osoba, da je knjiga “Troubleshooting Oracle Performance” od Christiana Antogninija odlična, pa sam se i sam odlučio uvjeriti u to.

 

Knjiga je zahtjevna i nije namijenjena početnicima, nego naprednijim Oracle stručnjacima, koji žele još više proširiti svoje znanje. U mnogim slučajevima autor opisuje materiju, podrazumijevajući da čitalac vlada dotičnom tematikom i stručnim pojmovima, tako da se ne troši prostor na osnovne stvari, nego se fokus stavlja baš na komplikovane i skrivene (tj. malo poznate) mogućnosti Oracle baze.

Christian već na početku postavlja pitanje – kada treba trošiti vrijeme na poboljšanje performansi? Odgovor je jednostavan – prvenstveno onda kada se korisnici počnu žaliti ili kada se povrijedi neka tačka ugovora (Service Level Agreement). Pri objašnjavanju načina nadgledanja performansi kompletnog sistema, upozorava da mnogi administratori boluju od tzv.  “compulsive tuning disorder“, tj. od pretjeranog provjeravanja statističkih podataka vezanih za performanse baze i pokušavanja konstantnog poboljšanja rada baze, pri čemu se “gubi” mnogo vremena, a to vrijeme je skupo. Nekad je svejedno da li neki SQL upit vraća rezultat za 5 sekundi ili za 50, a pri čemu gazdi nije svejedno da mu DBA potroši dan-dva na optimizaciju tog upita. Dakle, bitan je “feedback” i od korisnika, i od naručioca aplikacije, kako biste mogli ustanoviti kada trebate trošiti vrijeme na poboljšanje performansi.

Nakon uvodnog opisa pristupu problemima i kada ih pravovremeno uočiti, počinju poglavlja sa pretežno tehničkom pozadinom.

U drugom poglavlju možete saznati npr. šta su selektivnost i kardinalnost (moram priznati da su ova dva pojma bolje i detaljnije opisana u knjizi “Cost Based Optimizer” od Jonathana Lewisa). Potom slijedi odličan opis životnog ciklusa jednog cursora, popraćen detaljnim objašnjenjem  parsovanja nekog SQL upita, te prednostima i manama korištenja bind varijabli. Na kraju ovog poglavlja su navedeni tipovi I/O operacija u bazi (logical reads, physical reads, physical writes, direct reads i direct writes).

Treće poglavlje sadrži informacije o ispravnoj identifikaciji problema. Kada vam korisnik kaže:”Jooooj, jest’ ovo generisanje izvještaja traje dugo… daj pogledaj, možeš li imalo ubrzati…“, morate se odlučiti gdje i kako početi sa traženjem uzroka tog usporenja. Pronalaženje pravog uzroka ovog problema može nekad biti dugotrajan i zahtjevan proces, a autor u ovom poglavlju daje savjete, koje metode i alate koristiti u tu svrhu. Tako možete pročitati o instrumentalizaciji i profilisanju neke aplikacije, tj. o dvije metode skupljanja informacija potrebnih za pronalaženje problematične komponente dotične aplikacije. Zatim možete saznati čemu služi “tracing” i kako protumačiti rezultat dobijenih podataka u trace datotekama. Za analizu tih podataka autor je čak napravio vlastiti alat pod nazivom TVD$XTAT, a usput je opisao i korištenje TKProf alata, kao i Profilera (DBMS_PROFILER).

U narednim poglavljima (4. i 5. poglavlje), autor objašnjava kako funkcioniše “query optimizer“, te naglašava veliki značaj redovnog prikupljanja i održavanja sistemskih i objektnih statistika, koje bitno utiču na rad “cost based optimizera“. Možete saznati, koji sistemski parametri se mogu konfigurisati, da bi performanse odgovarale vašim potrebama, npr. podešavanje parametra db_file_multiblock_count – tako u OLTP sistemu ovaj parametar treba biti što manji, dok u Datawarehouse sistemu ovaj parametar treba biti što veći.

Iz 6. poglavlja pod nazivom “Execution plans” sam lično naučio dosta novih stvari od kojih bih izdvojio objašnjenje operacija NESTED LOOPS i CONNECT BY WITH FILTERING, a vama će vjerovatno biti interesantan opis korištenja komande EXPLAIN PLAN i paketa DBMS_XPLAN, koji je popraćen odličnim tumačenjem pravilne interpretacije “execution plana”. Za sve “tjunere” je ovo jako bitno poglavlje, tako da ga pažljivo čitajte.

Na red dolazi poglavlje o tehnikama SQL “tjuniranja”, odnosno poboljšanja performansi nekog SQL upita. Navedene tehnike obuhvataju hintove, podešavanje okruženja u kojem se SQL izvršava, zatim SQL profile, “Stored outlines“, te korištenje SQL Tuning Advisora. Ja lično rijetko kad koristim hintove, a stored outline sam koristio za jednu third-party aplikaciju, čiji source code nisam mogao mijenjati. SQL Tuning Advisor koristim tu i tamo u Grid Controlu, kada poželim vidjeti prijedloge, koje taj “savjetnik” generiše.

Da biste mogli uspješno optimizovati neki SQL upit, morate znati kako neke stvari “interno” funkcionišu. Osmo poglavlje govori o parsovanju SQL upita. Parsovanje SQL upita se može najjednostavnije nazvati internom analizom SQL upita, sa ciljem pronalaska najboljeg execution plana za taj upit, pri čemu se pored ostalog provjeravaju prava pristupa ciljanim objektima, kao i postojanje odgovarajućih sistemskih i objektnih statistika. Prekomjerno parsovanje upita se može spriječiti ispravnim podešavanjem parametara open_cursors i session_cached_cursors (kod mene u bazi sam ovu vrijednost podesio na 200). Takođe bitan uticaj ima i parametar cursor_sharing .

Deveto poglavlje “Optimizing Data Access” govori o odabiru pravilnog “pristupa” podacima. Uspoređeni su Full table scan i korištenje particija u tabeli, sa napomenama šta je kad i kako bolje koristiti. Potom dolazi poređenje B-Tree i Bitmap indeksa, takođe sa primjerima i savjetima, npr. koji indeks se u kojoj situaciji treba koristiti. Jako zanimljivo poglavlje, sa odličnim primjerima particionisanja i korištenja indeksa. Jedina zamjerka u ovom poglavlju je nedovoljno detaljno opisano funkcionisanje “hash clustera“, pošto autor na više mjesta u knjizi spominje kako je “hash cluster” jako performantan u odnosu na neke druge opcije.  Sve u svemu, ako radite sa velikim tabelama, onda ovo poglavlje nudi pregršt korisnih informacija.

Optimizing Joins“, odnosno optimizacija priduživanja tabela u SQL upitima, prilično detaljno je obuhvaćena u 10. poglavlju. Pored osnovnih vrsta join-a (self-join, equi-join, cross-join, outer join), tu su još opisani “nested loop join“, “merge join“, “hash join“, “partition-wise join” i td. Možete saznati kako pojedine join metode interno funkcionišu i kako možete da utičete na odabir prave join metode. Datawarehouse specijaliste će sigurno zanimati optimizacija “star transformation” upita.

Predzadnje poglavlje pod nazivom “Beyond Data Access and Join Optimization” govori o korištenju slijedećih “tehnika”: “materialized views“, keširanje rezultata SQL upita (“result caching“), paralelno izvršavanje upita, “direct-path insert“, “row prefetching” i “array interface“. Pročitajte šta autor kaže o dotičnim tehnikama u tom poglavlju, a ja ću prokomentarisati svaku od njih na osnovu ličnog iskustva:

materialized views: koristim ih u velikom broju i zaista doprinose bržem izvršavanju pojedinih SQL upita. Ako vam je parametar query_rewrite_enabled podešen na TRUE, onda možete još više da uočite korisnost, koju oni nude. Dodatak pod nazivom “materialized view log” je šlag na tortu. Međutim, nisu uvijek idealni, npr. ako imate ogromnu tabelu u koju često unosite velike količine podataka (10-20 GB dnevno) i ako želite za tu tabelu kreirati jedan materialized view plus materialized view log, onda ćete se iznenaditi suprotnim učinkom. U tom slučaju unos podataka traje prilično duže, a znalo se desiti da čitav proces jednostavno pukne. Ja sam tu pojavu prijavio Oracle Supportu i rekli su da je bug, zbog čega sam čak neko vrijeme morao deaktivirati parametar query_rewrite_enabled sve dok nije izašao odgovarajući patch za taj bug.

result caching: pošto ova opcija postoji tek od verzije 11g, nemam s njom nikakvog iskustva, ali čitajući u dokumentaciji i po komentarima drugih, izgleda da keširanje rezultata u određenim slučajevima znatno poboljšava performanse nekog SQL upita

paralelno izvršavanje upita: eee, koje sam muke imao sa ovim čudom… Nekad su pojedini upiti stvarno bili tako brzi, da se čovjek oduševi, ali previše puta su se znali zablokirati sa wait eventima “PX Deq Credit: send blkd” i “px – waiting on query coordinator” (ili tako nekako, ne znam sad napamet), da sam morao praktično odustati od te metode poboljšavanja performansi. Pisao sam o tome u par navrata(“ORA-00600: internal error code, arguments: [pxTmpAlo_pkey]” i “Oracle: paralelno izvrsavanje upita (Parallel Query Execution) “).

direct-path insert: uuuuu brale, kako unos podataka ovom metodom LETI!!! Jako korisna metoda za unos velikih količina podataka, pogotovo uz NOLOGGING opciju.Ali avaj… sve ima svoje vrline i mane. Problem je što se na ovaj način zauzima samo novi prostor iznad high watermarka, pa se eventualno slobodni prostor ispod high watermarka ignoriše. Ako brišete puno podataka iz te tabele u koju ih unosite “direct-path insert” metodom, onda ćete biti suočeni sa konstantnim povećanjem prostora, koju ta tabela zauzima. Može da se dogodi kontraefekat pri selektovanju podataka iz te tabele, jer se moraju “pročitati” i prazni blokovi iz kojih su podaci obrisani, a nisu naknadno popunjeni zbog “direct-path insert” metode. Osim toga, ako koristite NOLOGGING opciju, onda neće biti generisani Redo podaci, pa se u slučaju havarije može desiti da izgubite te podatke. Znači oprezno sa ovom metodom!!!! Koristite ju npr. za “batch” prebacivanje ogromne količine podataka iz eksterne tabele u neku permanentnu tabelu u bazi.

row prefetching: ukoliko SQL upit vraća više redova odjednom, onda će vam opcija biti od pomoći. Ja lično obožavam BULK COLLECT i koristim ju u svakoj situaciji, kada moram u nekoj uskladištenoj proceduri obraditi stotine, hiljade ili čak milione redova. Ograničenje broja selektovanih redova pomoću opcije LIMIT daje vam mogućnost da ispravno koristite fizičke resurse (CPU, I/O operacije i network bandwidth). Extra stvar!!

array interface: ova opcija je takođe korisna u situacijama kada klijent šalje veliku količinu podataka bazi i obrnuto. Ako imate neki batch job, koji preko sqlplus-a izvršava neku proceduru, podesite arraysize u sqlplusu na veću vrijednost (set arraysize 100), pa usporedite vrijeme izvršavanja prije i nakon toga. Kod mene svaki batch job ima podešen arraysize na minimalno 100, a neki čak i na 500. Osim toga, u PL/SQL procedurama, pored BULK COLLECT obavezno isprobajte FORALL komandu. Piči kao zmaj, zar ne?

Zadnje poglavlje, 12. po redu, pod nazivom “Optimizing the Physical Design“, objašnjava o pravilnom odabiru tipa podataka i rasporedu kolona u tabeli, zatim o nus-pojavama “row migration” i “row chaining“, te o “block contention” konfliktu kada više transakcija pristupa istom bloku. Veoma korisno poglavlje, kako za administratore, tako i za programere.

 

I tako poglavlje po poglavlje dođe kraj knjige. Šta da vam kažem – iako lično imam dosta iskustva sa Oracle bazom, našao sam prilično dosta korisnih i novih informacija. Ne kaže se džabe – čovjek uči dok je živ. Knjiga je zanimljiva i sadrži dosta detalja, dijagrama i ostalih grafičkih prikaza, koje upotpunjuju tekstualna objašnjenja i primjere. Moja srdačna preporuka!

Ocjena: 10/10


SQL Developer, nebrušeni dijamant

Friday, 19.06.2009 – Darko

Nedavno  mi pade na pamet jedan duži tekst koji sam posvetio recenziji IDE-ova za rad sa Oracle-om, pisanju koda u PL/SQL-u, upita u SQL-u i slično, a koji nikada nisam objavio.
Dakle, o alatima koji su u ponudi na tržištu, i moje impresije o istima.
Konkretno – radi se o “PLSQL Developer”-u , “Toad”-u , “SQL Developer”-u i “SQL Manager 2007 Lite for Oracle”.
Ja u principu nisam baš totalno zadovoljan alatima ove vrste za rad sa Oracle-om i ovo je upravo jedna kategorija IDE-a koje sam vrlo često mjenjao tokom rada sa pomenutom bazom ne bih li našao nešto što mi u potpunosti odgovara.

Ovdje ću prenijeti samo dio teksta, i to onaj koji je posvećen Oracle-ovom SQLDeveloper-u.

Dakle, ovako sam tada opisao ovaj alat:

SQL Developer


sqldeveloper

Ako pričamo o konkurenciji Toad-u, onda moramo na prvo mjesto staviti program koji nam dolazi pravo iz Oracle-a a koji je ranije bio poznat pod nazivom Raptor: SQL Developer.
Zaista svjetlo na kraju tunela, i pravo osvježenje!

sqldeveloper-izgled

Ovo je nešto što, po meni, najviše liči na jedan pravi alat za rad sa bazom podataka i razvoj aplikacija, kada je u pitanju Oracle.
To što je pisan u Javi je u jednoj mjeri dobra stvar, a u najvećoj mjeri jako loša.
Upravo je moja najveća zamjerka kod ovog programa uperena ka njegovoj brzini. Ustvari ne ka brzini izvršavanja naredbi toliko – koliko na brzinu renderovanja njegovog izgleda i brzinu jave u domenu GUI-ja inače.
Znamo da Java baš i nije svjetski prvak u brzini kreiranja GUI objekata. E , tu ova mana dolazi do izražaja.
Mislim da su momci iz Oracle-a mogli ovaj aspekt malo bolje uraditi. Pravi primjer brzog IDE-a pisanog u Javi kod kojeg nikada nemamo ovaj problem je npr. NetBeans ili Eclipse.
Često mi se desi da nakon dugog rada u nekom drugom programu, kliknem da se vratim na SQL Developer, a onda moram da sačekam ko zna koliko ( dragocjenog ) vremena da mi se prikaže program sa svim elementima i trenutnim stanjem.
Inače, ovo je možda jedina ozbiljnija zamjerka na ovaj program.
Program ima veoma dobar code completion , ima podršku za CVS i subversion, stablo je veoma lijepo urađeno, pregledno je i brzo.

Ima skoro sve elemente koje editor jednog savremenog IDE-a treba da ima.

Pristup tabelama je veoma jednostavan i brz:
Jednim klikom na neku tabelu nam se odmah otvara novi prozor sa svim informacijama po tabovima za odabranu tabelu.
Tabela za prikaz podataka bi mogla biti puno ljepša , a njene ćelije malo većih dimenzija.

Još jedna dobra stvar kod ovog programa je ta da ne moramo imati instaliran nikakav Oracle client kod sebe, jer za konekciju ne koristi tnsnames.ora već JDBC drajvere.

SQL Developer sada zaista zaslužuje da mu se da šansa.

Savjet:
Svim korisnicima savjetujem da prije početka obavezno urade sljedeće:

Tools -> Preferences -> Database -> Object viewer Parameters i štrikirajte “Automatically freeze object  viewer windows” jer će se u protivnom svaka tabela na koju kliknemo jednom otvarati uvijek u jednom istom prozoru. Sada će se svaka tabela otvarati u posebnom prozoru.

Da , to je nešto što bih ranije rekao za ovaj alat, nakon nekoliko nedjelja rada u njemu i to u NE kritičnim situacijama, kada se mogu tolerisati određene gluposti koje IDE može izazvati.
Tada mi je ovaj program zaista bio pravo osvježenje jer je izgledao oprilike onako kako sam ja zamišljao da bi jedan IDE za rad sa Oracle-om ( za developere, naravno ) i trebao izgledati.
Ono što bih SADA rekao za ovaj IDE je da ga se bar još neko vrijeme zaobilazi u širokom luku!
On je OK da se koristi “kući”  ili  za učenje, ali ako se odlučite za njega na nekom ozbiljnijem projektu – uvijek treba imati pored sebe i jedan od dokazanih alata.

Zašto sam promjenio mišljenje?

Pa kao prvo zato što sa ovim alatom nikada ne znaš na čemu si. Recimo da smo prepravili neku funkciju, paket, proceduru… Nakon kompajliranja istih uopšte nećemo znati da li je kompajliranje uspješno obavljeno, da li je novi objekat validan , u čemu je problem ako problem postoji ( ne prikaže se lijepo poruka kao u npr. Toad-u )…

Evo još jedan primjer: dešavaće vam se nekada da će program sam od sebe početi prikazivati neki view sa uduplanim kolonama, dok je u drugim alatima taj pogled sasvim OK. A onda ti ako nemaš na produkcionoj lokaciji još neki alat,  nećeš moći ništa dalje raditi oko pomenutog pogleda…

Ako ovaj program ( kojem inače ne treba instalacija ) iskopiramo na neki drugi računar i pokušamo ga pokrenuti – tu nastaju tek posebne situacije i blokiranja računara jer slijepo vjeruje podešavanjima koja su za njega setovana ( a koja su u ovom slučaju prenijeta sa prethodne lokacije )…
O fantomskom brisanju ili dodavanju znaka tačka-zarez ( ; ) na kraju kodova koje želimo iskompajlirati – i da ne pričam!

Sve u svemu – SQL Developer je zaista alat kojeg jedna tanka linija dijeli od odličnog alata i vjerovatno će to uskoro i postati, kada se isprave određene nebuloze koje postoje u njemu. Zaista je sjajno zamišljen.
Mislim da Oracle mora sebi priuštiti jedan ovakav, ali bug-free  ( i price-free 🙂 , naravno )  alat po svaku cijenu.

Volio bih čuti  kakva su vaša iskustva sa opisanim alatom,   tj. šta vi koristite u radu sa Oracle-om…?


MS SQL 2008: Novi tipovi podataka

Monday, 15.06.2009 – Zidar

 

 

Ovo je skraceni prevod originalnog teksta http://www.simple-talk.com/sql/learn-sql-server/sql-server-2008-the-new-data-types/ koji je napisao Brad McGhee.

MS SQL 2008 donosi nekoliko novih tipova podataka:

  • Date and Time: Cetiri nova pod-tipa, koji bi trebalo da olaksaju rad sa date/time podacima. To su: DATE, TIME, DATETIME2, DATETIMEOFFSET
  • Prostorni tip: Dva nova tipa podataka za modelovanje prostora (Geografski Informacioni Sistemi, GPS podaci i slicno) – GEOMETRY i GEOGRAPHY, koje mozemo upotrebiti da na ‘prirodan’ nacin cuvamo informacije koje opisuju lokaciju
  • Hijerarhijski tip, HIERARCHYID, omogucava modelovanje hijerarhisjkih struktura, kao sto su organizacione sheme firmi, lanci komandovanja, sastavnice materijala.
  • Filestream: nije tip podataka sam po sebi, nego unapredjena varijacija VARBINARY(MAX). Omogucuje da se podaci cuvaju na server, u file sistemu, umesto unutra MS SQL baze. Ovo zahteva dosta posla na strain administracije baze pa ce biti obradjeno manje nego ostali noviteti.

Date and Time

U ranijim verzijama MS SQL imali smo DATETIME i SMALLDATETIME tipove. Koriscenje DATETIME i SMALLDATETIME nije jednostavno i cesto smo imali probleme, kao sto su:

  • Datum i vreme su deo istog tipa, i nije bilo moguce cuvati datumski ili vremenski deo. Razbacivali smo proctor cuvajuci vremenski deo koada sun am trebali samo datumi. To i nije bilo najstrasnije, glavni problem su  nastajali kad smo zeleli da cuvamo recimo samo vreme, bez datuma. Neophodne sui  funkcije za konverziju datuma iz jednog u drugi format, kveriji su bili tezi nego sto je potrebno, zbog komplikovane sintakse. Cesto zbog konverzije nismo mogli da koristimo postojece idnekse, optimizer bi jednostavno zanemario index, sto je dovodilo do sporijeg izvrsavanja kverija.
  • DATETIME i SMALLDATETIME ne uzimaju u obzir vremenske zone, sto zahteva dodatno kodiranje u aplikacijama koje treba da rade globalno
  • Preciznost je samo 0.333 sekunde, sto je cesto nedovoljno za mnogeprimene.
  • Opseg datuma koji pokrivaju DATETIME tipovi cesto nije zadovoljavajuci.

Da bi se ovi problem prevazisli, MS SQL 2008 uvodi nove tipove podataka:

·         DATE: kao sto naslucujete, DATE cuva podatke u obliku YYYY-MM-DD. Opseg vazenja tipa DATE je  0001-01-01 do 9999-12-31, sto bi trebalo d abude dovoljno za vecinu poslovnih i tehnickih aplikacija. Preciznost je  1 dan, i jedan DATE podatak zahteva 3 bajta prostora na disku.

·         TIME se cuva kao hh:mm:ss.nnnnnnn, opseg je od 00:00:00.0000000 do 23:59:59:9999999, tacnost ide do 100 nanoseconds. Zavisno od zahtevane tacnosti, potrebno je 3 do 5 bajta za cuvanje TIME podataka.

·         DATETIME2 je slican DATETIME< ali jepovecan opseg i preciznost. Format je YYYY-MM-DD hh:mm:ss:nnnnnnnm u opsegu od 0001-01-01 00:00:00.0000000 do 9999-12-31 23:59:59.9999999, uz preciznost do 100 nanoseconds. Zavisno od preciznosti, potrebno je 6 do 8 bajta za cuvanje DATETIME2 podataka

·         DATETIMEOFFSET jer slicasn DATETIME2 ali ukljucuje i dodatnu informaciju za pracenje vremenskih zona. Format je YYYY-MM-DD hh:mm:ss[.nnnnnnn] [+|-]hh:mm u opsegu od 0001-01-01 00:00:00.0000000 do 9999-12-31 23:59:59.9999999 (sa koriscenjem UTC), preciznosdo 100 nanoseconds. Zavisno od preciznosti, potrebno je 8 do 10 bajta za cuvanje DATETIMEOFFSET podataka.

Sve postojece funkcije za rad sa datumima i vremenima su preradjene tako da rade sa novim tipovima podataka. Dodate sui  neke nove funkcije, io cemu cemo pisati nekom drugom prilikom.

Modelovanje Prostora – Spatial Data Type

Spatial data Type u sustini zanci cuvanje koordinata tacaka u bazi podataka. To smo mogli i ranije da radimo sa kalsicnim numerickim tipovima podataka. Primedba prevodioca: Cemu onda novi tip? Navodno, uz novi tip podataka olaksane su neke radnje koje sun am potrebne ako se bavimo GIS/GPS sistemima. Vreme ce pokazati da li je ovo stvarni napredak ili nam Microsoft prodaje toplu vodu kao novo epohalno otkrice.

GEOMETRY tip se korsiti za cuvanje XY koordinata u planarnom, dakle dvodimenzionom koordinatnom sistemu

GEOGRAPHY se koristi za cuvanje podataka o tackama na Zemljinoj kugli.

GEOMETRY i GEOGRAPHY tipovi podataka se koriste u sprezi sa .NET CLR tipovima podataka, sto znaci da .NET i CLR funkcije mogu da primenjuu ugradjene funkcije i metode za ovakav tip podataka. Na primer, moze se pozvati metod koji izracunava daljinu izmedju dve zadate tacke. Drugi primer je metod koji kazuje da li se dve linije seku. Metode je definisao Open Geospatial Consortium standard uz koji s emogu koristiti Microsoftove ekstenxije (ako neko razume, neka nam objasni J) Kako sve to radi, izlazi iz planiranog opsega ovog napisa.

Jos jedna osobion spatial data tipova je da mogu da koriste prostorne indekse (spatial indexes). Prostorni indeksi su mrezne structure i omogucavaju ubrzano pretrazivanje prostora –tacaka na koordinatnoj mrezi.

Vecini DB administratora, a i ostalim,  je ovo sve novo i zahteva dosta matematickog znanja, inace se covek lako izgubi u svemu. Videcemo sta se nam ovo doneti.

Hijerehije

Iako su hijerarhijske structure veoma ceste u praksi, SQL uospte, MS QL posebno ne pruzaju mnogo u toj oblasti. Skrivene tabele, kursori, proceduralno procesiranje tabela u zdatom redosledu, sve to nam je trebalo da bismo se nekako iscupali u specificnoj situiaciji. Malo toga je bilo prenosivo na neku drugiu situaciju. SQL Server 2008 uvodi HIERARCHYID tip podataka da bi se neki od problema prevazisli. Predvidjeno je da HIERARCHYID cuva podatke o poziciji cvora u hijerarhijskom stablu. Sledeci odgovori mogu se dobiti i bez uvodjejnja parent-child kolona i slozenih kverija:

  • Organizacione structure
  • Skup zadataka koji cine veci projekat, kao Gantt dijagrami
  • File sistemi (direktorijumi i poddirektorijumi)
  • Recnici
  • Sastavnice i recapture, specifikacije materijala
  • Graficka reprezentacija linkova zimedju web starnica

FILESTREAM

SQL Server odlicno cuva lepo strukturirane podatke u normalizovanim bazama. Medjutim, sve vise se trazi cuvanje i manipulisanje nestrukturiranih podata (video fajlovi graficki fajlovi, Word i Excel dokumenti i slicno), gde MS QKL nije tako dobar. Pre verzije NS SQL 2008, ako ste zeleli da upotrebite MS SQL za manipulisanje takvim podacima,  imali ste dve opcije. Mogli ste da cuvate kompletne fajlove kao  VARBINARY(MAX) unutar same SQL baze, kao kolone VARBINARY(MAX) tipa; ii ste cuvali fajlove negde na fajs sitemu (server) a u bazi ste cuvali adrese tih fajlova, pokazivace na lokacije gde su fajlovi bili smesteni. Aplikacija bi onda procitala adresu iz abze in a toj adresi otvorila fajl (ukoliko ga neko u medjuvremenu nije sklonio ili preimenovao).

Nijedno od dva resenja nije savrseno. Cuvanje fajlova unutar  VARBINARY(MAX) kolona daje ne bas idealne performance, imamo  2 GB ogranicenje velicinevfajla , i sve skupa dramaticno mzioe povecati velicinu same baze podataka.

S druge strane, ako cuvamo fajlove naNTFS  serveru, kao minimum treba nam nacin imenovanja fajlova tako das u imena jedinstvena, treba nam pametan system za upravljanje folderima; bezbednost podataka je problem, jer su podaci van SQ, pa treba koristiti NTFS; treba nam poseban back-up; i uvek ce se neko vec naci sa dovoljno privilegija da obrise, pomeri ili preimenuje fajlove tako da ih SQL ne moze naci. Sve u svemu, mrka kapa.

Da bi se bar neki problem prevazisli, SQL Server 2008 uvodi nesto sto se zove  FILESTREAM storage, sto je u sutini hibridni pristup, sa namerok da se dobre strane oba resenja kombinuju.

FILESTREAM storage se ostvaruje tako sto  SQL Server 2008 cuva VARBINARY(MAX) objekte (BLOBs) izvan baze, u  NTFS fajl sistemu. Deluje slicno opisnom metodu, ali samo na prvi pogled. Umosto jednostavnih pokazivaca, SQL Server Database Engine je  integrisan sa NTFS fajl sistemom tako da se dobije optimalna kombinacija performansi i kompleksnosti administracije. Na primer, FILESTREAM korist Windows OS sistemski cache umestop SQL Server buffe. Ovo solbadja SQL manipulacije Windows fajlovima, tako da server manipulise samo strukturiranim podacima, dok Windows radio no sto Widows ume da uradi – upravlja velikim fajlovima.

FILESTREAM nudi i ova poboljsanja:

  • Transact-SQL se moze koristiti ( SELECT, INSERT, UPDATE, DELETE ) nad FILESTREAM podacima.
  • Po defaultu, FILESTREAM podaci idu u back-up zajedno sa bazom podataka, iako sede izvan baze. Ako hocete, mozete da razdvojite back-up za bazu i  FILESTREAM podatke.
  • Velicina fajlova i njihov broj ogranicen je samo is prostorom na NTFS, za razliku od standardnih 2 GB za  VARBINARY(MAX.

Ipak, ni FILESTREAM nije resenja za ma a bas svaku situaciju. Veruje se da je najbolje primeniti FILESTREAM kada:

  • Radimo sa  BLOB fajlovima  1MB ili vecim.
  • Treba nam veoma brz pristup z acitanje (read access).
  • Aplikacije imaju ugradjenu logiku u middle-tier.
  • Kada se ne zahteva kriptovanje podatka, posto FILESTREAM ne podrzava enkripciju.

Ako vasa primena ne zadovoljava navedene uslove, verovatno je pristup sa  VARBINARY(MAX) najbolja opcija. Posto je sve ovo novo i neisprobano, dajte sebi dosta vremena za testiranje probanje ove ili one opcije.

Clanak se dalje nastavlja uputama za adminsitratora kako da setuje FILESTREAM i taj deo ostavljam zaintersovanim da sami pogledaju.

 

J


ORA-04028: cannot generate diana for object

Wednesday, 10.06.2009 – Dejan

Zadnjih dana me baš krenulo sa čudnim Oracle greškama…

Prvo u ponedeljak dobijem jednu grešku, koju do sada u životu nisam vidio:

ORA-04028: cannot generate diana for object name

Potražio sam na MetaLinku neko objašnjenje ili rješenje, ali ne nađoh ništa korisno. Samo definiciju pojma diana (DIANA je skraćenica za ‘Descriptive Intermediate Attributed Notation for Ada‘) i obavijest, da je ova greška riješena još u verziji Oracle 8. Otkud onda odjednom ta greška kod nas u bazi sa verzijom 10g?

ORA-04028: cannot generate diana for object name
Cause: A lock conflict prevented the generation of diana for an object.
Action: Check the syntax. If no syntax errors are found, report this error to Oracle World Wide Support.

PL/SQL is based on the programming language Ada. As a result, PL/SQL uses a variant of Descriptive Intermediate Attributed Notation for Ada (DIANA), which is a tree-structured intermediate language. It is defined using a meta-notation called Interface Definition Language (IDL). DIANA provides for communication internal to compilers and other tools.

DIANA is an abstract syntax tree for PL/SQL: it’s the output from the “front end” of the PL/SQL compiler (the parser and semantic analyzer). The committees that created Ada also created Diana, and any conforming Ada compiler is supposed to generate Diana. PL/SQL Diana is a modified version of the Ada Diana because PL/SQL includes SQL functionality not present in Ada.
At compile time, PL/SQL source code is translated into machine-readable m-code. Both the DIANA and m-code for a procedure or package are stored in the database. At run time, they are loaded into the shared memory pool. The DIANA is used to compile dependent procedures; the m-code is simply executed.

Greška se pojavila prilikom rekreiranja nekoliko “materialized views” (dalje u tekstu kao MV) i potom rekompilacije nekoliko PL/SQL paketa, koji su koristili te MV. Nakon što su MV rekreirani, par PL/SQL paketa su postali invalidni i prilikom ponovne rekompilacije javljali su gorenavedenu grešku ORA-04028. Pokušavao sam potom sa rekompilacijom spornih MV (ALTER MATERIALIZED VIEW COMPILE), ali da stvar bude čudnija, svaki od tih MV neposredno nakon rekompilacije postaje invalidan… Wtf!?

Ni Google mi nije pomogao, pa sam se odlučio na radikalan korak – dropnuo sam dotične MV i ponovo ih jednog po jednog kreirao. Nakon toga sam rekompilirao invalidne pakete i sve je radilo kako treba. Pojma nemam zašto se ta greška pojavila, niti kako bih ovaj problem mogao drugačije riješiti… Ako se neko susretao sa ovom greškom i zna šta raditi u tom slučaju, neka napiše komentar i pomogne meni, a vjerujem i drugima. 🙂

 

Druga greška se javlja pri ugniježđenom korištenju analitičkih funkcija (npr. SUM() OVER() i td.) i funkcije TO_NUMBER(string) kada string sadrži nulu (‘0’) i to u slučaju kada se radi operacija dijeljenja:

create table ora01476(
 num_id      number,
 string_col  varchar2(64)
 );
 
insert into ora01476
select numval, stringval
  from (select column_value as stringval 
          from table (sys.ODCIVarchar2List('0','1','2','3'))
       ) strings,
      (select column_value as numval
        from table(sys.odcinumberlist(0, 1,2,3,4))
      ) numbers;
      
commit;

Nakon ovog upita:

     
select CASE 
         WHEN num_id = 0 OR string_col='0'
         THEN 0
         ELSE sum(num_id / TO_NUMBER(string_col)) over(partition by num_id)
       END as result
  from ora01476;

javlja se greška:

ORA-01476: divisor is equal to zero

Za ovu grešku sumnjam da je u pitanju bug, pa sam otvorio jedan Service Request na MetaLinku. Upravo sam napravio test case, da pokažem kako se greška može u svako doba reproducirati, pa da vidimo šta će stručnjaci iz Oraclea reći po ovom pitanju … Više o ovome nakon što se Service Request zatvori.


Code Review – revizija programskog kôda

Thursday, 04.06.2009 – Dejan

Bez obzira koji RDBMS ili programski jezik koristite, svjedoci ste izmjena u novijim verzijama dotičnih.

U većini slučajeva novije verzije sadrže ispravljene greške iz prethodnih verzija, zatim poboljšanja postojećih funkcionalnosti, kao i mnoge novotarije. Zbog svih tih izmjena, preporučljivo je raditi redovan pregled programskog kôda (code review) – ako ne jednom godišnje, onda barem nakon prelaska na noviju verziju RDBMS-a ili programskog jezika.

U mojoj bivšoj firmi se code review obavljao periodično svakih 6 mjeseci, što je po meni bilo nepotrebno, jer se gubilo dragocjeno vrijeme za razvoj novih aplikacija, a osim toga, u tom periodu se rijetko kad promjeni nešto bitno u kompletnom sistemu, da bi se morala raditi revizija svih aplikacija.

Po meni se revizija svih ili barem bitnih aplikacija mora obavljati prilikom svakog prelaska na novije verzije (major release change) ili jednom godišnje ukoliko dođe do većih promjena u sistemu.

Tako npr. verzija Oracle 11g sadrži mnoštvo ispravljenih grešaka iz prethodnih verzija, kao i mnogo novih funkcionalnosti u odnosu na starije verzije, a koje bi mogle doprinijeti poboljšanju rada određenih aplikacija baziranih na Oracle tehnologijama. Čak se i verzija Oracle 10g Release 2 prilično razlikuje od verzije 10g Release 1, a o poređenju sa verzijama 9i ili 8i da i ne govorim…

Isto tako i nove verzije MySQL-a, PHP-a i td. sadrže priličan broj izmjena, tako da se prelazak na novije verzije preporučuje u svakom slučaju, ali tek nakon što se obavi detaljno testiranje postojećih aplikacija.

Prije prelaska na novije verzije, obavezno pročitajte change log, da biste dobili uvid u značajne promjene u odnosu na prethodne verzije. Nakon toga podesite testnu konfiguraciju sa novijim verzijama odabranog RDBMS-a ili programskog jezika, pa prepravljeni programski kôd detaljno testirajte prije nego što ga postavite u proizvodno okruženje.

Mnogima je revizija programskog kôda dosadna i smarajuća, ali se to jednostavno MORA obaviti ukoliko želite imati uspješan sistem na duže staze.


Koji alat koristite za modelovanje baze podataka?

Thursday, 28.05.2009 – Dejan

Zanima me čisto informativno, a i statistički, koji alat koristite za modelovanje baze podataka.

Znači, šta koristite za ER dijagrame, za UML dijagrame i sl. Ako uhvatim vremena, namjeravam napisati usporedni test određenih alata za rad sa bazama podataka, pa ne bi bilo loše da dobijem neki input o aktivno korištenim alatima. 😀