Baze podataka – MySQL, Oracle, PostgreSQL, MS SQL Server, Access, modelovanje podataka …

Druženje u Beogradu?

Saturday, 26.01.2013 – Dejan

Nakon nekoliko seminara u Zagrebu, ovaj put idem na jedan kurs u Beograd: “Oracle Database 11g: Data Guard Administration Rel 2”, jer mi je potreban kao uslov za polaganje OCM (Oracle Certified Master) ispita.
Dakle, od 31.03.2013. do 04.04.2013. sam u Beogradu, pa ako je neko za druženje uz pivo/nespresso/ćevape/Sushi i ostale delikatese, nek se javi!


Full Table Scan vs. BITMAP Index vs. VIRTUAL Column

Friday, 02.11.2012 – Dejan

Ovaj put donosim još jedan primjer iz prakse, na osnovu kojeg ću pokazati interesantne metode optimizacije problematičnog SQL upita.

U stvarnoj bazi postoji jedna tabela, u koju se podaci unose i obrađuju po slijedećem principu:
– podaci se unose u nejednakim razmacima, pri čemu se jedna status kolona označi sa ‘N’, što znači da podaci nisu obrađeni; ukoliko dođe do neke greške prilikom unosa ili su podaci nepotpuni, onda status kolona dobija vrijednost NULL
– jedan SQL upit se izvršava svakih 5 sekundi i provjerava, da li postoje neobrađeni ili nepotpuni podaci
– ukoliko postoje neobrađeni podaci, onda bivaju obrađeni, nakon čega se vrijednost u status koloni mijenja iz ‘N’ u ‘Y’

E sad, ostavimo na stranu što je dizajn ove tabele, odnosno njena fizička struktura, u praksi veoma loša…

Zadatak je da optimiram onaj SQL, koji svakih 5 sekundi provjerava, da li postoje neobrađeni podaci. Možeš se žaliti da je struktura tabele loša i da ju treba izmijeniti – odgovor je uvijek isti:”Nemamo sad vremena za komplikovane izmjene, moramo do kraja mjeseca završiti druge bitnije stvari, a to ćemo naknadno…bla bla“…

Dakle, na posao… Trebalo mi je skoro 2 sata vremena, ali rezultat je bio itekako dojmljiv… Zanima vas kako?
Pročitaj kompletan tekst »


Interval partitioning: zašto i kako?

Saturday, 27.10.2012 – Dejan

Zašto?

Slagaću ako kažem, da nisam početkom skoro svake godine nailazio na grešku “ORA-14400: inserted partition key does not map to any partition“. Uvijek, ali uvijek! neko od programera zaboravi kreirati particiju za MAXVALUE ili particije i za narednu godinu, pa poslije Nove godine bude frka i panika, kad aplikacija ne radi, a telefon zvoni, dok preko E-Maila šalju screenshotove sa greškom… Na svu sreću, Oracle je tom problemu izašao u susret i omogućio opciju “Interval partitioning“, pomoću koje se nove particije automatski kreiraju.

Naravno kao i uvijek ću na praktičnom primjeru pokazati i objasniti, kako se interval partitioning podešava, kao i osnovne naredbe za rad sa particijama i subparticijama u tom slučaju.
Pročitaj kompletan tekst »


Preglednost kôda: IF var1,…,varN IS NOT NULL … vs. COALESCE(var1, var2,…, varN)

Wednesday, 24.10.2012 – Dejan

Po ko zna koji put vidjam u PL/SQL procedurama aljkav kôd i ne mogu se nacuditi raznim improvizacijama i perverzijama, koje pojedini programeri pisu…

Jedna od zadnjih se protezala na 90 linija kôda i izgledala je ovako:

IF var1 IS NOT NULL THEN varResult := var1;
ELSIF var2 IS NOT NULL THEN varResult := var2;
...
ELSIF varN IS NOT NULL THEN varResult := varN;
END IF;

Mislim, cemu to!? Shvatio sam da je cilj provjeriti varijable jednu po jednu, i cim se dodje do prve varijable, koja ima neku vrijednost, dodijeliti ju rezultatskoj varijabli. Zar nije ovako preglednije?

varResult := COALESCE(var1, var2, ..., varN);

FLASHBACK DATABASE glavu čuva!

Tuesday, 23.10.2012 – Dejan

Zašto Flashback?

Sigurno ste se već našli u situaciji da imate veoma kratak “maintenance window” u sklopu kojeg se vrše neke izmjene nad bazom, npr. instaliranje novog patcha, novi release ogromne aplikacije ili neka slična operacija, koja bi mogla biti kritična, što znači, da bi u slučaju neke greške ili neželjenog rezultata morali vratiti bazu u prvobitno stanje, dakle prije te izmjene.

U mnogim slučajevima se previdi taj “fallback” scenario, pa Oracle DBA radi restore kompletne baze… A to traje, pogotovo ukoliko je baza velika… Taman ste pomislili:”Još ova sitnica, 5-10 minuta i gotovo!“, kad ono cvrc! Greška. Panika. Psovanje. Restore baze. Pa se onda češkate po glavi i nestrpljivo čekate kad će restore biti okončan…

