ORION - ORacle I/O Numbers

ORacle I/O Numbers (ORION) e' un tool, sviluppato dalla Oracle Corp., che consente di effettuare prove prestazionali di I/O sullo Storage, simulando le stesse attivita' che svolge l'RDBMS Oracle.
Si tratta di un semplice programma che effettua un benchmark sulle prestazioni di dischi e Storage, evitando l'installazione della base dati e la preparazione di un benchmark applicativo specifico. Bastano alcuni parametri per indicare il tipo di test e l'elenco dei dischi su cui eseguire le prove. Lanciato il programma vengono eseguiti i test previsti in successione ed i risultati ottenuti sono raccolti in file di testo/CSV facilmente utilizzabili per ottenere statistiche e grafici con uno spreadsheet.
ORION non e' certificato ne supportato da Oracle... pero' e' disponibile da anni, funziona senza problemi (anche se qualche limite mi e' capitato di raggiungerlo), viene aggiornato e migliorato con frequenza. L'utilizzo del programma e' gratuito, per effettuare il download e' necessaria la sola accettazione della licenza OTN.

Facciamo un giro?

Scarichiamo ORION dal sito Oracle [NdE il precedente link http://www.oracle.com/technetwork/topics/index-089595.html non e' piu' funzionante] e copiamolo sul server su cui vogliamo effettuare i test.
Scriviamo nel file test01.lun il nome di un disco (eg. /dev/sda2).
Lanciamo il test con nohup ./orion -run simple -testname test01 -num_disks 1 &.
Andiamo a prendere il caffe con la collega (ci vogliono 10 minuti circa), quando siamo tornati il risultato e' pronto.
Leggiamo il file test01*summary*.txt (il nome esatto dipende dalla versione di ORION, nelle ultime c'e' l'orario di lancio ed e' molto comodo)... facciamo finta di capire tutto quello che c'e' scritto sul tipo di test e finalmente troviamo i valori riassuntivi al fondo:

Maximum Large MBPS=152.38
Maximum Small IOPS=959
Minimum Small Latency=2.04
Gia' fatto? Bene! E' un buon risultato: il nostro disco e' in grado di leggere circa 150MB al secondo, di effettuare quasi mille operazioni al secondo ed ha una latenza intorno ai 2 millisecondi (NdE i dati sono veri ma non e' proprio un disco interno...).

I valori riportati sono quelli piu' importanti per lo storage e sono anche quelli piu' significativi per Oracle... continuate a leggere e capirete perche'! Spero...

Come funziona Oracle?

ORION simula il comportamento dell'Oracle RDBMS effettuando la stessa tipologia di operazioni su disco. Ma cosa ci fa ai dischi Oracle?

A seconda del tipo di comando SQL eseguito, l'attivita' di Oracle sui dischi e' molto diversa. Ma vi sono alcune specifiche tipologie di accesso:

Oracle garantisce sempre le proprieta' ACID (NdE ACID=Atomiticy, Consistency, Isolation, Durability) di un transazionale, effettuando scritture sui datafile e sui redo log con un ordine preciso. L'RDBMS Oracle utilizza funzioni di lettura e scrittura su disco sofisticate che dipendono dal sistema operativo ospite e delle librerie presenti. Oltre ad effettuare il READ AHEAD, Oracle utilizza in modo molto significativo l'I/O asincrono.
Non e' tutto qui perche' con l'ASM Oracle puo' fare molto piu' di questo (l'ASM e' un "Volume Manager" interno alla base dati con RAID, ...), ma ci basta gia' cosi'.

Naturalmente queste operazioni avvengono con percentuali differenti a seconda del tipo di database (eg. OLTP, DWH, ...) e del carico presente. Ebbene tutte le modalita' di accesso al disco effettuate dal database Oracle vengono simulate da ORION, che permette di indicare la tipologia e le percentuali dei diversi tipi di accesso.

Ovviamente su una base dati ben configurata, Oracle accede ai dischi solo quando necessario: Oracle utilizza la SGA per ospitare un'ampia buffer cache. Il tuning della base dati e' assolutamente necessario ma non viene trattato in questo documento. Semplicemente quando un dato viene trovato in Cache non c'e' bisogno di accedere al disco.

