24 settembre 2009

Lancio di 11gR2 ieri a Milano

Ieri sono stato al lancio di Oracle 11gR2 all'hotel Hilton a Milano. Speravo di incontrare qualche DBA del gruppo Oracle DBA Italia di Facebook, ma non è stato così, nonostante le sale fossero affollate.

Con grande piacere ho conosciuto Alberto Dell'Era, di cui ho letto spesso articoli interessantissimi su Oracle. Ho scoperto solo ieri che ha aperto anche un blog.
Ho parlato con Alberto a proposito di un sito aggregatore di riferimento per tutti i DBA italiani, in italiano, in modo da raccogliere anche le sue impressioni. A parte le divergenze, siamo d'accordo che ci vorrebbe una maggiore adesione ed entusiasmo da parte degli altri DBA.

Nonostante io abbia seguito per quanto possibile tutti gli annunci all'uscita di 11gR2, mi ero perso una strana e inusuale novità in Oracle Exadata 2: Hybrid Columnar Compression. Oracle sta passando ai database "colonnari"? Anche Kevin Closson se n'è occupato, e sembra che la versione Oracle abbia qualche feature in più (da ciò l'espressione "ibrida").

Da provare assolutamente la edition-based redefinition, che promette di aggiornare gli oggetti del db in modo trasparente durante una upgrade dell'applicazione. In pratica non si avrà più downtime per gli aggiornamenti. Le "edizioni" sono definibili a livello di database.

Ho visto una slide sul RAC one-node, in pratica un licensing particolare per cui si costruisce un RAC a due nodi in cui c'è sempre al massimo un'istanza attiva, mentre sull'altra macchina ci sono attive tutte le componenti RAC tranne l'istanza. È in ultima analisi un cluster attivo/passivo controllato da clusterware. A quanto ho capito ha anche il difetto(ne) di esistere solo per enterprise edition.

Un ottimo utilizzo del nuovo cluster filesystem ACFS è come ORACLE_HOME condivisa. Nel caso di upgrade della home, è anche possibile utilizzare la funzione di snapshot per poter eventualmente tornare indietro all'occorrenza, solo però per quanto riguarda i file binari, non per il db.

Le idee in casa Oracle non mancano. Vi aggiornerò prossimamente sulle prove di Grid Infrastructure 11gR2 che ho appena ultimato.

15 settembre 2009

Colonne correlate in 11g

In passato avevo già affrontato il problema delle colonne correlate e il sampling dinamico come soluzione alternativa.

In 11g, mediante una nuova modalità di raccolta delle statistiche, è possibile specificare dei gruppi di colonne su cui misurare la correlazione, in qualche modo un'estensione del concetto di distribuzione poco uniforme dei dati (skewness).

Facciamo un esempio più generale di quello fatto in passato, dove la correlazione è meno evidente. Nell'esempio del post sul sampling dinamico avevo utilizzato due colonne con valori uguali per ogni riga, mentre ora utilizzo un caso più reale: immaginiamo di avere tre gruppi di valori, il primo di valori attorno a 1000, il secondo attorno a 2000, il terzo attorno a 3000:
SQL> desc correl
Name Null? Type
------------------- -------- --------------
TAG NOT NULL VARCHAR2(16)
VAL NOT NULL NUMBER(38)

SQL> insert into correl select 'TIPO1', 1000+TRUNC(DBMS_RANDOM.VALUE(0,100)) from all_objects;

61122 rows created.

SQL> select * from correl where rownum < 10;

TAG VAL
---------------- ----------
TIPO1 1035
TIPO1 1012
TIPO1 1003
TIPO1 1090
TIPO1 1070
TIPO1 1061
TIPO1 1004
TIPO1 1020
TIPO1 1032

9 rows selected.

SQL> insert into correl select 'TIPO2', 2000+TRUNC(DBMS_RANDOM.VALUE(0,100)) from all_objects;

61122 rows created.

SQL> insert into correl select 'TIPO3', 3000+TRUNC(DBMS_RANDOM.VALUE(0,100)) from all_objects;

61122 rows created.

SQL> commit;

Commit complete.

A questo punto prendiamo le statistiche standard e vediamo che l'optimizer, per un valore qualsiasi (e non esistente) all'interno del range max-min della colonna, prevede che ci siano 204 righe:
SQL> exec dbms_stats.gather_table_stats(user, 'CORREL', estimate_percent=>100);

PL/SQL procedure successfully completed.

SQL> explain plan for select * from correl where tag = 'TIPO2' and val = 1200;

Explained.

SQL> select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 469411154

----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 204 | 2040 | 141 (4)| 00:00:02 |
|* 1 | TABLE ACCESS FULL| CORREL | 204 | 2040 | 141 (4)| 00:00:02 |
----------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

1 - filter("VAL"=1200 AND "TAG"='TIPO2')

13 rows selected.

Ma ora prendiamo le statistiche utilizzando i gruppi di colonne:
SQL> exec dbms_stats.gather_table_stats(user, 'CORREL', method_opt => 'FOR COLUMNS (TAG,VAL) SIZE SKEWONLY', estimate_percent => 100);

PL/SQL procedure successfully completed.

SQL> explain plan for select * from correl where tag = 'TIPO2' and val = 1201;

Explained.

SQL> select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 469411154

----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 611 | 6110 | 141 (4)| 00:00:02 |
|* 1 | TABLE ACCESS FULL| CORREL | 611 | 6110 | 141 (4)| 00:00:02 |
----------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

1 - filter("VAL"=1201 AND "TAG"='TIPO2')

13 rows selected.

È evidente che ora le cose vanno molto meglio: la stima dell'optimizer è di 611 righe, anche se non esistono righe per cui il valore val è 1201.

Ma il grande vantaggio è che ora la stima di circa 600 righe è valida per i numeri esistenti:
SQL> explain plan for select * from correl where tag = 'TIPO2' and val = 2023;

Explained.

SQL> select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 469411154

----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 611 | 6110 | 141 (4)| 00:00:02 |
|* 1 | TABLE ACCESS FULL| CORREL | 611 | 6110 | 141 (4)| 00:00:02 |
----------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

1 - filter("VAL"=2023 AND "TAG"='TIPO2')

13 rows selected.

SQL> select count(*) from correl where tag = 'TIPO2' and val = 2023;

COUNT(*)
----------
645

1 row selected.

Probabilmente con qualche intervento sull'istogramma del gruppo di colonne è possibile correggere anche la stima errata dovuta alla distribuzione molto disuniforme dei numeri nella colonna val.

Oracle Exadata versione 2

Ieri sera Larry Ellison in persona ha presentato la versione rinnovata della sua Database Machine, battezzata Oracle Exadata version 2. È molto interessante che l'hardware usato sia completamente Sun su Intel.

Ho guardato la presentazione in diretta, ma più che una serie di elogi al prodotto e un elenco di fattori di performance (2x, 4x, 10x, 30x ecc.) affibbiato a ciascuno dei componenti, non ho sentito molti dettagli tecnici.
La novità più rilevante è sicuramente la tecnologia FlashFire, in sostanza una cache intelligente a livello di storage server. I database server tengono in considerazione la presenza della cache al momento di elaborare il piano di esecuzione delle query.

È stato detto più volte che Oracle Exadata versione 2 è la macchina più veloce mai costruita, sia come datawarehousing che (udite udite) per OLTP! Bisogna trovare qualcuno disposto a spendere un bel po' per portarsela a casa.

Aggiornamento 22-9: da oggi è disponibile il webcast qui.

09 settembre 2009

Alcune novità dell'optimizer 11g

In 11g ci sono diverse novità per quanto riguarda il cost-based optimizer:
  • Null-aware anti-join: interessante per me perché l'ho affrontato qualche giorno fa. Quando si ha una query del tipo:
    SELECT... FROM T1 WHERE T1.X NOT IN (SELECT T2.Y where...);
    e T2.Y è una colonna che può assumere valori nulli, 10g e precedenti possono utilizzare un piano di esecuzione che porta a un eccesso di consistent gets (sostanzialmente CPU), e quindi a una query molto lenta. In 11g è invece possibile l'anti-join.
    Consiglio l'ottimo articolo di Greg Rahn per chi volesse approfondire l'argomento.

  • Join Predicate Pushdown: quando c'è una join tra una tabella e una view, la condizione di join (esempio T.X = V.Y) viene computata direttamente con la tabella nella view che contiene la colonna: T.X = TV.Y. In questo modo si sfruttano eventuali indici presenti, anche con view che contengono group by, distinct e join

  • Spostamento del group by: nel caso di una join con group by, l'optimizer è in grado di spostare il group by e la funzione di gruppo all'interno di una view, che permette di ridurre le righe su cui fare la join.

  • Eliminazione dei DISTINCT: l'optimizer analizza i vari blocchi di cui è formata una query, ed elimina i DISTINCT ove possibile.

Per molti versi sembra che tutte queste ottimizzazioni siano volte ad evitare rallentamenti dovuti ai più comuni errori di programmazione.

07 settembre 2009

Nuovi processi di background in 11g

Oracle 10g ci aveva abituato ad una proliferazione di processi di background, specialmente riguardo a RAC, ma 11g batte tutti e introduce tutta una serie di processi dedicati ai compiti più fantasiosi:
  • DBRM (database resource manager) imposta le risorse del Resource Manager

  • DIA0 (diagnosability process) risolve i deadlock e rileva i blocchi

  • EMNC (event monitor coordinator) gestisce eventi e notifiche

  • FBDA (flashback data archiver process) archivia i dati storici delle tabelle per cui viene attivato il flashbak archive e mantiene l'archivio

  • GTX0-j (global transaction) permette le transazioni globali distribuite (XA) in ambiente RAC. Attualmente le transazioni XA sono possibili solo su un unico nodo per client

  • GMON gestisce i dischi nei diskgroup ASM

  • KATE gestisce l'I/O di un disco ASM che è andato offline per qualche motivo

  • MARK marca come invalide le unità di allocazione scritte su dischi ASM che sono andati offline

  • SMCO (space management coordinator) gestisce l'allocazione e la deallocazione dello spazio su disco in maniera proattiva

  • VKTM (virtual keeper of time) mantiene l'orologio di riferimento, che viene aggiornato ogni secondo

Col tempo ci sarà occasione di approfondire i compiti dei nuovi processi.

02 settembre 2009

Lancio di 11gR2 a Milano il 24: ci vediamo?

Giovedì 24 settembre si terrà a Milano un evento per il lancio di Oracle 11g release 2.

Io ci sarò; se qualcuno di voi ci sarà, potrebbe essere un'occasione per incontrarsi, fare conoscenza e scambiare qualche opinione.
Lasciate i vostri messaggi nei commenti, così ci si trova più facilmente.

Si preannunciano interessanti le discussioni aperte con i beta-tester dalle 11 alle 12 e le sessioni pomeridiane che ricapitolano le nuove feature.

11gR2 Generally Available

È uscita oggi la release 2 di Oracle 11g.

Se ha le stesse novità che aveva 10gR2 rispetto alla R1, si preannunciano interessanti prove e confronti.

Aggiornamento 15:09: I primi requirements per l'installazione si trovano nei documenti Metalink 880936.1 (32 bit) e 880989.1 (64 bit).

Ora Clusterware è diventato Grid Infrastructure? :-)