Taaa-daaam!

Od sad, pa nadalje i ubuduće za većinu tih “maintenance taskova” (plaćam pivo i ćevape za iole smislen prevod ovih riječi!) možete koristiti Flashback tehnologiju! Ukratko, Flashback omogućava “povratak u prošlost” do nekog zadanog trenutka.

Dakle, prije nego što započnete sa izmjenama na bazi, aktivirate Flashback i postavite tačku (“RESTORE POINT“) do koje želite vratiti bazu ukoliko dođe do nekih problema.

Kako Flashback?

Pokazaću kako se Flashback aktivira, kako se postavlja RESTORE POINT i kako se koristi za vraćanje kompletne baze do te tačke.

1. Da bi Flashback mogao biti aktiviran, baza mora biti u ARCHIVELOG režimu rada. Provjeriti parametre i ukoliko je potrebno, prebaciti bazu u ARCHIVELOG režim. U suprotnom, preskočite taj korak.

SQL> select log_mode, flashback_on from v$database;

LOG_MODE     FLASHBACK_ON
------------ ------------------
NOARCHIVELOG NO

SQL> sho parameter db_recovery_file_dest

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
db_recovery_file_dest                string      D:\_Oracle_\app\flash_recovery_area
db_recovery_file_dest_size           big integer 3912M


SQL> shut immediate
Database closed.
Database dismounted.
ORACLE instance shut down.

SQL> startup mount
ORACLE instance started.

Total System Global Area 2572144640 bytes
Fixed Size                  2178496 bytes
Variable Size            1811939904 bytes
Database Buffers          738197504 bytes
Redo Buffers               19828736 bytes
Database mounted.
SQL> alter database archivelog;

Database altered.

SQL> alter database open;

Database altered.

2. Potrebno je obavezno podesiti dva parametra u bazi: veličinu i lokaciju za Flashback arhivu:

SQL> alter system set DB_RECOVERY_FILE_DEST_SIZE=10G scope=BOTH;

System altered.

SQL>  alter system set db_recovery_file_dest='D:\_Oracle_\app\flash_recovery_area' scope=BOTH;

System altered.

Parametri moraju ostati permanentno u SPFILE ili u init.ora datoteci, da se ne bi nakon restarta baze izgubili. Ako ne stavite “scope=BOTH” ili ukoliko u init.ora datoteci ne sačuvate te parametre, onda ćete nakon restarta baze dobiti slijedeću gresku:

SQL> flashback database to restore point BEFORE_CHANGE;
flashback database to restore point BEFORE_CHANGE
*
ERROR at line 1:
ORA-00283: recovery session canceled due to errors
ORA-38770: FLASHBACK DATABASE failed during recovery.
ORA-38760: This database instance failed to turn on flashback database

a u alert logu ćete pronaći ove greske:

Thu Oct 25 09:45:09 2012
ALTER DATABASE   MOUNT
Successful mount of redo thread 1, with mount id 684437221
Allocated 14761792 bytes in shared pool for flashback generation buffer
Starting background process RVWR
Thu Oct 25 09:45:14 2012
RVWR started with pid=18, OS id=58916978
RVWR could not begin generation of flashback log data because
DB_RECOVERY_FILE_DEST is not set.
Errors in file ..._rvwr_58916978.trc:
ORA-38776: cannot begin flashback generation - recovery area is disabled
Database mounted in Exclusive Mode
Lost write protection disabled
Completed: ALTER DATABASE   MOUNT
Thu Oct 25 09:45:24 2012
flashback database to restore point BEFORE_CHANGE
Flashback Restore Start
Thu Oct 25 09:46:18 2012
Flashback Restore Complete
Flashback Media Recovery Start
 started logmerger process
Thu Oct 25 09:46:18 2012
Slave exiting with ORA-38770 exception
Errors in file ..._pr00_24903742.trc:
ORA-38770: FLASHBACK DATABASE failed during recovery.
ORA-38760: This database instance failed to turn on flashback database
Recovery Slave PR00 previously exited with exception 38770
Flashback Media Recovery failed with error 10879
ORA-283 signalled during: flashback database to restore point BEFORE_CHANGE...

3. Aktiviranje Flashback-a i postavljanje tačke povratka:

3.1. U verziji 10g baza mora biti u MOUNT režimu, da bi se Flashback mogao aktivirati:

SQL> shut immediate
Database closed.
Database dismounted.
ORACLE instance shut down.

SQL> startup mount
ORACLE instance started.

Total System Global Area 2572144640 bytes
Fixed Size                  2178496 bytes
Variable Size            1811939904 bytes
Database Buffers          738197504 bytes
Redo Buffers               19828736 bytes
Database mounted.

SQL> alter database flashback on;

Database altered.

SQL> create restore point BEFORE_CHANGE guarantee flashback database;

Restore point created.

SQL> alter database open;

Database altered.

3.2. U verziji 11gRel2 baza ne mora biti u MOUNT režimu, tako da odmah možemo aktivirati Flashback i postaviti RESTORE POINT:

