Translation

The oldest posts, are written in Italian. If you are interested and you want read the post in English, please use Google Translator. You can find it on the right side. If the translation is wrong, please email me: I'll try to translate for you.

giovedì, luglio 21, 2011

Hierarchical Queries

Come ottenere un result set utilizzando query gerarichiche.

SELECT LPAD(' ', LEVEL*2)||columnX
FROM table
WHERE condition(s)
START WITH condition(s)
CONNECT BY PRIOR column1 = column2
ORDER SIBLINGS BY columnX;

Ci sono due modi di ricevere i dati (il top-down coincide con la visita in ordine anticipato di un albero):

=======
Top down
=======
column1 = Parent Key
column2 = Child Key

=======
Bottom up
=======
column1 = Child Key
column2 = Parent Key

The direction of the query, whether it is from parent to child or from child to parent, is determined by the CONNECT BY PRIOR column placement. The PRIOR operator refers to the parent row. To find the child rows of a parent row, the Oracle server evaluates the PRIOR expression for the parent row and the other expressions for each row in the table. Rows for which the condition is true are the child rows of the parent. The Oracle server always selects child rows by evaluating the CONNECT BY condition with respect to a current parent row.
(11g SQL Fundamentals II - App F.7)

You have to be careful when trying to order the rows of output in a hierarchical query. By default, if you omit the ORDER BY clause altogether, the query attempts to sort rows in an order that’s reflective of the hierarchy. Display will start first with a LEVEL 1 row. If that row is superior to any LEVEL 2 rows, those rows will display next before another LEVEL 1 row displays. The same approach is taken at LEVEL 2, so that rows will display down to leaf node levels before the next rows show at the higher levels. The result is a display that is meaningful to the hierarchy. But if you try to order these rows with the ORDER BY clause, you’ll create a syntactically correct statement that probably doesn’t help you much. ORDER SIBLINGS sorts rows within each given level, not across levels, thus retaining the hierarchical relationship across rows of output. Note that our earlier use of ORDER BY did not create an error message, just misleading output
(OCA Oracle Database SQL Certified Expert Exam Guide)

Per esempio, il top-down:

SELECT LPAD(' ', LEVEL*2)||last_name
FROM employees
START WITH last_name = 'King'
CONNECT BY PRIOR employee_id = manager_id
ORDER SIBLINGS BY last_name;

Userò il concetto di query gerarchiche in due casi:
  1. lock
  2. parallel query

venerdì, luglio 15, 2011

Modify dos windows colours

Questi i parametri della finestra dos utilizzati da Power Shell

Layout: Dimensioni buffer dello schermo
Larghezza 120
Altezza 3000

Layout: Dimensioni finestra
Larghezza 120
Altezza 52

Layout: Posizione finestra
Sinistra 201
Alto 18

Colori: Testo normale
Rosso 255
Verde 255
Blu 255

Colori: Sfondo normale
Rosso 1
Verde 36
Blu 86

Colori: Testo popup
Rosso 128
Verde 0
Blu 128

Colori: Sfondo popoup
Rosso 255
Verde 255
Blu 255

giovedì, luglio 14, 2011

How to change language of SQL Developer

Nella direcotry "bin" di SQL Developer, aprire il file "sqldeveloper.conf" ed aggiungere o modificare le seguenti due righe:
 
AddVMOption -Duser.language=en
AddVMOption -Duser.country=US
 
Una volta fatto, chiudere e riavviare l'applicazione.

Questo il link originale: How to change the language of SQL Developer's user interface?

Di seguito due immagini utili a mostrare le modifiche da fare.



Create new user and assign grant

[nz@dwhtwf01 ~]$ nzsql
Welcome to nzsql, the Netezza SQL interactive terminal.

Type:  \h for help with SQL commands
       \? for help on internal slash commands
       \g or terminate with semicolon to execute query
       \q to quit

SYSTEM(ADMIN)=> CREATE USER sarusso WITH PASSWORD 'please_change_me';
CREATE USER

SYSTEM(ADMIN)=> ALTER GROUP group_dev ADD USER sarusso;
ALTER GROUP

SYSTEM(ADMIN)=> ALTER GROUP group_analyst ADD USER sarusso;
ALTER GROUP



SYSTEM(ADMIN)=> \c NTZ_DWDMP
You are now connected to database NTZ_DWDMP.

NTZ_DWDMP(ADMIN)=> GRANT LIST ON TABLE TO sarusso;
GRANT

NTZ_DWDMP(ADMIN)=> GRANT SELECT ON TABLE TO sarusso;
GRANT



NTZ_DWDMP(ADMIN)=> \c NTZ_DWDMS
You are now connected to database NTZ_DWDMS.

NTZ_DWDMS(ADMIN)=> GRANT LIST ON TABLE TO sarusso;
GRANT

NTZ_DWDMS(ADMIN)=> GRANT SELECT ON TABLE TO sarusso;
GRANT



NTZ_DWDMS(ADMIN)=> \c NTZ_DWSAS
You are now connected to database NTZ_DWSAS.

NTZ_DWSAS(ADMIN)=> GRANT LIST ON TABLE TO sarusso;
GRANT

NTZ_DWSAS(ADMIN)=>  GRANT SELECT ON TABLE TO sarusso;
GRANT

NTZ_DWSAS(ADMIN)=> \q

mercoledì, giugno 22, 2011

Who is blocking me?

col username for a25
col IS_BLOCKED_BY for a20
col state for a40
col sql_id for a15
col obj for a80
set lines 220
set trim on