Tutto qui?

Nella prima prova abbiamo effettuato il test piu' semplice ed in sola lettura. In realta' anche in un test simple ORION effettua una serie di prove o run con tipi di attivita' diverse. Una prima discriminante e' l'accesso a blocchi singoli (eg. 8KB) o in sequenza (eg. 1MB). I run possono provare un solo tipo di accesso o un mix ottenuto mettendo in matrice le diverse combinazioni. I dati acceduti possono essere in sequenza oppure in posizioni casuali. E' possibile effettuare anche prove di scrittura indicando % write (NB i test in scrittura su disco... scrivono su disco! ovviamente la scrittura e' distruttiva: fate attenzione) Se sono presenti piu' dischi i test possono essere eseguiti su tutti i device in parallelo.
Qualche esempio di parametro? Non sono certo sia una buona idea scriverlo! Sono gia' indicati nell'help e nella documentazione e se non avete voglia di leggerli... allora e' meglio che vi limitiate al test simple! Va beh, ho cambiato idea: ecco un esempio di alcune esecuzioni simple con un numero crescente di dischi ed un test avanzato con il 100% di scritture. Prima di lanciare lo script (eventualmente con un nohup), vanno preparati i file test*.lun contenenti i device da analizzare.

./orion_linux_x86-64 -run simple -testname test1a  -num_disks 1 ; sleep 70
./orion_linux_x86-64 -run simple -testname test1b  -num_disks 1 ; sleep 70
./orion_linux_x86-64 -run simple -testname test1c  -num_disks 1 ; sleep 70
./orion_linux_x86-64 -run simple -testname test1d  -num_disks 1 ; sleep 70

./orion_linux_x86-64 -run simple -testname test2a  -num_disks 2 ; sleep 70
./orion_linux_x86-64 -run simple -testname test2b  -num_disks 2 ; sleep 70

./orion_linux_x86-64 -run simple -testname test3a  -num_disks 3  ; sleep 70

./orion_linux_x86-64 -run simple -testname test4a  -num_disks 4  ; sleep 70

# Write test BE CAREFUL with the ACID!
# ./orion_linux_x86-64 -run advanced -testname test1a -num_disks 1 -write 100 -type rand ; sleep 70
# ./orion_linux_x86-64 -run advanced -testname test1c -num_disks 1 -write 100 -type rand ; sleep 70

ORION fornisce il risultato di ogni singolo test su file (vengono dei bellissimi grafici se importati in uno spreadsheet) e riporta il riassunto nel file *summary*. I valori riportati in questo file (MB/sec, I/O Op/sec, latency) sono i piu' significativi, pero' naturalmente dipendono dall'utilizzo della base dati.

Un database OLTP effettuera' sopratutto operazioni di I/O di dimensioni limitate, quindi sara' importante il valore di I/O Op/sec. Un DWH tipicamente accede a grandi quantita' di dati in modo sequenziale... in questo caso saranno significativi i MB/sec. Conoscere la tipologia di accessi effettua una base dati non e' difficile: e' tutto indicato nelle viste V$, basta leggerle! In particolare la vista V$SYSTAT (GV$... su RAC) contiene i contatori su tutte le attivita' di I/O Una query utile e':

set heading off
select 
 'Small Reads:      '||
  sum(decode(name,'physical read total IO requests',value,0)-
  decode(name,'physical read total multi block requests',value,0)),
 'Small Writes:     '||
  sum(decode(name,'physical write total IO requests',value,0)-
  decode(name,'physical write total multi block requests',value,0)),
 'Large Reads:      '||
  sum(decode(name,'physical read total multi block requests',value,0)),
 'Large Writes:     '||
  sum(decode(name,'physical write total multi block requests',value,0)),
 'Total MB Read:    '||
  trunc(sum(decode(name,'physical read total bytes',value,0))/(1024*1024)),
 'Total MB Written: '||
  trunc(sum(decode(name,'physical write total bytes',value,0))/(1024*1024))
from v$sysstat;
select 'Since: ' || startup_time from v$instance;
Quanto riportato e' valido dalla versione 10g R2 in poi, nelle versioni precedenti vanno controllate le V$FILESTAT.

Simulando esattamente il comportamento della base dati si possono effettuare valutazioni molto precise.
In ogni caso i valori ottenuti da ORION sono utili anche per valutare le performance dei dispositivi di storage ed evidenziare immediatamente eventuali problemi, anche senza una simulazione completa del carico applicativo.

Cosa c'e' dentro?

Con la stessa fiducia di San Tommaso ho voluto toccare con mano ORION, quindi l'ho aperto per vedere cosa c'era dentro!
ORION e' un solo semplice file eseguibile linkato dinamicamente con alcune librerie di sistema (eg. libaio.so, libpthread.so). Per essere eseguito non ha bisogno di alcuna variabile di ambiente o di configurazione.

In realta' la parte piu' interessante e' vedere cosa fa... Con semplici comandi di sistema e' facile scoprire come funziona.
Appena lanciato il processo principale crea un segmento di shared memory e genera i thread necessari con clone(). Eseguiti i controlli su device da analizzare ed il lancio dei thread il processo principale non fa piu' nulla se non raccogliere le statistiche. Ad eseguire le singole sessioni di test sono i singoli thread che raccolgono i tempi di ogni singola operazione di I/O. Ecco un esempio:

open("/dev/vx/dsk/dwh_dg/oradata_dwh", O_RDWR|O_DIRECT) = 8
fcntl(8, F_SETFD, FD_CLOEXEC) = 0
stat("/dev/vx/dsk/dwh_dg/oradata_dwh", {st_mode=S_IFBLK|0600, st_rdev=makedev(199, 65530), ...}) = 0
open("/dev/vx/dsk/dwh_dg/oradata_dwh", O_RDONLY|O_DIRECT) = 9
ioctl(9, BLKGETSIZE, 0x7fff2c1461d0) = 0
close(9)                    = 0
brk(0x9041000)              = 0x9041000
times(NULL)                 = 609057139
times(NULL)                 = 609057139
times(NULL)                 = 609057139
REPEAT
    io_submit(47816990777344, 1, {{0x9020a58, 0, 0, 0, 8}}) = 1
    times(NULL)                 = 609057140
    io_getevents(47816990777344, 1, 1024, {{0x9020a58, 0x9020a58, 8192, 0}}, {600, 0}) = 1
    times(NULL)                 = 609057493
...

Ovviamente, mutatis mudandis, quanto descritto sopra per un sistema Linux vale anche per gli altri sistemi operativi ospiti. Per esempio su Solaris vengono utilizzati processi e non thread e le chiamate di I/O sono differenti:

6969:     kaio(AIOWRITE, 256, 0xFFFFFFFF7C300000, 8192, 0x021E400002101590) = 0
6969:     kaio(AIOWAIT, 0xFFFFFFFF7FFBCD60)               = 4329477296
6969:     kaio(AIOWRITE, 256, 0xFFFFFFFF7C300000, 8192, 0x23368000020E94B0) = 0
6969:     kaio(AIOWAIT, 0xFFFFFFFF7FFBCD60)               = 4329575824
Al termine di ogni run, il processo principale raccoglie i dati e lancia il run successivo.

C'e' altro?

A proposito di ORION: non fidatevi mai dei numeri! La matematica e' una scienza esatta. Quindi di tutti i numeri solo uno e' quello giusto: la probabilita' che il risultato sia corretto quindi e'... nulla!
A parte le battute, i risultati ottenuti vanno verificati incrociandoli con le analisi eseguite sul sistema ospite, sullo storage, sugli switch, ...

Nella versione 11g e' stata introdotta la procedure DBMS_RESOURCE_MANAGER.calibrate_io... fornisce risultati analoghi a quelli di ORION!

Qualche link? Ecco!
ORION: User Guide Download
Il problema del tempo: Adesso non e' lo stesso! VMware timekeeping
Benchmark: Il Grinder Database Benchmark


Testo: ORION - Oracle I/O
Data: 31 Giugno 2010
Versione: 1.0.1 - 31 Giugno 2015
Autore: mail@meo.bogliolo.name