SQL> alter database flashback on;

Database altered.

SQL> create restore point BEFORE_CHANGE guarantee flashback database;

Restore point created.

SQL> col name for a25
SQL> col time for a34
SQL> set lines 180
SQL> select SCN, NAME, GUARANTEE_FLASHBACK_DATABASE as GUA, STORAGE_SIZE, TIME
 from v$restore_point;

       SCN NAME               GUA STORAGE_SIZE TIME
---------- ------------------ --- ------------ ----------------------------------
   1673006 BEFORE_CHANGE      YES     15941632 23-OCT-12 10.00.42.000000000 PM

4. Napravimo neku izmjenu u bazi – za ovaj primjer ću samo kreirati jedan tablespace i jednog korisnika:

SQL> create tablespace dejan 
datafile 'D:\_ORACLE_\APP\ORADATA\DWHTEST\dejan.dbf' size 16M autoextend off 
extent management local segment space management auto;

Tablespace created.

SQL> create user dejan identified by dejan default tablespace users temporary tablespace temp;

User created.

Opcionalno možete povećati “retention time”, ukoliko taj “maintenance task” traje duže od jednog dana. Standardno je parametar “db_flashback_retention_target” postavljen na 1440 minuta, odnosno jedan dan, pa ga po potrebi povećajte:

SQL> sho parameter flashback

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
db_flashback_retention_target        integer     1440 

SQL> alter system set db_flashback_retention_target=2880;

System altered.

5. Ok, gotovi smo sa izmjenama, pa možemo ili vratiti bazu u prvobitno stanje ukoliko se pojavila neka kritična greška, ili deaktivirati Flashback i obrisati RESTORE POINT:

5.1. Vraćanje baze u prvobitno stanje:

SQL> shut immediate
Database closed.
Database dismounted.
ORACLE instance shut down.

SQL> startup mount
ORACLE instance started.

Total System Global Area 2572144640 bytes
Fixed Size                  2178496 bytes
Variable Size            1811939904 bytes
Database Buffers          738197504 bytes
Redo Buffers               19828736 bytes
Database mounted.

SQL> flashback database to restore point BEFORE_CHANGE;

Flashback complete.

SQL> alter database open resetlogs;

Database altered.

SQL> alter database flashback off;

Database altered.

SQL> drop restore point BEFORE_CHANGE;

Restore point dropped.

5.2. Sve je u redu, nastavljamo u revijalnom tonu:

SQL> alter database flashback off;

Database altered.

SQL> drop restore point BEFORE_CHANGE;

Restore point dropped.

6. OBAVEZNO!!!! uraditi full backup baze, zato što smo napravili novu inkarnaciju baze sa ALTER DATABASE OPEN RESETLOGS.

Eto, pa vi sad usporedite vrijeme potrebno za restore kompletne baze i vrijeme potrebno da se baza pomoću Flashback tehnologije vrati u prvobitno stanje.


OLAP 11g: Instalacija AWM (Analytic Workspace Manager)

Tuesday, 23.10.2012 – Dejan

Pošto se u zadnje vrijeme intenzivno bavim DWH (Data WareHouse) tehnologijama, odlučio sam isprobati nove OLAP opcije u verziji 11g.

U sklopu toga, krenuh instalirati AWM (Analytic Workspace Manager) prateći uputstvo korak po korak kao što piše u tutorijalu “Building OLAP 11g Cubes“. Downloadao sam i instalirao sve šta je bilo potrebno, ali nisam morao čekati dugo na prvu grešku….

U poglavlju “Creating an Analytic Workspace” fino piše:
Enter Oracle11g in the Description field and <hostname>:1521:<SID> in the Connection Information field and click Create.“, a ja se pravim pametan i umjesto toga, upisujem tnsnames connection string (u mom slučaju DWHTEST). Naravno da nije radilo – dobio sam grešku:
oracle.jdbc.driver.T2CConnection.getLibraryVersionoNumber()

Dakle, ispravih to na localhost:1521:DWHTEST i mogao sam nastaviti dalje…

Čitav proces tekao je glatko dok nisam došao do dijela “Loading and Viewing Cube Data” i koraka “Maintain Cube SALES_CUBE” … E tu su nastale muke…

Konstantno sam dobijao grešku (kod mene na njemačkom jeziku, jer su mi lokalna podešavanja tako postavljena):

INI: Fehler beim Erstellen eines Definition Managers, Allgemein in TxsOqConnection::generic<BuildProcess>INI: XOQ-01600: OLAP-DML-Fehler “ORA-01858: Ein nicht-numerisches Zeichen wurde gefunden, während ein numerisches Zeichen erwartet wurde
” bei der Ausführung von DML “SYS.AWXML!R11_LOAD_MEASURES(‘SALES_CUBE.CUBE’  SYS.AWXML!___R11_LONG_ARG_VALUE(SYS.AWXML!___R11_LONG_ARG_DIM 1)  SYS.AWXML!___R11_LONG_ARG_VALUE(SYS.AWXML!___R11_LONG_ARG_DIM 2)  SYS.AWXML!___R11_LONG_ARG_VALUE(SYS.AWXML!___R11_LONG_ARG_DIM 3) ‘NO’)”, Allgemein in TxsOqStdFormCommand::execute