select
  nvl(USERNAME,schemaname)||' ('||SID||':'||INST_ID||')' USERNAME
 ,SQL_ID
 ,nvl2(BLOCKING_SESSION,BLOCKING_SESSION||':'||BLOCKING_INSTANCE||':'||
   (select
      sql_id
    from
      gv$session holder
    where
      holder.inst_id= s.BLOCKING_INSTANCE
    and holder.sid=s.BLOCKING_SESSION), null) IS_BLOCKED_BY
 ,decode(state, 'WAITING', 'WAITING', 'ON CPU')||'
 ('||substr(event,1,40)||')' state
 ,ROW_WAIT_FILE#||':'||ROW_WAIT_BLOCK#||':'||ROW_WAIT_ROW#||'
'||case
    when ROW_WAIT_OBJ# >0 then
     (select owner||':'||object_name||':'||nvl(subobject_name,'=nosub=')||' ('||object_type||')'
      from
       dba_objects do
      where
       do.object_id=s.ROW_WAIT_OBJ#)
  end obj
from
  gv$session s
where
  event in
    (select
       NAME
     from
       v$event_name
     where
       WAIT_CLASS != 'Idle')
order by sid;

martedì, giugno 21, 2011

Format on Windows 7 [1]

From dos window:

DISKPART
LIST DISK
SELECT DISK # (USB Stick)
CLEAN ALL
CREATE PARTITION PRIMARY
SELECT PARTITION 1
ACTIVE
FORMAT FS=FAT32
ASSIGN
EXIT
EXIT


[1] http://www.sevenforums.com/hardware-devices/61770-cannot-format-usb-flash-drive.html

lunedì, giugno 20, 2011

Single quotes and double quote

Che differenza c'è tra gli apici singoli e quelli doppi in bash?

Semplicemente, nel primo caso la shell non interpreta le variabili, cosa che invece fa nel secondo. In altri termini, nel secondo caso, la shell sostituisce la variabile con il suo valore.

=========
Apici singoli
=========
[my-lap]$ var1=pippo
[my-lap]$ var2='$var1 & pluto'
[my-lap]$ echo $var2
$var1 & pluto

=========
Apici doppi
=========
[my-lap]$ var1=pippo
[my-lap]$ var3="$var1 & pluto"
[my-lap]$ echo $var3
pippo & pluto

domenica, giugno 19, 2011

Workload

Vediamo il significato di workload, preso direttamente dal dizionario:

Workload – The amount of work that a machine produces or can produce in a specified time period [1]

ovvero il "workload" rappresenta la quantità di lavoro che una macchina produce o può produrre nell'unità di tempo. E' una definizione interessante a cui però occorre presrestare attenzione. Il termine "macchina", anche se menzionato, non ha nulla a che fare con un computer o con un database. Qui, la "macchina" è pensata come statica e pertanto non c'è la possibilità di migliorare le prestazioni. Per una fotocopiatrice ad esempio, indipendentemente dalla risma di carta utilizzata o dal numero di copie da produrre, il lavoro svolto è costante.

Quando lavoriamo con i computer, il workload assume tutt'altro significato. Il carico di lavoro, nella sua definizione più generale, è il numero totale di richiesete che arrivano su di un sistema. Nel caso di un database, questo vuol dire che il workload è l'insieme degli statement SQL che, indipendentemente dalla loro esecuzione, arrivano su un'istanza e danno una risposta agli utenti che li hanno sottomessi.

E' chiaro che questo è un concetto duro da accettare perché per "insieme degli statement SQL che arrivano su un istanza" si intende proprio tutto l'SQL: sia quello visibile che quello non visibile. Ed in fondo è difficile fare il tuning dell'invisibile.

Dobbiamo allora utilizzare una definizione più ampia di workload considerando ciò che il database vede indipendentemente da quello che succede al di fuori del database stesso. Questo vuol dire campionare, misurare, tracciare quelle statistiche, all'interno dell'RDBMS, che misurano, quantificano o caratterizzano cosa sia il workload. Ed è fondamentale non solo scegliere quelle che lo misurano ma anche considerare quelle che non dipendono dalle performance del db. Statistiche come "CPU usage", "elapsed time" ed i vari "wait event" non sono buoni esempi di misura del workload poiché dipendono ampiamente dal sistema su cui gli statement SQL stano girando. Metriche più appropriate potrebbero invece essere quelle di gruppo come "numero di esecuzioni di SQL", "active session", "users" etc.

E' chiaro che mentre la scelta delle metriche deve essere indipendente da quanto avviene fuori dal db, ciò che misuriamo lo deve invece essere. Voglio dire che, quando definiamo un workload, al di là dalla metrica utilizzata, dobbiamo essere sicuri che quello che stiamo tracciando sia correlato alle risorse consumate all'interno del database. In questo possiamo allora dire, in base all'aumento o alla diminuzione del workload, qual è o quale sarà l'impatto sulle performance percepito.




[1] What Is Your Definition of Database Workload?

mercoledì, giugno 15, 2011

Metrics

Le metriche mantengono traccia di differenti eventi durante la vita del database [1]. Queste sono visibili da GV$METRICNAME.METRIC_NAME.

Sono statistiche che misurano la variazione dei cambiamenti in statistiche di performance comulative [2]. L'idea di base è la seguente [5]:

Tra di esse troviamo: "CPU Usage Per Sec", "Elapsed Time Per User Call", "Host CPU Utilization", etc.

Prendo un valore V1, all'istante T1 ed uno V2, all'istante T2. A questo punto, la metrica è definita come rapporto (V2 – V1) / (T2 – T1). AWR le raccoglie automaticamente. Frequenza della raccolta e retention dei dati, sono specificati in DBA_HIST_WR_CONTROL

SELECT snap_interval, retention FROM dba_hist_wr_control;

SNAP_INTERVAL
-------------------------------------
RETENTION
-------------------------------------
+00000 01:00:00.0
+00007 00:00:00.0

(profondità di 7 giorni, con raccolta ogni ora) e la modifica è possibileattraverso la funzione DBMS_WORKLOAD_REPOSITORY.MODIFY_SNAPSHOT_SETTINGS

BEGIN
  dbms_workload_repository.modify_snapshot_settings(
  interval => 60,
  retention => 10*24*60
  );
END;


Sono collezionate ogni minuto, storicizzate in memoria e quindi salvate nelle tabelle WRH$ (H=History) di AWR (il tablespace su cui risiedono è SYSAUX). Complessivamente, sono disponibili le seguenti [3][5]:

Table: Global
VIEW/TABLE
GV$METRIC
GV$METRIC_HISTORY

Table: Information
VIEW/TABLE
GV$METRICGROUP
GV$METRICNAME
DBA_HIST_METRIC_NAME
WRH$_METRIC_NAME

Sono disponibili per [5]

» System
» Sessions
» Services
» Events
» Files

e raggruppate come di seguito:

select GROUP_ID, GROUP_NAME from V$METRICGROUP order by GROUP_ID

  GROUP_ID GROUP_NAME
---------- -------------------------------------------
         0 Event Metrics
         1 Event Class Metrics
         2 System Metrics Long Duration
         3 System Metrics Short Duration
         4 Session Metrics Long Duration
         5 Session Metrics Short Duration
         6 Service Metrics
         7 File Metrics Long Duration
         9 Tablespace Metrics Long Duration
        10 Service Metrics (Short)

Ed in V$METRICNAME.METRIC_UNIT, troviamo l'unità di misura in cui viene espressa quella particolare metrica. Sono espresse per

» Valori assoluti
» Percentuali
» Per secondi e per transactioni

Ad esempio:

select group_id id, metric_name, metric_unit from v$metricname where group_id=1

  ID METRIC_NAME                         METRIC_UNIT
---- -------------------------------     -----------
   1 Total Wait Counts                   Waits
   1 Total Time Waited                   CentiSeconds
   1 Database Time Spent Waiting (%)     % (TimeWaited / DBTime)
   1 Average Users Waiting Counts        Users


I valori degli utli 10 minuti sono visibili dalle GV$*, quelle degli utlimi 10+60 minuti dalle GV$*_HISTORY e quelle con retention superiore dalle DBA_HIST_* (le sottostanti tabelle sono le WRH$*). Le viste di sistema disponibili sono:

Table: Events
GROUP_ID VIEW/TABLE
0 GV$EVENTMETRIC
1 GV$WAITCLASSMETRIC
GV$WAITCLASSMETRIC_HISTORY
WRH$_WAITCLASSMETRIC_HISTORY

Table: System
GROUP_ID VIEW/TABLE
2/3 GV$SYSMETRIC
GV$SYSMETRIC_HISTORY
GV$SYSMETRIC_SUMMARY
DBA_HIST_SYSMETRIC_HISTORY
DBA_HIST_SYSMETRIC_SUMMARY
WRH$_SYSMETRIC_HISTORY
WRH$_SYSMETRIC_SUMMARY

Table: Session
GROUP_ID VIEW/TABLE
4/5 V$SESSMETRIC
DBA_HIST_SESSMETRIC_HISTORY
WRH$_SESSMETRIC_HISTORY

Table: Service
GROUP_ID VIEW/TABLE
6/10 GV$SERVICEMETRIC
GV$SERVICEMETRIC_HISTORY

Table: Files
GROUP_ID VIEW/TABLE
7 GV$FILEMETRIC
GV$FILEMETRIC_HISTORY
DBA_HIST_FILEMETRIC_HISTORY
WRH$_FILEMETRIC_HISTORY

Per il GROPU_ID 9 della V$METRICGROUP, non ho trovato associazioni. Suppongo, visto che si tratta di tablespace, che le corrispondenti metriche si potrebbero associare a quelle per "Files".

GROUP_ID VIEW/TABLE
9

[1] Oracle Metrics
[2] Database Metrics
[3] AUTOMATED WORKLOAD REPOSITORY
[4] AWR Metrics
[5] Automatic Workload Repository


Post update 2011/06/16

lunedì, giugno 13, 2011

puser

Quali processo stanno utilizzando la porta del listener? Linux permette di rispondere a questa domanda utilizzando il comando fuser con l'opzione "-n". Il programma che segue è scritto in perl ed è necessario avere i privilegi di accesso a tutte le sottodirectory di /proc. Per utilizzarlo basta lanciare “puser” seguito dal numero della porta da controllare. Ad esempio:

#andrea> puser 1531
1531: 2506 18359

#!/usr/bin/perl
die "Usage: puser \n" if @ARGV[0] == 0;

$ENV{'PORT'} = @ARGV[0];
$shell_in = <<'IN'; echo "" > /tmp/checkPortTestPerl;

for PROC in /proc/*; do
  echo $PROC >> /tmp/checkPortTestPerl 2> /dev/null
  pfiles -F $PROC | grep port |grep $PORT >> /tmp/checkPortTestPerl 2> /dev/null

done 2> /dev/null

IN

$shell_out = `$shell_in`;
open(FH, "< /tmp/checkPortTestPerl") or die "can't open /tmp/checkPortTestPerl: $!";

$i=0;
$lineprep=;

for ($count=0; $row=; $count++) {
  if ($row =~ m/@ARGV[0]/){
    $lineprep =~ m#^/[a-z]+/([0-9]+)$#;
    $process[$i]=$1;

    $i++;
  }
  $lineprep=$row;
}

print "@ARGV[0]: @process\n";
unlink "/tmp/checkPortTestPerl";

Time Zone

Riporto questo documento che scrissi nel 2005

domenica, giugno 12, 2011

set events 10053

Alcuni eventi come il 10053, hanno bisogno del privilegio esplicito di ALTER SESSION.

* Creiamo innanzitutto un utente:

wedosas01.RAIDTRN(SYS)> create user pippo identified by pippo;
User created.

wedosas01.RAIDTRN(SYS)> grant connect to pippo;
Grant succeeded.

* Proviamo ad abilitare l'evento 10053

wedosas01.RAIDTRN(SYS)> conn pippo/pippo
Connected.

wedosas01.RAIDTRN(PIPPO)> alter session set events '10053 trace name context forever , level 1';

ERROR:
ORA-01031: insufficient privileges

* Assegnamo allora esplicitamente il privilegio di ALTER SESSION...

wedosas01.RAIDTRN(PIPPO)> conn / as sysdba
Connected.

wedosas01.RAIDTRN(SYS)> grant alter session to pippo;
Grant succeeded.

* ...e riproviamo ad abilitarlo nuovamente

wedosas01.RAIDTRN(SYS)> conn pippo/pippo
Connected.

wedosas01.RAIDTRN(PIPPO)> alter session set events '10053 trace name context forever , level 1';
Session altered.

venerdì, ottobre 24, 2008

Perfect!

Tre! Tre è il numero perfetto.

In 3 categorie, possiamo classificare i lock:

1. Lock di tipo applicativo
2. Latch sul Dizionario Dati
3. Latch sulle strutture dati di memoria

In 3 categorie possiamo schematizzare le operazioni fatte sulla Buffer Cache:

1. Ricerca (di un blocco in memoria)
2. Modifica/Sostituzione (del blocco ricercercato al punto 1)
3. Scrittura su disco (del blocco modificato al punto 2)

In 3 categorie possiamo raggruppare le informazioni raccolte dalle viste di sistema [Lewis:

1. Persone (v$sesstat, v$session_event, v$sess_time_model)
2. Risorse (v$filestat, v$segstat, v$latch, v$event_histogram)
3. Statement (v$sql, v$sqlstats)

come 3 sono i punti di vista da cui puoi guardare le problematiche:

1. Utente/Sistema
2. Storico
3. In tempo reale

In 3 categorie possiamo raggruppare come viene speso il tempo in Oracle:

1. Prentendo un latch (spinning o sleepling)
2. Mantenendo un latch (lavoro su CPU)
3. Rilasciare un latch (lavoro su CPU)

3 sono gli statement di modifica:

1. Insert
2. Update
3. Delete

3 sono le certificazioni:

1. OCA
2. OCP
3. OCM

Ed infine, 3 sono le leggi a cui un DBA deve sottostare.

Insomma se 3 è il numero perfetto e si adatta bene ad Oracle, vuoi vedere che sotto sotto.....

=================
Update - 04/12/2008
=================

3 sono le maggiori componenti del framework [OCA-CRS-01] per la gestione del db:

1. Istanza, che deve essere gestita
2. Listenser, che consente le connessioni al DB
3. Enterprise Manager, che consente una gestione centralizzata dei database

3 sono le cose che un bravo DBA deve saper utilizzare:
1. vi
2. SQL*Plus
3. RMAN

Sono 3 gli insiemi (di directories) [OCA-ALL-01] che lo standard OFA prevede siano utilizzati per facilitare la gestione del database:

1. Uno per la raccolta dei binari
2. Uno per la raccolta dei files di amministrazione, control files e redolog (archiviati)
3. Uno per la raccolta dei datafiles

Riferimenti:
========
Conquering Oracle Latch Contention - http://www.orapub.com/
How to do Trouble-Shooting - http://www.jlcomp.demon.co.uk/
[OCA-CRS-01] Oracle Database 10g: Administrator Workshop 1, Cap4
[OCA-ALL-01] Oracle Database 10g Certification All-in-One Exam Guide, Parte1, Cap2

martedì, ottobre 14, 2008

Too Many Secrets: Introduzione

A grandi linee possiamo dividere un database in 2 parti distinte: quella su file system (che prende il nome di database) e quella in memoria: la SGA.

La SGA è a sua volta, divisa in 2: processi di background (pmon, smon, etc) e pools (di buffer) tra cui troviamo la Buffer Cache, lo Shared Pool ed il Log Buffer (esistono altre aree in SGA, ma per semplicità, le ometto) [cosmus01].

Alcune domande.

  • La ricerca in Buffer Cache come avviene?
  • Ok, lo statement è nello Shared Pool, ma il suo piano di esecuzione dove lo trovo? Visto che "select * from dual" è diverso da "SELECT * FROM DUAL", dove trovo queste informazioni? Ma sono proprio statement diversi? In fondo a parte la differenza di capitalizzazione, sono proprio la stessa cosa.
  • Bhé si, le "entry di redo" sono scritte in Log Buffer, ma come fa Oracle ad essere sicuro che che la scrittura sia avvenuta?

Ciò che dobbiamo approfondire è quindi:

  1. Buffer Cache

  2. Shared Pool

  3. Log Buffer

In realtà, esiste un punto 0 che va considerato e senza il quale non è possibile proseguire:

  1. Latch
[cosmus01] Sul sito Kosmus, esiste un dettaglio sull'architettura di Oracle 9i. 10g modifica alcune cose aggiungendo ad esempio nuovi processi di backgroud. Tuttavia, tali modifiche non cambiano quanto detto.

venerdì, ottobre 19, 2007

Statspack, forse non tutti sanno che.....

Conosco qualche DBA che dello Statspack ne ha fatto una ragione di vita, come se da esso si potessero individuare e risolvere tutti i problemi di performance legati ad un'istanza.

Premetto di essere il primo ad utilizzarlo per capire cosa c'è che non va studiando l'output che esso genera. Tuttavia, a mio avviso, Statspack deve essere un punto di partenza e non uno di arrivo.

Forse sarebbe più corretto dire che ne determinare problemi di performance, l'output più che guardarlo, andrebbe letto.

Spero di riuscire a chiarire il concetto.


1. Aggregazione dei dati
La funzionalità di base di Statspack è quella di fare due istatntanee dell'istanza in due momenti diversi; quindi si calcolano le differenze ed ne viene mostrato il risultato.

Questo però comporta un'aggregazione di dati. Purtroppo da un aggregato non è possibile estrarre un particolare.

Faccio un esempio. Se ho 100 palline che pesano 100 grammi, dico che ogni pallina pesa 1 grammo. Ma se di queste 100, 99 fossero nere ed 1 bianca, posso ancora dire che una sola pesa 1 grammo? In questo caso, l'informazione aggragata che tutte insieme pesano 100g non è sufficiente: per determinare il peso di ogni singola pallina devo necessariamente pesarle (i).

In Oracle succede una cosa analoga. L'output di Statspack mi dice che ci sono stati problemi di latching, di hard parsing, etc, ma non mi dice chi ne è stato la causa.


2. Heisemberg
Statspack è scritto in PL/SQL: quando vengono calcolati gli snapshot, vengono fatte query sul dizionario dati. In questo modo, secondo il Principio di Indeterminazione di Heisemberg, Statspak (l'osservatore) influenza l'istanza (l'osservato). Oracle 10g, cambia punto di vista: l'RDBMS stesso popola la base dati di AWR (ii).


3. Metriche inesatte
Fino alla versione 10gR1, le informazioni statistiche di uno statement non vengono aggiornate finché questo non si è concluso (iv). O meglio, la sessione aggiorna le statistiche di session e statement alla fine di ogni "database call" (v). Questo vuol dire che la macchina potrebbe star soffrendo a causa di latch contention, ma il nostro snapshot e relativo report non lo segnalano. 10gR2, ha modificato questo comportamento (v), aggiornando le statistiche ogni 5 sec.

4. Statement fantasma
Se il sistema è particolarmente sotto carico, potrebbe succedere che uno statement venga espulso dalla SQL AREA. In questo caso non sarà presente nello snapshot e quindi nel report (commento in v) (vi)


(ii) THE SELF-MANAGING DATABASE
(v) Scoping
(vi) A problem with Statspack

domenica, settembre 23, 2007

1 giorno con Joze Senegacnik

Devo essere sincero. Joze Senegacnik mi era del tutto sconosciuto. Forse anche perché da quando seguo più lo sviluppo che l'esercizio, ho perso un pò di visione su quello che è la tematica che riguardante strettamente il DBA.

Cercando in rete però, mi sono reso conto che Senegacnik deve essere uno in gamba, vista la sua presenza su siti di un certo calibro (hotsos, oaktable). E se guardiamo le sue pubblicazioni (non ancora scaricabili), il quadro risulta completo.

Ero quindi molto curioso di partecipare al seminario, anche se mi chiedevo come in un solo giorno (il 13 Settembre 2007 a Milano) potesse parlare degli internals di Oracle.

Se confrontato con i seminari di Kyte e Lewis, quello di Senegacnik, è stato di tutt'altra pasta. Mentre i primi due hanno forinto tools e metodologie, quest'ultimo si è limitato a fare una panoramica delle strutture interne di Oracle. Del resto in 7 ore di corso, non poteva fare altrimenti.

Dal mio punto di vista, il seminario è stato un riassunto di quanto avevo studiato fino ad allora prorpio: gestione della buffer cache, degli undo etc. La cosa interessante che non avevo mai visto è stata la sua discussione su RAC.

C'è da dire comunque che tutto il materiale su cui si è basato è disponibile in rete sul sito di Julian Dyke, nella sezione Presentations. Consiglio gli interessati di leggersi attentamente i documenti che vi si trovano.

Ma vediamo gli argomenti del seminario:

  1. Buffer Cache
  2. RAC and Cache Fusion, RAC specific wait events
  3. SGA and Library Cache
  4. Undo and Redo
  5. SQL Work Area Memory Management (PGA)

Come dicevo, quanto detto durante il corso, lo si può trovare sul sito di Julian Dyke. Quello che mi è sembrato interreante sono le seguenti cose:

  1. Sia in una istanza stand alone che in RAC, esiste una sola versione "corretente" del blocco. Nel caso di RAC, però, ciò significa che se più sessioni eseguono un UPDATE sullo stesso blocco, questo deve girare tra le istanze.
  2. Ogni istanza è MASTER per un pool di blocchi. Questo vuol dire che se un'applicazione è connessa ad una istanza I1 che non è master per il blocco richierichiesto, allora i) l'istanza I1, chiederà chi è il master per quel blocco; 2) si farà inviare il blocco in questione; 3) fornirà al client che ne ha fatto chiesta, la versione consistente del blocco.
  3. Se un'istanza è lenta a rispondere, tipicamente perché le cpu sono sature, allora viene fatto lo shutdown dell'istanza stessa.



sabato, giugno 16, 2007

Le tre leggi

To be or not to be (a DBA), that is the question
- Amleto

Qualcuno potrebbe pensare che scomodare addirittura Shakespeare per essere o meno un DBA sia un po eccessivo. Eccentirco forse, ma eccessivo no. Vediamo il perché.

NON essere un DBA è facile. Conosco qualcuno che si spaccia come tale, ma è ben lontano dall'esserlo. Piuttosto, essere un DBA, ha a che fare con il carattere. Ma a questo ci arriveremo.

I DBA, esistono a diversi livelli:

  • Chi si occupa di Installazione, Configurazione e Monitoring dell'RDBMS
  • Chi si occupa di Backup & Recovery (quì intendo anche Replicazione, Standby DB, etc)
  • Chi si occupa di HA (RAC ad esempio)
  • Chi si occupa di Performance and Tuning
  • Chi supporta lo sviluppo (DBA Applicativo)

Ovviamente esistono anche altri livelli di esistenza, ma mi premeva far capire la complessità dell'universo DBA.

A tutto questo va aggiunto che un DBA deve conoscere:

  • il Sistema Operativo, per affrontare problematiche si installazione, performance, tuning, backup
  • SQL & PL/SQL, per poter fare interrogazioni mirate sul db sia per il tuining che per il monitoring. Senza tener conto del supporto che deve fornire in qui casi in cui il codice è scritto male
  • linguaggi di scripting come bash, perl e tcl/tk, per il monitoring ed il reporting
  • linguaggi di programmazione come C/C++ e Java, per affrontare problematiche di installazione, di configurazione, supporto allo sviluppo

non è detto che debba conoscere tutto e bene, ma il "conoscere" sicuramente aiuta.

Cosa fondamentale poi, è che il DBA deve saper ascoltare. Deve saper interpretare le esigenze degli utilizzatori del DB. Deve saper capire quali sono i limiti degli utenti e fornire ove necessario valide alternative. E' per questo, ad esempio, che risulta fondamentale la conoscenza dell'SQL e del PL/SQL.

Il DBA deve avere quindi del carattere per poter sapientemente argomentare pregi e difetti di una soluzione. Il DBA deve aver carattere nel saper riconoscere i propri limiti. Il DBA deve aver carattere nell'ammettere che altri ne sanno più di lui. E soprattutto il DBA deve aver carattere dimostrandosi umile.

Quindi: si può fare il DBA per necessità, lo si puòfare per prestigio o solo per lavoro. Ma soprattutto lo si può fare per passione. La differenza? La differenza è il risultato finale: chi lo fa per passione ha fame di informazioni ed è sempre alla ricerca di nuove sfide da superare.

Un DBA cerca di conoscere le strutture fisiche e logiche degli schemi dei database che gestisce e cerca di comprendere le applicazione che li utilizzano: indaga sui perché di eventuali problemi e fornisce, come detto, valide alternative. Badate bene che "valide alternative" non vuol dire creare un indice o lanciare le statistiche: ci sono già tools che fanno questo. Tom Kyte in un suo interessantissimo thread, spiega bene l'idea (riporto parte della discussione):

Tools apply a set of rule, heuristics (like the things I have in my head after doing it for 15 years)... I can look at a query, and a plan -- and with a KNOWLEDGE of the data (statistics to the software, even more knowledge to a human) -- I can generally "make the query better". Not always, but many times. That is the software does, it applies a series of rules to the queries and suggests (based on rules of thumb) enhancements to the schema or the query that would make it better. I've yet to see any software take a query though and say things like "well, if you remove that non-necessary outer join, use the analytic functions instead it'll run much faster". I see them say "add this index" sort of advice (very basic).

Ma non solo. Un DBA deve preoccuparsi anche e soprattutto della sicurezza dei dati. Spesso si tende a confondere tale termine. Credo che il modo giusto di vedere la cosa sia nel dire che "sicurezza" racchiude in se tre concetti distinti:

  • Protezione

  • Affidabilità

  • Disponibilità

La sola mancaza di protezione implica l'assenza delle componenti di affidabilità e disponibilità. Se il dato non è protetto allora possiamo essere certi che prima o poi le modifiche fatte alla base dati andranno perse perché non esiste nesun criterio di garanzia sulle operazioni svolte.

Supponiamo ad esempio di avere uno schema, acceduto dall'applicazione per inviare sms (l'appicazione di produzione), dallo sviluppo per fare i test, dall'esercizio per la manutenzione e dal monitoring per controllare eventuali problemi. In questo caso la probabilità che un danno accidentale si verifichi risulta proporzionale alla grandezza della base dati e dal numero di utilizzatori della stessa.

Che dire: un gran casino.

Ho allora immaginato 3 leggi a cui un DBA deve attenersi. 3 leggi che devono governare la vita di un DB. Un po come le 3 leggi della robotica di Asimov (prima Shakespeare, adesso Asimov: chi mi ferma più):

  • Prima Legge: Il DBA deve garantire la sicurezza dei dati. Deve cioè garantire che siano rispettati i vincoli di Protezione, Affidabilità e Disponibilità;
  • Seconda Legge: Ogni utilizzatore del db deve modellare la propria base dati secondo le esigenze di performance della sua applicazione, purché queste non contrastino con la Prima Legge;
  • Terza Legge: Il DBA deve fornire ogni tipo di supporto agli utilizzatori del database, deve raccogliere le loro esigenze e suggerire valide alternative purché venga rispettata la Seconda Legge;

Vorrei concludere citando Stéphane Faroult, autore di The Art of SQL, edito da O'Reilly. Il libro si rifà, come si evince dal titolo, all'Arte della Guerra di Sun Tzu (questa non ve l'aspettavate, vero?). Nell'introduzione del libro, Faroult scrive:

[...] I realized that the problem of teaching developers how to use database efficiently was similar to the problem of teaching officers how to conduct a war. You need knowledge, you need skills, and you need talent. Talent cannot be taught, but it can be nurtured.

Direi che questa frase calzi perfettamenteanche ai DBA, oltre che agli sviluppatori.


venerdì, giugno 01, 2007

Il Costo è Tempo?

Jonathan Lewis nel suo libro Cost-Based Oracle Fundamentals, nel Cap1 pagina 4 dice:

According to the CPU costing model:
Cost = (
#SRds * sreadtim +
#MRds * mreadtim +
#CPUCycles / cpuspeed
) / sreadtim

where

#SRDs - number of single block reads
#MRDs - number of multi block reads
#CPUCycles - number of CPU Cycles
sreadtim - single block read time
mreadtim - multi block read time
cpuspeed - CPU cycles per second

Translated, this says the following:

The cost is the time spent on single-block reads, plus the time spent on multiblock reads, plus the CPU time required, all divided by the time it takes to do a single-block read. Which means the cost is the total predicted execution time for the statement, expressed in units of the single-block read time.

L’affermazione che il “costo è il tempo” viene ribadito anche sul suo sito, dove aggiunge note al suo libro. La sezione “Cost is time (30th Dec 2005)”, termina infatti con: “Cost is Time – but the units are a bit funny”.

In realtà, come poi Lewis stesso ammette, le cose sono un pò diverse da come sembrano. In un thread del suo Blog infatti, si corregge con la seguente affermazione:

[…] I should have said “resource consumption” rather than cost […]

Di fatto, non possiamo utilizzare il costo di uno statement per dire se è buono o meno. Il motivo di tale affermazione è il risultato di un thread sul sito di Kyte che devo dire essere estremamente interessante.

Il mio personale consiglio è ovviamente di leggerlo. Qui riporto la risposta che Wolfgang Breitling in quel thread da ad una domanda fatta da un lettore:

To those who cling to the illusion that the "cost" of an explained sql is in any way related to the performance, read Tom's lips: "It is not".
The cost is used during the parse to pick one plan among all the ones considered (the one with the lowest "cost"). Once it has served that purpose and a plan is chosen, it is meaningless. In particular, it can NOT be compared to the cost of a another explain. If everything is the same between the two explain, the resulting plans and their costs will be the same. If they are not, then something is different and you can not compare the results anymore.
In pre-Oracle9, the "cost" is roughly equal to the estimated number of logical reads (db blocks needed to find the answer). That estimate of the number of blocks to be visited can be different from reality for a number of reasons, only a few of which could be considered bugs. A lot of the reasons for wrong estimates are due to data distribution and dependencies. That is what Tom refers to a human knowledge about the data which goes far beyond what the optimizer can discern from the statistics. For a presentation I am giving at the Hotsos Performance Symposium (IOUG wasn't interested) I have prepared testcases where the same query on tables with virtually identical statistics returns vastly different numbers of rows to show that it is impossible for the optimizer to come up with accurate estimates and therefore the best plan in all cases.

Cost and execution time are NOT related. There are plenty of examples that prove that they are not. The comparison of costs can only be made by the optimizer while it is parsing a sql and is evaluating different access paths. Once an access path is chosen it is invalid to compare its cost number to that of a different plan and draw any conclusion from it.
When parsing a sql the optimizer, in addition to using the gathered statistics - table as well as system in 9i - the optimizer has to make many assumptions about the data (uniform distribution for example in the absence of histogram data) and if the reality differs from the assumption the plan that came out with the lowest cost based on the assumptions can very well be far inferior to a plan that has a higher cost number (based on the assumptions) but is better suited to the reality and hence performs better. It is a rather far stretch to call the inability of the optimizer to accurately estimate certain characteristics of the data in the database, given limited information, a bug.

giovedì, febbraio 08, 2007

...e 2 giorni con Jonathan Lewis

Prima di qualsiasi commento, mi preme fare una precisazione. Per chi ha un "buon" grado conoscenza ed un "ottimo" livello di preparazione, i giorni 6 e 7 Febbraio non hanno rappresentato nulla di nuovo (se ricordo bene, il valore 7 a scuola era l'equivalente di discreto, poi c'era buono (8), ottimo (9) ed infine eccelente (10)).

Ho ritenuto doveroso tale precisazione per fugare il dubbio se questi due giorni fossero stati o meno utili. Se poi consideriamo il privilegio di aver potuto assistere dal vivo ad una lezione tenuta da Jonathan Lewis ( e farsi autografare il libro)....... :)

Bene. Il seminario ha coperto diversi argomenti, tutti legati all'ottimizzatore. La cosa interessante è che Lewis osserva il modo (Oracle) proprio dal punto di vista del CBO. In quest'ottica, allora gli argomenti trattati hanno tutti un filo conduttore:

Giorno1:
======

  1. Aritmetica di base del COSTO
  2. Meccanismi di JOIN
  3. Selettività ed HINTS
  4. Come e dove trovare i piani di esecuzione
  5. Come leggere i piani di esecuzione

Giorno2:
======

  1. Problemi con i piani di esecuzione
  2. Uso degli indici
  3. Mito degli indici
  4. Descrivere i dati

Le informazioni che ha dato sono state davvero tante ed il mio unico rammarico è di non essere andato lì già preparato: diciamo che se avessi letto e studiato il suo libro, probabilmente avrei non solo apprezzato di più il suo intervento, ma sarei riuscito a catturare tutti i suggerimenti durante le due giornate.

In effetti se proprio dovessi muovere una critica al seminario sarebbe quella di essere stato troppo breve se rapportato alla quantità di cose discusse. Come dire: troppo, in troppo poco tempo. Ci sono state infatti cose che non sono riuscito a capire appieno ed altre che mi sono del tutto sfuggite. Ad esempio, non sono riuscito a capire esattamente l'algoritmo di HASH JOIN, anche se ne ho carpito il senso, ma mi è completamente sfuggito il funzionamento del piano di esecuzione di tipo BITMAP.

Lasciando però da parte le cose che mi sono sfuggite (diciamo il 20%), i restanti argomenti li ho trovati davvero utili.

  • Non è vero ad esempio che l'ottimizzatore, nel caso in cui deve restituire meno del 5% delle righe, utilizza un indice. Ci sono diversi fattori che influenzano il CBO per la scelta del piano di esecuzione: il parametro DB_FILE_MULTIBLOCK_READ_COUNT, il CLUSTERING FACTOR (CF, da adesso in poi), i parametri OPTIMIZER_INDEX_COST_ADJ (OICA) e OPTIMIZER_INDEX_CACHING (OIC), ad esempio.
  • Kyte nei suoi libri indica il fattore di clustering come "grado di disordine di un indice". Lewis ha dato un'altra definizione: "rappresenta la qualità di un indice". Ha inoltre tenuto a precisare che, nel caso in cui il CF approccia al numero di righe, non vuol dire che sia sbagliato. Il fatto è che se cerchiamo valori singoli in una tabella, allora il CF non ha rilevanza: lo ha nel caso in cui, per accedere alla tabella, facciamo un FULL SCAN dell'indice.
  • Le statistiche di sistema (quelle raccolte con dbms_stats.gather_system_stats) misurano le performance di un sistema, visto che valutano la velocità di un processore (Mega operazioni al secondo), valutano la lettura media di una lettura singola e di una lettura multi-blocco. In ogni caso ha detto di fare attenzione ad i numeri che ne derivano. Il fatto è che talvolta le statistiche risultano falsate perché i venditori di hardware ottimizzano i loro sistemi per velocizzare l'accesso al disco rendendo ad esempio più veloce la lettura dalla cache (vedi EMC, ad esempio).
  • Le statistiche di sistema (quelle raccolte con dbms_stats.gather_system_stats) hanno introdotto un nuovo modo di calcolare il costo. In Oracle 8i, c'era solo l'I/O cost, mentre a partire da Oracle 9i, è stato introdotto il CPU cost. Prima di Oracle 9i, cioè, c'erano due presupposti sbagliati:
    1. L'ottimizzatore assumeva che tutte le letture avvenivano da disco
    2. Non venivano considerati i tempi di accesso dell'indice e di un FULL SCAN: una lettura singolo-blocco, cioè, pesava esattamente come una lettura multi-blocco
    Per tale motivo sono stati forniti i parametri OICA e OIC

E queste sono solo alcuni degli argomenti trattati. Immagginate 2 giorni pieni zeppi di cose da apprendere e soprattutto utili al fine di capire come l'ottimizzatore lavora e su come valutare l'impatto dei parametri messi a disposizione dall'RDBMS per far fare al CBO esattamente ciò che noi vogliamo.

Famiglia e lavoro permettendo, cercherò di pubblicare gli appunti che ho preso durante il seminario. La cosa come potete immaginare non è semplice visto che devo ripercorrere tutte le slide del corso e adattare quello che ho scritto con ciò che lui a detto. Cmq, ci proverò.

venerdì, gennaio 05, 2007

Heisenberg Uncertainty Principle

Dopo qualche anno (ormai quasi 7) che lavoro con Oracle, devo ammettere che lo studio di questo database è diventato soprattutto una passione. L'acquisto dei libri tecnici a partire dal 1999, è sempre stato mirato all'approfondimento di Oracle stesso. E non parlo solo di libri specifici (Backup & Recovery, Amministrazione, Performance and Tuning (sopratutto), PL/SQL), ma anche di Sistema Operativi (Unix like), File System e Programmazione C. Ormai ho perso il conto dei soldi spesi.

Ma si sà: gli hobby costano.

Tuttavia, non tutti condividono il mio stesso entusiasmo per Oracle. Qualche giorno fa ho scritto una email a colui che mi ha insegnato le basi di Oracle.

Il suo punto di vista è molto diverso: sostiene che Oracle non è l'unico database e sulla piazza si trovano db che costano meno e sono ugualmente funzionali. Sinceramente non saprei come dargli torto, ma credo che il primo amore non si scordi mai......

--- cut here ---

E’ vero che non conosco altri db se non Oracle, ma devi ammettere che le funzionalità implementate sono valide.

Potrei decantarti le lodi di questo database (la 10g inizia una nuova vita), ma so che saresti in grado di confutarne ogni caratteristica. Ti inoltro allora un
documento
(1). Non so se lo hai già visto o letto, ma data la sua particolarità credo sia importante sottolineare lo sforzo fatto degli ingegneri per la realizzazione del software.

Non voglio anticiparti nulla, ti dico solo che non è la prima volta che il principio di intederminazione di Heisenberg viene tirato in ballo. Non sono un’esperto, ma una mia idea me la sono fatta.

La prima volta che ho visto porsi il problema di come effettuare misure corrette per individuare problemi di performance è stato nel libro Optimizing Oracle Performance (libro davvero incredibile. Scritto da Cary Millsap e Jeff Holt ed edito da O’Reilly). In un piccolo riquadro spiegano come sia difficle effettuare misure precise anche in sistemi di calcolo come i computer.

Il fatto poi di dover utilizzare software di terze parti, comporta l’alterazione del database stesso, per cui molte delle misure potrebbero essere imprecise.

In questo senso Oracle 10g ha fatto un passo avanti. A mio avviso ha cambiato la filosofia di approccio all’analisi: l’osservatore non influenza più l’osservto, ma è l’osservabile stesso a fornire le proprie informazioni.

--- cut here ---

(1) Qui il pdf in formato slide.