27 gennaio 2008

11g Real Application Testing spiegato

Segnalo un interessante articolo di Arup Nanda sull'ultimo Oracle Magazine, a proposito di Real Application Testing e i suoi meccanismi.
Molto più chiaro delle decine di documenti marketing letti fin'ora, l'articolo di Nanda mette alla luce le procedure necessarie per replicare il carico reale su un server di test, facendo capire quali sono gli oggetti fisici in gioco, quindi in ultima analisi come funziona Real Application Testing.

18 gennaio 2008

Bind peeking e piani di esecuzione: DTY

In questi giorni uno sviluppatore mi ha sottoposto una query abbastanza semplice, che però veniva eseguita troppo lentamente dalla nuova versione della nostra webapp.
Ho subito cercato di replicare il comportamento della query via sqlplus, anche con le variabili di bind, e ho visto che effettivamente la query era lenta.
Dopo avere controllato rifatto le statistiche (macchina di test), tutto è tornato normale e la query era velocissima. Da un rapido esame dell'autotrace era evidente che il piano soffriva di statistiche sballate, ma ciò era nelle attese sul database di test, in cui le tabelle vengono caricate e scaricate continuamente.

La situazione per il thin client Java invece non migliorava, anzi a tratti peggiorava.
Ho fatto attivare il trace dalla sessione Java, ma simpaticamente proprio il piano di esecuzione che mi interessava non ha fatto a tempo a finire nel file di trace; pazienza, tanto già sapevo che era sballato e che un piano corretto esisteva (quello scelto via sqlplus e visto con autotrace), l'importante era capire perché. I dati di consistent gets/query, nel trace, erano completamente diversi. La query via Java muoveva 1000 volte la quantità di dati mossa da sqlplus, con le stesse 807 righe risultanti.

Mi sono ricordato di un post di Cristian Cudizio sul peeking, nel quale veniva citato sia il metodo di Alberto Dell'Era per estrarre le variabili di bind usando la feature non documentata dbms_xplan.display_cursor(null, null, 'ADVANCED'), sia un post di Jonathan Lewis in cui ho rapidamente identificato la stessa mia situazione.

Subito ho tentato di vedere le variabili di bind con il metodo di Alberto, ma serve almeno l'accesso alla V$SESSION, e non avevo molta intenzione di indagare, visto che, a mio modo di vedere, avrebbe dovuto funzionare con gli stessi privilegi necessari per l'autotrace.
Ho utilizzato invece il trace 10g via DBMS_MONITOR.SESSION_TRACE_ENABLE(session_id IN BINARY_INTEGER DEFAULT NULL, serial_num IN BINARY_INTEGER DEFAULT NULL, waits IN BOOLEAN DEFAULT TRUE, binds IN BOOLEAN DEFAULT FALSE), applicandola solamente alle sessioni del pool di connessioni esclusivo dello sviluppatore in questione.
Per ogni sessione del pool ho avviato il trace con
DBMS_MONITOR.SESSION_TRACE_ENABLE(session_id => sid, binds => true). Non serve infatti il serial#.

È risultato che sqlplus eseguiva la query velocemente perché io correttamente impostavo il tipo delle variabili di bind a char(5), mentre il thin client Java finiva per impostare il tipo a varchar2.

Dove sono disponibili queste informazioni? Nel file di trace era presente la sezione delle variabili di bind, e per tutte era indicato, oltre il valore, una serie di dati tra cui
oacdty=01
che contraddistingue il tipo varchar (DTY = data type), mentre il tipo di sqlplus era char/nchar (96).

Vi risparmio il piano di esecuzione sbagliato, quasi comico.
Ho potuto vagliare comunque, in seguito, la bontà del SQL tuning advisor di Enterprise Manager, che con una comprehensive analysis mi ha fornito sia il piano sbagliato che quello corretto, proponendomi però di applicare un SQL profile alla query, invece che risolvere correttamente il problema.