error_maintain_sales_cube

Dole u popisu svih operacija, pored naziva “failed” koraka stoji i nepotpun SQL kôd, tako da ga ne mogu kopirati i izvršiti u SQL Developeru, TOAD-u ili SQL Plusu. I ajd sad ti znaj u čemu je problem !?

E sad na scenu stupa iskustvo – u TOAD-u nađem ovaj session od AWM programa, pokrenem tracing za taj session i opet u AWM kliknem na “Maintain SALES_CUBE”. Očekivano, u trace datoteci sam pronašao kompletan SQL kôd:

PARSING IN CURSOR #46 len=11771 dep=1 uid=91 oct=3 lid=91 tim=215623360605 hv=3267082949 ad=’7ff86cb22c0′ sqlid=’a4nh9jm1brfq5′
SELECT /*+  bypass_recursive_check  cursor_sharing_exact  no_expand  no_rewrite */   T44_CHANNEL_KEY ALIAS_237,   T41_MONTH_ID ALIAS_238,   T38_STATE_PROVINCE_KEY ALIAS_239,   T35_ITEM_KEY ALIAS_240,   SUM(T47_SALES)  ALIAS_241,   SUM(T47_QUANTITY)  ALIAS_242 FROM   (  SELECT /*+  no_rewrite */     T1.”QUANTITY” T47_QUANTITY,     T1.”SALES” T47_SALES,     T1.”DAY_KEY” T47_DAY_KEY,     T1.”PRODUCT” T47_PRODUCT,     T1.”CHANNEL” T47_CHANNEL,     T1.”CUSTOMER” T47_CUSTOMER   FROM     OLAPTRAIN.”SALES_FACT” T1   )   T47,   (  SELECT /*+  no_rewrite */     T1.”CHANNEL_KEY” T44_CHANNEL_KEY   FROM     OLAPTRAIN.”CHANNELS” T1   )   T44,   (  SELECT /*+  no_rewrite */     T1.”DAY_KEY” T41_DAY_KEY,     T1.”MONTH_ID” T41_MONTH_ID   FROM     OLAPTRAIN.”TIMES” T1   )   T41,   (  SELECT /*+  no_rewrite */     T1.”CUSTOMER_KEY” T38_CUSTOMER_KEY,     T1.”STATE_PROVINCE_KEY” T38_STATE_PROVINCE_KEY   FROM     OLAPTRAIN.”CUSTOMERS” T1   )   T38,   (  SELECT /*+  no_rewrite */     T1.”ITEM_KEY” T35_ITEM_KEY   FROM     OLAPTRAIN.”PRODUCTS” T1   )   T35 WHERE   ((T47_CHANNEL = T44_CHANNEL_KEY)     AND (T47_DAY_KEY = T41_DAY_KEY)     AND (T47_CUSTOMER = T38_CUSTOMER_KEY)     AND (T47_PRODUCT = T35_ITEM_KEY)     AND ((T47_DAY_KEY)  IN ((TO_DATE(’06-FEB-2010′) ) , (TO_DATE(’20-JAN-2010′) ) , (TO_DATE(’14-NOV-2010′) ) , (TO_DATE(’21-APR-2010′) ) , (TO_DATE(’02-APR-2010′) ) , (TO_DATE(’11-JAN-2010′) ) , (TO_DATE(’29-JAN-2010′) ) , (TO_DATE(’27-JUN-2010′) ) , (TO_DATE(’30-NOV-2010′) ) , (TO_DATE(’11-AUG-2010′) ) , (TO_DATE(’30-JAN-2010′) ) , (TO_DATE(’25-JAN-2010′) ) , (TO_DATE(’26-NOV-2010′) ) , (TO_DATE(’26-OCT-2010′) ) ,
— … ostatak obrisan radi preglednosti …
(TO_DATE(’21-JAN-2010′) ) , (TO_DATE(’02-JUN-2010′) ) , (TO_DATE(’14-JUN-2010′) ) , (TO_DATE(’16-MAR-2010′) ) , (TO_DATE(’27-JUL-2010′) ) , (TO_DATE(’27-MAR-2010′) ) , (TO_DATE(’22-NOV-2010′) ) , (TO_DATE(’19-SEP-2010′) ) ) ) )  GROUP BY   (T35_ITEM_KEY, T38_STATE_PROVINCE_KEY, T41_MONTH_ID, T44_CHANNEL_KEY)  ORDER BY   T35_ITEM_KEY ASC NULLS LAST ,   T38_STATE_PROVINCE_KEY ASC NULLS LAST ,   T41_MONTH_ID ASC NULLS LAST ,   T44_CHANNEL_KEY ASC NULLS LAST
END OF STMT

Obratite pažnju na crveno označeni tekst! Dakle, kopiram čitav SQL upit i pokrenem ga u SQL Plusu. Naravno – greška:

