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.

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.