16 gennaio 2008

Lentezze in RMAN

Oracle 10g ha problemi residui di lentezza di RMAN, ad esempio durante la sincronizzazione del catalogo. Metalink riporta i workaround principali a nella nota 463227.1.
Un ottimo punto di partenza è l'analisi delle performance da parte di Enterprise Manager sul database del catalogo. Si possono identificare problemi di indici già dall'esame sui picchi di attività.

Le cose principali da controllare sono:
  1. il numero dei record nella tabella ROUT e nella RSR

  2. la presenza di indici su ROUT e RSR

Devono essere presenti gli indici rout_i_db on rout(db_key) e rout_i_rsr on rout(rsr_key).

Anche sulla tabella RSR può essere utile l'indice rsr_i_stamp on rsr(rsr_sstamp, rsr_srecid).

Se collegate al repository di RMAN una versione aggiornata di Oracle, potete sempre fare un'UPGRADE CATALOG per assicurarvi che le modifiche indicate vengano automaticamente incluse, se necessario.

09 gennaio 2008

La saga di DBCA e ASM

Dopo decine di installazioni Oracle questo strano problema di DBCA che non riconosce l'istanza ASM presente e funzionante sul server forse è giunto alla sua soluzione.

Il problema è questo: durante la creazione di un database senza la creazione contestuale dell'istanza ASM (specie RAC, nel mio caso), oppure (più probabile) con ASM già configurata in un'altra ORACLE_HOME, DBCA visualizza il seguente errore:
DBCA could not startup the ASM instance configured on this node. To proceed with ASM diskgroup management you need the ASM instance to be up and running. Do you want to recreate the ASM instance on this node?

Oracle, nella nota Metalink 467756.1, afferma che il problema riguarda la versione 10.2.0.3.0; io confermo, ma accade a volte anche con la 10.2.0.1.0. La soluzione però non è valida, almeno per RAC: la nota dice di aggiungere l'istanza ASM a /etc/oratab, ma nel mio caso la entry apposita già c'era e su tutti e due i nodi del cluster.
Qualsiasi tipo di combinazione e configurazione delle variabili d'ambiente non aveva alcun effetto.

La soluzione (tenetevi forte) sembra proprio la seguente:
eseguire DBCA in questo modo:
#>cd $ORACLE_HOME/bin
#>./dbca

e non tramite path!

D'oh!

07 gennaio 2008

Homepage di EM lenta

In questi giorni sono incappato in una strana lentezza della homepage di Enterprise Manager (database control). Tutte le altre pagine venivano visualizzate con la solita velocità (abbastanza lente), ma quella principale ci metteva fino a mezzo minuto (!).

Ebbene, è risultato che lo statement incriminato era una semplice select da una view di sistema, precisamente V$RMAN_BACKUP_JOB_DETAILS, che ci metteva fino a 30 secondi per restituire una risultato; per inciso, la view conteneva una dozzina di righe.

Bene.

Andando a vedere il testo della view, si scopre che si basa su un'altra view, V$RMAN_BACKUP_SUBOBJ_DETAILS, la quale si basa su un'altra view, V$RMAN_STATUS, la quale si basa finalmente su 3 fixed table.

Da una ricerca sui forum Oracle, ho intuito che la lentezza è dovuta alla presenza delle statistiche sulle 3 fixed table.

È bastato quindi eseguire:
dbms_stats.delete_table_stats('SYS', 'X$KRBMRST')
dbms_stats.delete_table_stats('SYS', 'X$KSFQP')
dbms_stats.delete_table_stats('SYS', 'X$KCCRSR')

per riportare la situazione ad una velocità normale (a dire il vero piuttosto veloce).

Per essere sicuri che non vengano prese in futuro le statistiche su quelle fixed table, si può usare
dbms_stats.lock_table_stats('SYS', 'X$KRBMRST')
e così via.

Un caso in cui le statistiche è meglio non averle.

Nota Metalink: 420200.1