sqlplus_ora-01858
Prva asocijacija je odmah bila na drugačije NLS postavke, jer su ovdje vrijednosti hardkodirane u formatu DD-MON-YYYY (hardkodiranje bez format maske je idiotski!! čisti amaterizam!!).

Prvo sam pokušao sa “AFTER LOGON ON DATABASE” triggerom postaviti NLS_DATE_FORMAT na DD-MON-YYYY, ali nije dalo očekivani rezultat…
Potom sam u registry promijenio NLS_LANG na AMERICAN_AMERICA.AL32UTF8, no ni to nije dalo rezultat…

Čak mi ni moj prijatelj Google nije pomogao 🙁

Međutim!!!! (sad malo dramaturgije uz zvuke fanfara…)

Daaaaavno sam se nešto bio patio sa JDeveloperom i u podsvijesti mi je sinula ideja sa dodatnim Java parametrima za AWM! Naime, u direktorijumu gdje je instaliran AWM, nalazi se i datoteka awm.bat. E u toj datoteci se nalazi slijedeća linija:

start javaw -mx1024m -jar awm11.2.0.3.0.jar

Dodao sam opcije -Duser.language=en -Duser.country=US, tako da je ta linija izgledala onda ovako:

start javaw -mx1024m -Duser.language=en -Duser.country=US -jar awm11.2.0.3.0.jar

Pokrenuo sam AWM, kliknuo na “Maintain SALES_CUBE” i sve je prošlo bez ijedne greške!!! Mojoj sreći nije bilo kraja…

Dakle, ovu grešku vjerovatno većina “english speaking” korisnika neće nikad dobiti, a nas non-english ko **** …


SQL Developer: instalacija na Windows 7 64-bit : problemi i rješenja

Saturday, 20.10.2012 – Dejan

Na jednom od kompjutera sa instaliranim Windows 7 64-bit, morao sam instalirati Oracle 11gRel2 i SQL Developer. Pošto uz instalaciju baze standardno dolazi i SQL Developer, pomislio sam da neće biti potrebno ništa dodatno podešavati – ali, avaj, grdno sam se prevario…

Prvo je bilo potrebno podesiti lokaciju za java.exe, a onda se pojavila greška “Could not find jvm.cfg!”, odnosno “Unable to find a Java Virtual Machine“… Na svu sreću, otprije mi je poznat problem sa 32-bit i 64-bit nekompatibilnosti, pa sam skinuo ispravnu verziju Jave (trenutno JDK 7u9) i SQL Developera (trenutno verzija SQL Developer 3.2.1).

Naravno, tu nije bio kraj mukama. Nakon što se instaliraju Java i SQL Developer, prilikom pokretanja SQL Developera se pojavila greška “The program can’t be startet, the MSVCR100.dll is missing on the computer“. E, ovu grešku sam prvi put vidio.

Pošto je Google moj najbolji prijatelj, tako mi je pomogao i ovaj put. Rješenje je kopirati taj msvcr100.dll iz direktorija <Java install>\jdk1.7.0_09\bin\ u direktorij <SQL Developer install>\sqldeveloper\sqldeveloper\bin\ i to je to.


Oracle SQL Developer: problem sa memorijom “Java heap space”

Thursday, 04.10.2012 – Dejan

Lično ne koristim Oracle SQL Developer, ali dosta PL/SQL programera kod mene u firmi koriste ovaj alat i žale se, da imaju problema pri radu sa većom količinom podataka ili sa većim datotekama. Ugnjavili su me da im pomognem, tako da sam testirao razna podešavanja parametara za SQL Developer i došao do rješenja.

U dva odvojena bin direktorija (kod mene se nalaze ovdje: C:\Program Files (x86)\Oracle\SQLDeveloper\sqldeveloper\bin\ i C:\Program Files (x86)\Oracle\SQLDeveloper\ide\bin\) se nalaze dvije datoteke za konfiguraciju GUI/IDE interfejsa za SQL Developer: ide.conf i sqldeveloper.conf.

Potrebno je postaviti/promijeniti slijedeće parametre:

C:\Program Files (x86)\Oracle\SQLDeveloper\ide\bin\ide.conf:

AddVMOption  -Xms512M
AddVMOption  -Xmx512M

C:\Program Files (x86)\Oracle\SQLDeveloper\sqldeveloper\bin\sqldeveloper.conf:

AddVMOption -XX:MaxPermSize=512M
AddVMOption -Dsun.awt.keepWorkingSetOnMinimize=true
AddVMOption -Dsun.java2d.noddraw=true
AddVMOption -XX:+UseCompressedOops
AddVMOption -XX:+AggressiveOpts
AddVMOption -XX:+UseConcMarkSweepGC
AddVMOption -XX:+UnlockExperimentalVMOptions
AddVMOption -XX:+UseG1GC
AddVMOption -XX:+G1YoungGenSize=25m
AddVMOption -XX:+G1ParallelRSetUpdatingEnabled
AddVMOption -XX:+G1ParallelRSetScanningEnabled

Ako imate dovoljno RAM memorije, onda umjesto 512M postavite 1024M.


DST funkcija

Thursday, 27.09.2012 – mradovan

DST (Daylight Saving Time) je interesantna fora uvedena za vrijeme 1. svj. rata u svrhu bolje usklađenosti dnevnog i radnog svjetla, te naravno ušteda na potrošnji energije za osvjetljavanje.

Koliko god korisno, pomicanje sata unatrag u proljeće te unaprijed na jesen ima i svoje štetne posljedice, a to su anomalije u broju sati u danima pomicanja kazaljke. Tako se dogodi da u prvom slučaju imamo 23 sata, dok u drugom slučaju imamo dan u trajanju od 25 sati.

Pojedini sustavi standardno zapisuju vremena u UTC formatu, a za svrhu prikaza potrebno je to vrijeme konvertirati u lokalno vrijeme. Iako postoji vjerojatno mnogo algoritama i biblioteka za to, ja sam za potrebe obrade podataka na razini Oracle baze podataka napisao funkciju koja ulazno UTC vrijeme vraća kao lokalno vrijeme. Varijabla l_result unutar funkcije ima inicijalnu vrijednost 1, a to se odnosi na +1 vremensku zonu kojoj pripadamo. Ako živimo npr. u Londonu, ta varijabla bi trebala imati inicijalnu vrijednost 0. Datum pomicanja sata nije fiksan, već se radi o posljednjoj nedjelji u 3. i 10. mjesecu u godini.

CREATE OR REPLACE FUNCTION ARCHDB.LOCALTIME(utc_in date) RETURN date
IS
  l_start date;
  l_end date;
  l_result number := 1;
BEGIN
  l_start := to_date('31.03.' || extract (YEAR FROM utc_in), 'dd.mm.yyyy');
  l_end := to_date('31.10.' || extract (YEAR FROM utc_in), 'dd.mm.yyyy');

  SELECT (TRUNC (LAST_DAY  (l_start) + 1, 'iw') - 22/24) INTO l_start FROM DUAL;
  SELECT (TRUNC (LAST_DAY  (l_end) + 1, 'iw') - 21/24) INTO l_end FROM DUAL;

  IF utc_in BETWEEN l_start AND l_end THEN
     RETURN utc_in + (l_result + 1)/24;
  ELSE 
     RETURN utc_in + l_result/24;
  END IF;

EXCEPTION
   WHEN others THEN RETURN NULL;
END LOCALTIME;

Oracle RAC 11.2 on Windows 2008 R2 – Part II

Wednesday, 01.08.2012 – Noctua4u

DO NOT… IN PRODUCTION!


Obzirom da su mi se više puta obraćali, sa raznih strana sveta, za mišljenje i iskustvo u radu Oracle RAC-a 11.2.0.2 pod Windows 2008 R2, evo sistematizovanih činjenica.

Zapravo, ovo je kratki info i instrukcije o upotrebi RAC-a u produkciji. Sve što je napisano je plod ličnog iskustva i uopšte ne mora da znači da bi se ponovo reprodukovalo ako bi neko ponovo pokušao to isto. Ovo je samo skup činjenica o kojima bi trebalo voditi računa ukoliko neko planira uvođenje ovakvog sistema u produkciju (pod sličnim okruženjem).

Dakle, obzirom da je teks prilično dug, podeljen je na dva dela. Sledi nastavak.

FORMS 6 i još poneki jezici

Ako niste već pročitali, FORMS 6 (i raniji) uopšte “ne ume da razume” SCAN koncept i celu tu priču oko TAF, Fail over i slično. Tj, da budem precizniji, ne može baš da iskoristi sve potencijale koje najnoviji RAC ima. Dakle, ona priča, dostupnost 24/7 i nije baš takva…
No, toga smo bili svesni i taj “nedostatak” smo iskoristili da se konačno ratosiljamo starog FORMS-a.
Što se tiče drugih jezika, bilo je zanimljivih situacija… svi su se uspešno konektovali na RAC, ali pojedini jezici nisu baš umeli da iskoriste sve mogućnosti.

Neka generalizacija bi bila: Ako jezik koristi Oracle Client, onda koristi sve mogućnosti RAC-a inače… šarenoliko…

WIN i memorija

Takođe, jedno od mojih subjektivnih zapažanja. Sve mi se nešto čini da Win, nakon završetka korisničke konekcije ne ume baš da uvek oslobodi zauzetu memoriju.
Naime, u pikovima korišćenja baze, kada ima ~1k konkurentnih korisnika, stvar funkcioniše, ali, nakon odjavljivanja korisnika sa DB, količina zauzete memorije koju prikazuje OS se drastično razlikuje od količine koju prikazuje DB. I to potraje od nekoliko sati do nekoliko dana!
Sama analiza kroz DB ne ukazuje na postojanje memoriskih problema, i na neko neuobičajno trošenje memorijskih resursa, ali indikativno je bilo na strani OS-a da se memorija “popunila” i da se nije “oslobodila” nakon završetka konekcije.

E, sad, sve ovo ima i neke “side efekte” tipa na ~1k konkurentnih korisnika, novi korisnik ne može da ostvari konekciju uz poruku tipa “nema memorije”, u oracle logovima se pojavljuju ORA-600 greške sa generičkim objašnjenjem da je thread ID taj i taj iznenada “umro” i slično ili da db writer ne stiže da upiše sve što treba…

Bug 13902780 – RAC ENVIRONMENT CHANGED NETWORK IP ADDRESS ON ITS OWN INITIATIVE

Na početku priče sam napomenuo da nismo u trenutku kretanja imali redundantne serverske kartice. Bile su naručene, ali… tender u toku pa… znate kako to već ide u zemlji…
Stigle su naknadno.
Nije problem da se to konfiguriše naknadno i da se sve to “prespoji”. I tako, proučimo literaturu što MS, što Oracle, i konstatujemo da ništa nema problematično i mudro da se radi i krenemo.
Regularni shutdown RAC-a (srvctl stop cluster -all)
Regularni shutdown nodova.
Ubaci kartice u nodove.
Upali nodove.
Iiiii….
Zabava počinje!

Šta je premudri Win uradio?

Promenio je sistemski redosled kartica!

Naime, postojeća PublicLan kartica je bila na prvom mestu. Nakon umetanja nove kartice ona je na drugom mestu!!! Na prvom je nekonfigurisana i neaktivna kartica!

Ekvivalent na linuxu bi bio: eth0, postojeći, funkcionalan, konfigurisan i operativan, postaje eth1 a eth0 je neaktivna i nekonfigurisana nova kartica!!!

Mala digresija za neupućene: to bi bilo kao da na maxini ubacujete novi HDD i on postaje C: a postojeći sistem na kom je Win postaje D! Naravno da win više neće da radi, zar ne?

Jedan od vrlo eksplicitnih zahteva prilikom instalacije RAC-a je bio da je PUBLIC LAN na prvom mestu na Win-u (ili na eth0)…

E, obzirom da je RAC prilično inteligentna i “idiot resistant” roba, uspešno je prebrodio ovu Win glupost, ali…
Shvatio je da je izvršena hardverska rekonfiguracija mašine i da su mrežni interfejsi loši, pa je pokušao, u skladu sa pravilima, da sam rekonfiguriše situaciju.
Rekonfiguracija prolazi kako treba, sa stanovišta RAC-a, ali javljaju se “IP duplikati” na mreži, jer RAC sve to uredno registruje i u DNS!

Ala ga je napravio, svaka mu čast!

Desilo se sledeće: tri SCAN IP adrese su razdeljene po nekom algoritmu na postojeće VIP i node interfejse.
U prevodu na govorni srpski, konflikt u DNS-u se ogleda u sledećem:

nslookup ime-noda vraća IP adresu noda, IP adresu VIP-a i jednu ili dve IP adrese SCAN-a!!!

i tako za oba noda.

Dakle, sad su svi nezadovoljni. DNS vrišti, paketi se gube, klijenti (koji se konektuju preko VIP adresa) ne mogu baš uvek da se konektuju, a kad im pođe za rukom, otvaranje konekcije traaajeee…

Najstrašnije u celoj priči je to što nismo odmah ni primetili problem!!!
Jer je nakon tog inicijalnog (re)starta, RAC je raspodelio IP adrese tako da nije bilo konflikta (jedna IP adresa se ne javlja dva puta na nekom mestu)!

Probleme smo učavali kasnije, kada se iz produkcije videlo da nešto nije uredu… Mada, dosta sam lutao tražeći rešenja za te probleme na sasvim drugom mestu…

Problemi su bili šarenoliki.

RMAN je prvi proreagovao i prijavljivao čudne generičke greške tipa “ne znam gde je ASM”, backup je trajao letnji dan do podne.
Listeri su se gasili naizmenično, otprilike na 3-4 dana.
Neki od clusterware servisa su trajno prestali da rade (konkretno CVU servis koji je prvo prijavljivao grešku tipa TIMEOUT, a onda se i ugasio).
Nije mogla da se uradi relokacija resursa sa noda na nod…
OCR diskovi prijavljuju po nekad nedostupnost u OEM-u iako su online i vidljivi…
Gomila neverovatnih ORA-600 grešaka koje upućuju na neke nimalo naivne greške…

I tako sve neki problemi koji ne ukazuju na suštinu. A onda smo morali da restartujemo jedan nod jer je totalno izgubio veze sa svetom… i više nije hteo uopšte da se podigne…
Tada smo i primetili… jer je Win prijavio IP konflikt!

U prvom mometu bila je totalna PANIKA.
A onda, smo krenuli da rešavamo problem ikako nekako… I na brzinu došli do rešenja da restart celog RAC-a može da razreši IP s(r)tanje.
Naime, nakon svega, konstatovao sam da RAC nakon svakog restarta radi HW rekonfiguraciju mrežnih interfejsa! Kao da uvek ubacujemo nove mrežne kartice… iako smo odmah vratili poredak u Win kako treba, to nije više pomagalo.

Dobro, sad, dešava se da ponekad restart samo više ubrlja IP, pa mora nekoliko puta da se restartuje ceo RAC (i to sa različitih nodova stopiraš, i pokrećeš), ali uglavnom se na kraju nekako adrese preraspodele tako da jesu duplirane ali na način koji ne smeta Win-u i klijentima…

Panika je prošla, ostalo je da se nadjie rešenje problema.

E, tu sam svašta nešto naučio i što mi je trebalo i što nije…
Svašta smo pokušavali. Vadili mrežne kartice, vraćali mrežne kartice, gasili nodove, palili nodove, radili u “single nod režimu”, ma sve što bi padalo na pamet OS adminu… ili meni…
Menjao sam IP adrese VIP-u, SCAN-u, interkonkeciji, pokušavao da selim resurse…
Sve u svemu, ništa pametno nismo mogli da izvedemo…

Ono što je užasno frustrirajuće je i sledeća ćinjenica: na Win jednostavno nemaš alata čime nešto možeš da uradiš. DOS je takav kakav je i… kraj.
A mahom sve komande su portovane sa linux-a i… hvala na pitanju, bagovite su jer neko se nije setio da npr. ne postoji UNAME ili AWK na WIN i slično!

…i problemi sa Oracle Support

Onog sekunda kada sam shvatio šta se desilo, alarmirao sam prvo ljude u Oracle Srbija, pa prijavio problem na Metalinku. Obzirom na to da za najviši prioritet oni zahtevaju našu dostupnost 24/7, a mi to, jel, nemamo… morao sam se zadovoljiti nižim prioritetom.
I tu počinje još jedna zabava…
Dobio sam za podršku nekog finog gospodina iz Indije. Ma OK lik… samo što mi se činilo da ne pravi razliku između Win i Lin…

Natezanje je potrajalo jedno mesec dana. A onda na insistiranje i maltretiranje ljudi u Oracle Serbia, dobijam novog… indijca…

I on je bio OK lik, fino smo se razumeli… napisao sam sve do u detalja i on je kao nešto radio…otprilike sve nešto isto što smo mi odmah, prvog sata probali…

I posle nekoliko meseci… ponovo pritisak i ovog puta dobijamo internal info da eskaliramo problem. E, tu se već uključuje ozbiljnija podrška iz… hm… amerike, sudeći po imenu i stilu komunikacije…
To je već bilo sasvim prihvatljivo. Imali smo neku nazovi saradnju i ponovo smo prošli kroz sve procese koje smo mi već probavali. Samo sada sa stručnim objašnjenjem.
Na kraju su konstatovali su da je to bug (naveden u prethodnom naslovu)… ali… da nije do njih već do MSofta…

Naravno, ljudi iz MSofta su konstatovali nešto tipa “Šta? Niste znali da to može da se desi? Pa to nije bug… to je sasvim korektno ponašanje Win-a. A i zašto bi uopšte bio važan redosled mrežnih kartica?”

Na kraju cele sage, koja je potrajala nekih 8 (osam) meseci, dobio sam zadnju preprouku da je izašao “Latest windows bundle Patch 13575310” koji će najverovatnije rešiti problem. Iako sam pročitao detaljno sve u vezi istog, nisam našao ni približno ono što bi mi zaličilo na opis problema koji mi imamo.
Naravno, na konkretno pitanje da li garantuju da će update proći u ovakvom stanju (a pri tom update im JESTE bagovit na win-u) nisam dobio konkretan odgovor.
I tako smo se natezali još neko vreme i…

U međuvremenu, naš OS admin je uspeo da zakrpi problem. Obzirom da je sila u njemu mračna i jaka, ne bih ovde da iznosim u detalje kakvim se sve “mađijama” poslužio i šta je sve radio (a i da budem iskren, i ne razumem baš sve što je pričao) ali svelo se na to da je “objasnio” DNSu i Win nodovima da NIKO osim njega NE MOŽE da promeni IP adrese interfejsa.

To jeste rešilo problem sa IPjem…
Ali…

Neki “sitni” problemčići

Ne bih ovde navodio uobičajne oracle bugove koji se provlače, zapravo, postoje i u regularnim, freš, instalacijama… Nešto poput komande su neadekvatne (nepotpuni portovi sa linuxa), OEM ima svoje bug-ove (npr ne radi kreiranje servisa) koji su inače registrovani bug-ovi na Metalinku.

To sve podvodim pod “regularni posao” tako da…

Takođe, još jednom ponavljam, najverovatnije je upitno i moje poznavanje RAC okruženja, i integracije sa Win-om i svega, ali… ne mogu da se otmem utisku da je Oracle RAC on Windows jedan prilično loš potez.

Naravno da postoje instalacije koje rade. Verujem da postoji u produkciji dosta korektnih i konkretnih scenarija koji rade bez problema. Verujem, takođe, da ima među vama i onih koji to imaju u svojim firmama… ali… ako je po ljudima iz Oracle Serbia, na ovom delu sveta (ako se ne varam, misle na Jevropu, jel) nema u zvaničnoj produkciji varijante RAC + Win…
i mi smo im jedina referenca da to može…

A nakon ovog teksta, nadam se, i da to tako NE treba.