25 settembre 2008

Analytics - n.2: LEAD e LAG

LEAD e LAG sono funzioni analitiche che permettono di accedere al valore di un campo di un record del recordset risultato della nostra query, specificando l'offset dal record in cui la funzione viene valutata.
Nel caso di un offset che va fuori dal recordset, è possibile specificare un valore di default ritornato dalla funzione.

Il punto essenziale, come per gran parte delle funzioni analitiche, è l'ordinamento del risultato: il valore dell'n-esima riga prima o dopo la riga corrente è dato proprio dell'"order by" specificato nel partizionamento del resultset.

Prendiamo sempre l'esempio dei maratoneti che ho usato in un post precedente.
Mettiamo che io voglia conoscere la differenza di tempo in arrivo tra un corridore e il successivo, un po' come viene fatto alla fine di gare a tempo.
Posso usare la funzione LAG con parametro 1 e computata ordinando la tabella per arrival_time:
 SELECT runner_id,
arrival_time ,
extract(minute FROM
(arrival_time - lag(arrival_time, 1, arrival_time) over (order by arrival_time)) DAY TO second)
||''''
|| extract(second FROM
(arrival_time - lag(arrival_time, 1, arrival_time) over (order by arrival_time)) DAY TO second)
||'"' time_diff
FROM marathon
WHERE rownum < 10
ORDER BY arrival_time;

Nell'esempio prendo solo 10 righe per avere un po' di intervallo tra i tempi di arrivo e il risultato è il seguente:
 RUNNER_ID ARRIVAL_TIME        TIME_DIFF
---------- ------------------- ----------------------------------------------------------------------------------
4038 2008-06-19 12:32:09 0'0"
3144 2008-06-19 12:44:10 12'1"
660 2008-06-19 12:51:40 7'30"
4450 2008-06-19 12:54:54 3'14"
2441 2008-06-19 12:58:28 3'34"
591 2008-06-19 13:02:55 4'27"
3825 2008-06-19 13:05:03 2'8"
3169 2008-06-19 13:11:21 6'18"
4036 2008-06-19 13:11:39 0'18"

La funzionalità di LEAD è analoga a LAG, solo che va nel verso opposto, ovvero considera i record precedenti a quello in cui viene valutata.

21 settembre 2008

Oracle DBA Italia

Tempo fa sul blog di Cristian Cudizio si parlava di qualche iniziativa per riunire tutti i DBA Oracle italiani in una specie di network.
Ho provato a pensare a qualche soluzione, e l'unica che mi è venuta in mente è utilizzare Facebook.
Ho deciso quindi di fare una prova: in pieno spirito Web 2.0, ho creato un gruppo Facebook per tutti i DBA Oracle in Italia.

Invito tutti gli interessati ad iscriversi, prima di tutto a Facebook, se non fossero già iscritti.

Per ora il gruppo è pubblico, quindi tutti possono iscriversi e utilizzare tutte le funzioni messe a disposizione da Facebook. Anche il contenuto delle pagine create dai membri rimane pubblico.

Le funzioni sono le seguenti:
  • Discussioni
  • Bacheca
  • Foto
  • Video
  • Link utili
  • Eventi

Ritengo che siano più che sufficienti per iniziare a interagire, scambiarsi informazioni che altrove (es. sui blog dei partecipanti) non trovano collocazione e, perché no, organizzare futuri incontri ed eventi.
Non dimentichiamo che anche le aziende potrebbero essere molto interessate a noi!

Forza quindi! Io per oggi ho contribuito con il logo. Sfogate la vostra voglia di comunicare!
Attendo commenti, contributi, modifiche, critiche, segnali di vita...

25 agosto 2008

Dischi, burro e marmellata

Sono quantomai sorpreso dell'apprendere, sull'ultimo numero dell'ottimo Oracle Magazine, che Oracle ha avviato pochi mesi fa un progetto open source per un nuovo potente filesystem.

La grande sorpresa consiste nel fatto che tale BTRFS dove, viene precisato, btr si pronuncia butter, ricalca fedelmente l'interessantissimo ZFS di Sun, disponibile già da tempo nella famiglia di sistemi operativi Solaris.

Avevo intenzione di fare un post solo su ZFS per le sue rivoluzionarie caratteristiche, ovviamente dal punto di vista Oracle, anche per il fatto che ci sto lavorando abbastanza intensamente e ne ho potuto apprezzare le ottime funzionalità.

A questo punto cominciamo da ZFS. La migliore definizione che mi viene in mente è che ZFS è un filesystem e volume manager integrati, con possibilità di snapshot stile LVM e possibilità di replica anche incrementale.

Un'importantissima caratteristica di ZFS è che è un filesystem copy-on-write (COW): ciò significa che tutte le modifiche ai dati vengono scritte su disco in nuove allocazioni, lasciando integra su disco la precedente versione dei dati. Ciò è da tenere ben presente per un DBA poichè, col passare del tempo, i dati tendono a venire sparpagliati sul disco, aumentando quindi il tempo d'accesso specie per le letture di dati in sequenza; si pensi ad esempio all'utilità del db_file_multiblock_read_count di Oracle, anche se è ormai quasi obsoleto.

ZFS è anche un volume manager, ovvero può prendere in gestione più dischi e comporre zpool più grandi, in cui gestisce automaticamente lo striping; oppure può garantire livelli di tolleranza ai guasti come il mirroring e il RAIDZ, una modalità che somiglia molto al RAID5 o addirittura RAID6 con due dischi di "parità".

Il COW diventa meno importante man mano che il numero dei dischi a disposizione aumenta, poiché lo striping riduce naturalmente il raggruppamento dei dati in blocchi contigui su disco.

ZFS è un filesystem transazionale, ovvero le modifiche ai dati o avvengono in blocco o non avvengono; ciò, unito al COW, consente di fare a meno del journal, caratteristica di punta di filesystem avanzati come ReiserFS o ext3.

Con ZFS si possono anche fare snapshot consistenti istantanei dei filesystem, direttamente accessibili sul filesystem stesso, quindi copiabili e salvabili. Ciò rende possibile un hot-backup con il comando 10g ALTER DATABASE BEGIN BACKUP, come potrebbe avvenire con storage molto più costosi.

Da un punto di vista amministrativo ZFS è troppo semplice per essere vero: consente in pochi e semplicissimi comandi di sintetizzare numerose operazioni di amministrazione del sistema. E non solo, offre un supporto nativo a iSCSI e NFS senza toccare alcun file di configurazione.

Torniamo a BTRFS: le caratteristiche sul sito Wiki sembrano proprio ricalcare quelle di ZFS, che è anch'esso open-source. Ma allora perché non integrarlo nel kernel Linux?
Il problema sta nella licenza, che non è GPL (e sembra che Sun abbia fatto apposta).

La mia sensazione però è che alla fine non se ne faccia un granché, visto che ZFS è già in produzione avanzata sotto Solaris, mentre BTRFS è all'inizio dello sviluppo.

Tornerò sul tema ZFS per dirvi degli interessanti documenti in rete sui database e dei risultati delle mie prove.

14 agosto 2008

Oracle 11g su OpenSuSE 11

Visto che uno dei due dischi del mio megaserver di casa ha deciso, bontà sua, di rimettersi a funzionare, sono riuscito a fare vari esperimenti di cui vi parlerò, tra cui la prova di installazione di Oracle 11g su OpenSuSE 11.

L'installazione è andata molto bene e senza alcun errore, quindi la piattaforma preferenziale per le mie prossime installazioni di prova 11g sarà sicuramente OpenSuSE 11.

L'unica variazione nella configurazione, rispetto a quella di default, è l'aggiunta delle componenti di sviluppo C/C++ durante l'installazione, e un package libstdc++-devel che ho aggiunto io per precauzione.

Il vantaggio maggiore di utilizzare una distribuzione Linux non supportata da Oracle è di avere un sistema operativo completamente aggiornato, e in modo gratuito. Per noi che smanettiamo spesso con questo genere di software sarebbe bello che tutto ciò che dobbiamo installare sia liberamente utilizzabile per fini di ricerca.

12 luglio 2008

ASM a linea di comando

Ogni tanto arriva qualche e-mail dai lettori di questo blog. La maggior parte delle domande riguarda ASM, il volume manager/filesystem di Oracle dedicato all'immagazzinamento dei dati del suo motore RDBMS.

Forse non tutti sanno che ASM è accessibile anche da linea di comando con asmcmd.

asmcmd è sostanzialmente un prompt dei comandi che si collega all'istanza ASM attiva sulla $ORACLE_HOME impostata nell'ambiente, con il relativo $ORACLE_SID impostato a +ASM o +ASM<n> nel caso di RAC.

Eseguiamo asmcmd:
oracle@host:~> asmcmd -p
ASMCMD [+] >

Il flag -p permette di mostrare il path tra parentesi quadre.
I comandi disponibili sono: cd, du, find, help, ls, lsct, lsdg, mkalias, mkdir, pwd, rm, rmalias.
Per ogni comando si può avere l'help con help <comando>.
All'avvio troviamo l'elenco dei diskgroup montati dall'istanza ASM e in seguito i database montati in notazione OMF:
ASMCMD [+] > ls
DG1/
ASMCMD [+] > ls
ASMCMD [+] > cd DG1
ASMCMD [+DG1] > ls
DBTEST/
ASMCMD [+DG1] >

All'interno delle directory DB troveremo le sottodirectory in notazione OMF come su filesystem ordinario:
ASMCMD [+DG1/DBTEST] > ls
ARCHIVELOG/
CONTROLFILE/
DATAFILE/
ONLINELOG/
PARAMETERFILE/
TEMPFILE/
spfileDBTEST.ora
ASMCMD [+DG1/DBTEST] >

Il comando du mostra l'utilizzo del diskgroup:
ASMCMD [+DG1/DBTEST] > du .  
Used_MB Mirror_used_MB
24529 24529

Il comando lsdg mostra tutti i diskgroup:
ASMCMD [+] > lsdg
State Type Rebal Unbal
Sector Block AU Total_MB
Free_MB Req_mir_free_MB Usable_file_MB
Offline_disks Name
MOUNTED EXTERN N N
512 4096 1048576 347430
322841 0 322841
0 DG1/


Contrariamente a un filesystem normale, esistono i comandi per creare e rimuovere alias mkalias e rmalias.
Gli alias in ASM sono file finti nel filesystem che puntano a file normali che risiedono sempre in ASM; possono essere visti come link simbolici. Ricordiamo infatti che ogni file in un volume ASM è un file OMF, ovvero è un file del database Oracle (controlfile, datafile, redo, e così via) con un nome scelto dal RDBMS, ma non un file ordinario. Per ogni file del db, quindi, esiste uno e un solo file OMF con il nome scelto da Oracle. Per avere file con nomi più leggibili o facili da ricordare si usano gli alias, a cui si può fare riferimento con i comandi DDL da prompt SQL al posto dei file OMF. Gli alias possono risiedere ovunque in ASM.

03 luglio 2008

Vantaggi del sampling dinamico

Ho recentemente letto un curioso aricolo di Tom Kyte su Oracle Magazine sul dynamic sampling e i suoi vantaggi rispetto alle statistiche usate dal cost-based optimizer (CBO) in alcuni casi particolari.

La prima parte dell'articolo parla di V$SQL ed è molto interessante. Qui mi occupo della seconda parte, ovvero della cardinalità nel piano di esecuzione a seconda che venga usato il CBO o il sampling dinamico.

Nell'articolo si fa l'esempio di una tabella in cui due colonne (X e Y) hanno 12 valori distinti distribuiti uniformemente tra le righe, per cui una query del tipo
SELECT * FROM T WHERE X=5;

restituisce 1/12 delle righe, mentre
SELECT * FROM T WHERE X=5 AND Y=6;

restituisce 1/144 delle righe (1/12 * 1/12).
O almeno, questa è la selettività che si ottiene dalle statistiche sulla tabella.

Ma che cosa accade se X=Y per ogni riga? Una query come
SELECT * FROM T WHERE X=5 AND Y=6;

ritornerebbe 0 righe, quindi la stima del CBO sarebbe errata (introducendo eventuali piani di esecuzione sballati).

Utilizzando il sampling dinamico:
select /*+ dynamic_sampling(t 3) */ * from t

si ottiene invece il costo corretto, molto più basso, e quindi anche il piano corretto.

Il sampling dinamico è regolabile a vari livelli, espressi dal numero che segue il nome della tabella nell'hint all'optimizer. Il valore minimo del sampling è 32 blocchi con n=1; per i livelli da 1 a 9 vale la formula 32*2^(l-1) blocchi dove l è il livello di sampling. Nel nostro caso di n=3 si ha un sampling di 4*32=128 blocchi, per cui quasi certamente l'optimizer ha letto l'intera tabella. Per questo motivo il costo finale è molto preciso. Se il livello è 0 non si ha sampling, se è 10 il sampling viene fatto su tutti i blocchi della tabella (quindi può risultare mooolto lento).

Il dynamic sampling è quindi una possibilità in più utilizzabile nei casi in cui il CBO ci fornisce piani di esecuzione subottimali.

OCA 10g solo con esame SQL

Dal 28 novembre 2008 verrà richiesto un esame SQL per ottenere la certificazione OCA 10g, contrariamente a quanto è successo fin'ora, da quando fu introdotta la certificazione di base 10g.

Vedo con piacere che il buon vecchio 1Z0-007 (SQL 9i) torna in auge.

23 giugno 2008

Analytics - n.1: NTILE

Con questo post inauguro la serie "Analytics", ovvero come utilizzare le potenti funzioni analitiche di Oracle 10g.

NTILE è una funzione che permette di ottenere il numero corrente di partizione dei dati, basandosi su un criterio di partizione determinato nella query.

Facciamo subito un esempio: ho una tabella che contiene i tempi di arrivo di una maratona con tanti partecipanti, diciamo 5000. Di questi, 1000 sono arrivati al traguardo, mentre gli altri si sono persi per strada.
La tabella contiene un ID univoco del corridore e il suo tempo di arrivo.

Supponiamo che io voglia dividere l'insieme degli "arrivati" in n gruppi omogenei, cioè aventi lo stesso numero di componenti.
Gli ID, anche se generati con una sequenza, sono distribuiti casualmente, dato che solo 1/5 dei corridori è arrivato alla fine; lo stesso vale per i tempi di arrivo.

La funzione NTILE ci permette di dividere il nostro set di dati in partizioni uguali, assegnando ad ogni riga il numero di partizione in cui si trova. Il criterio per trovarsi in una partizione o in un'altra è il tempo di arrivo in ordine crescente.

Dividiamoli ad esempio in 10 gruppi:
SQL> select * from marathon;

RUNNER_ID ARRIVAL_TIME
---------- -------------------
93 2008-06-19 13:11:39
3144 2008-06-19 12:44:10
4450 2008-06-19 12:54:54
453 2008-06-19 12:52:58
808 2008-06-19 12:48:00
4036 2008-06-19 13:11:39
4048 2008-06-19 13:06:48
660 2008-06-19 12:51:40
4091 2008-06-19 13:12:38
591 2008-06-19 13:02:55
[...]

Con la query seguente otteniamo la divisione in gruppi:
SQL> select runner_id, arrival_time, ntile(10) over (order by arrival_time) nt from marathon;

Come si può vedere, ci sono esattamente 100 corridori in ogni gruppo:
SQL> select nt, count(*) from
(select runner_id, arrival_time,
ntile(10) over (order by arrival_time) nt from marathon)
group by nt order by nt;

NT COUNT(*)
---------- ----------
1 100
2 100
3 100
4 100
5 100
6 100
7 100
8 100
9 100
10 100

10 rows selected.

Possiamo anche calcolare l'ntile su una partizione dei dati originari: immaginiamo per esempio che ai corridori siano state assegnate delle pettorine colorate di rosso se il loro id era tra 1 e 1000, verde se tra 1001 e 2000, blu se maggiore di 2000, divisi quindi per categoria.
Una query come la seguente divide in dieci sottogruppi ogni categoria, basandosi sempre sul tempo di arrivo:
SQL> select runner_id, arrival_time, color,
ntile(10) over (partition by color order by arrival_time) from marathon;

02 giugno 2008

ROWSCN, una soluzione ai lost update

Per le applicazioni web-based l'aggiornamento di una serie di record nel database presenta problemi diversi da quelli delle applicazioni tradizionali client-server, che di solito utilizzano il metodo "SELECT ... FOR UPDATE".

Facciamo un esempio: due utenti di una webapp caricano una form di attributi di una stessa persona (identificata solamente da una chiave primaria) e li modificano nello stesso intervallo di tempo. Trascurando l'opportunità della cosa, l'ultima che avrà cliccato su "aggiorna" scriverà i dati della form nel database, sovrascrivendo eventuali modifiche fatte dal primo utente.

Ci sono un paio di metodi per accorgersi questa situazione: fare la "SELECT FOR UPDATE" appena prima di modificare il record inserendo una condizione WHERE che contiene tutti i dati originali, oppure usare una colonna timestamp per sapere la data di ultima modifica.
Non ci interessa invece che cosa fa l'applicazione una volta accortasi della cosa: ciò dipende dalla business logic, ovvero dal tipo di applicazione.

In Oracle 10g è presente una nuova pseudo-colonna: ORA_ROWSCN. Essa contiene l'SCN relativo all'ultima operazione DML effettuata sul blocco che contiene la riga selezionata. In questo modo è possibile sapere se il blocco è stato modificato dall'ultima lettura effettuata; ma come si fa ad utilizzare a livello di riga? La dipendenza a livello di riga viene abilitata all'atto di creazione di una tabella con la clausola ROWDEPENDENCIES.

Facciamo un esempio:
SQL> select CLAIM_NUM, CLAIM_AMT, CLAIM_BAL, ROWID, ORA_ROWSCN
from claim;

CLAIM_NUM CLAIM_AMT CLAIM_BAL ROWID ORA_ROWSCN
---------- ---------- ---------- ------------------ ----------
1 100 0 AAAdsYAAEAAAAD0AAA 1070257362
2 200 99 AAAdsYAAEAAAAD0AAB 1070257362
3 300 0 AAAdsYAAEAAAAD0AAC 1070257362
4 400 350 AAAdsYAAEAAAAD0AAD 1070257362
5 500 0 AAAdsYAAEAAAAD0AAE 1070257362
6 600 295 AAAdsYAAEAAAAD0AAF 1070257362
7 700 700 AAAdsYAAEAAAAD0AAG 1070257362
8 800 800 AAAdsYAAEAAAAD0AAH 1070257362

8 rows selected.

SQL> update claim set CLAIM_BAL = 1 where claim_num = 1;

1 row updated.

SQL> select CLAIM_NUM, CLAIM_AMT, CLAIM_BAL, ROWID, ORA_ROWSCN
from claim;

CLAIM_NUM CLAIM_AMT CLAIM_BAL ROWID ORA_ROWSCN
---------- ---------- ---------- ------------------ ----------
1 100 1 AAAdsYAAEAAAAD0AAA 1070257362
2 200 99 AAAdsYAAEAAAAD0AAB 1070257362
3 300 0 AAAdsYAAEAAAAD0AAC 1070257362
4 400 350 AAAdsYAAEAAAAD0AAD 1070257362
5 500 0 AAAdsYAAEAAAAD0AAE 1070257362
6 600 295 AAAdsYAAEAAAAD0AAF 1070257362
7 700 700 AAAdsYAAEAAAAD0AAG 1070257362
8 800 800 AAAdsYAAEAAAAD0AAH 1070257362

8 rows selected.

SQL> commit;

Commit complete.

SQL> select CLAIM_NUM, CLAIM_AMT, CLAIM_BAL, ROWID, ORA_ROWSCN
from claim;

CLAIM_NUM CLAIM_AMT CLAIM_BAL ROWID ORA_ROWSCN
---------- ---------- ---------- ------------------ ----------
1 100 1 AAAdsYAAEAAAAD0AAA 1201770241
2 200 99 AAAdsYAAEAAAAD0AAB 1201770241
3 300 0 AAAdsYAAEAAAAD0AAC 1201770241
4 400 350 AAAdsYAAEAAAAD0AAD 1201770241
5 500 0 AAAdsYAAEAAAAD0AAE 1201770241
6 600 295 AAAdsYAAEAAAAD0AAF 1201770241
7 700 700 AAAdsYAAEAAAAD0AAG 1201770241
8 800 800 AAAdsYAAEAAAAD0AAH 1201770241

8 rows selected.

SQL> create table claim_rowdep ROWDEPENDENCIES
as select * from claim;

Table created.

SQL> select CLAIM_NUM, CLAIM_AMT, CLAIM_BAL, ROWID, ORA_ROWSCN
from claim_rowdep;

CLAIM_NUM CLAIM_AMT CLAIM_BAL ROWID ORA_ROWSCN
---------- ---------- ---------- ------------------ ----------
1 100 1 AAAlQ9AAEAAAAIEAAA 1201772166
2 200 99 AAAlQ9AAEAAAAIEAAB 1201772166
3 300 0 AAAlQ9AAEAAAAIEAAC 1201772166
4 400 350 AAAlQ9AAEAAAAIEAAD 1201772166
5 500 0 AAAlQ9AAEAAAAIEAAE 1201772166
6 600 295 AAAlQ9AAEAAAAIEAAF 1201772166
7 700 700 AAAlQ9AAEAAAAIEAAG 1201772166
8 800 800 AAAlQ9AAEAAAAIEAAH 1201772166

8 rows selected.

SQL> update claim_rowdep set claim_bal = 0 where claim_num = 1;

1 row updated.

SQL> select CLAIM_NUM, CLAIM_AMT, CLAIM_BAL, ROWID, ORA_ROWSCN
from claim_rowdep;

CLAIM_NUM CLAIM_AMT CLAIM_BAL ROWID ORA_ROWSCN
---------- ---------- ---------- ------------------ ----------
1 100 0 AAAlQ9AAEAAAAIEAAA
2 200 99 AAAlQ9AAEAAAAIEAAB 1201772166
3 300 0 AAAlQ9AAEAAAAIEAAC 1201772166
4 400 350 AAAlQ9AAEAAAAIEAAD 1201772166
5 500 0 AAAlQ9AAEAAAAIEAAE 1201772166
6 600 295 AAAlQ9AAEAAAAIEAAF 1201772166
7 700 700 AAAlQ9AAEAAAAIEAAG 1201772166
8 800 800 AAAlQ9AAEAAAAIEAAH 1201772166

8 rows selected.

SQL> commit;

Commit complete.

SQL> select CLAIM_NUM, CLAIM_AMT, CLAIM_BAL, ROWID, ORA_ROWSCN
from claim_rowdep;

CLAIM_NUM CLAIM_AMT CLAIM_BAL ROWID ORA_ROWSCN
---------- ---------- ---------- ------------------ ----------
1 100 0 AAAlQ9AAEAAAAIEAAA 1201772868
2 200 99 AAAlQ9AAEAAAAIEAAB 1201772166
3 300 0 AAAlQ9AAEAAAAIEAAC 1201772166
4 400 350 AAAlQ9AAEAAAAIEAAD 1201772166
5 500 0 AAAlQ9AAEAAAAIEAAE 1201772166
6 600 295 AAAlQ9AAEAAAAIEAAF 1201772166
7 700 700 AAAlQ9AAEAAAAIEAAG 1201772166
8 800 800 AAAlQ9AAEAAAAIEAAH 1201772166

8 rows selected.


Come si vede dal ROWID i dati stanno tutti nello stesso blocco, mentre il ROWSCN cambia per tutto il blocco nella tabella claim e solo per la riga interessata dall'update nella tabella claim_rowdep.

Non è possibile aggiungere ROWDEPENDENCIES alla tabella già creata, bisogna farlo alla creazione: la clausola infatti comporta che ogni riga aumenti le proprie dimensioni di 6 bytes.

26 maggio 2008

Tornato da USA

Sono tornato domenica da una trasferta di lavoro in USA, per conoscere i miei nuovi colleghi d'oltreoceano e fare un po' di team-building con il mio omologo americano dell'azienda che abbiamo comprato.

Probabilmente per lavoro avrò a che fare, prima o poi, anche col mondo SQL Server, di cui ho visto qualche utilizzo. Per ora non so che cosa dire, il mondo dei wizard mi è sconosciuto, ma ammetto che la comodità di impostare ad esempio un backup solo con il mouse e con un'ottima interfaccia grafica non è trascurabile. Manca solo SQL Server per Linux :-)

Una giornata l'ho spesa a spiegare al mio collega USA come funziona RMAN, con una dimostrazione pratica di recovery. I suoi occhi brillavano, così come quando gli ho mostrato Data Pump con l'esportazione del "suo" database in 10 minuti, quando con export normale ci metteva 1 ora e mezza (ma non ho visto lo script che usava).

Mentre ero via è arrivato intanto il kit Oracle del certificato OCP 10g, con la tesserina e il diploma. Sono soddisfazioni, anche se preferirei avere anche una maglietta e un set di adesivi per la moto :-)

Oracle con una mail strana mi invita all'OpenWorld 2008 a S. Francisco. Ho qualche mese di tempo per convincere il mio capo della "necessità" della mia visita a S. Francisco, chissà forse in concomitanza con un altro viaggio in USA, ma si sa noi personaggi dell'IT non viaggiamo molto come i commerciali. Anzi praticamente non viaggiamo mai.

Una novità sulle certificazioni Oracle: Oracle Certification E-Magazine.
Le novità sono molteplici:
  • L'OCA 11g viene conseguita con 2 esami e non più uno come 10g
  • L'OCP 11g può essere conseguito come upgrade da 10g OCP ma anche da 9i OCP
  • C'è una nuova certificazione per il database: SQL certified expert

04 maggio 2008

Cost-based Oracle cap. 2: le statistiche di sistema

Sto leggendo il libro "Cost-based Oracle" di Jonathan Lewis.
Pensavo di dedicare un post ad ogni capitolo, ma non riesco a riportare tutte le cose interessanti che leggo; più realisticamente proverò a commentare i passi più importanti.

Oggi vi volevo parlare delle statistiche di sistema Oracle 10g. Non intendo le statistiche sugli oggetti di SYS e compari, e nemmeno le statistiche sulle fixed tables, ma su un gruppo di misure che l'optimizer può utilizzare per il suo lavoro.
Tra queste sono comprese la velocità della CPU, il tempo di lettura a singoli blocchi, il tempo di lettura multiblocco.
I valori ricavati dalle misure vengono inseriti nella tabella SYS.AUX_STATS$, che tra l'altro non ha sinonimi.

La tabella SYS.AUX_STATS$ si presenta più o meno così, dopo la creazione di un database:
SQL> select SNAME, PNAME, PVAL1 from sys.aux_stats$ where SNAME = 'SYSSTATS_MAIN';

SNAME PNAME PVAL1
------------------------------ ------------------------------ ----------
SYSSTATS_MAIN CPUSPEEDNW 1116.77078
SYSSTATS_MAIN IOSEEKTIM 10
SYSSTATS_MAIN IOTFRSPEED 4096
SYSSTATS_MAIN SREADTIM
SYSSTATS_MAIN MREADTIM
SYSSTATS_MAIN CPUSPEED
SYSSTATS_MAIN MBRC
SYSSTATS_MAIN MAXTHR
SYSSTATS_MAIN SLAVETHR

9 rows selected.

Si può notare come i valori di *READTIM e MAXTHR, tra i più interessanti, non siano valorizzati; inoltre i valori di IOSEEKTIM e IOTFRSPEED sono sempre uguali, anche per altri database non RAC.

Questa tabella viene popolata dalla procedura DBMS_STATS.GATHER_SYSTEM_STATS(). Può lavorare in due gathering_mode: NOWORKLOAD e a intervalli.
Nel primo caso la procedura misura le performance di I/O del sistema, determinando i valori di cpuspeednw, ioseektim, iotfrspeed.
Nel secondo caso si può far partire la misura con START e fermarla con STOP, scegliendo così un periodo di carico di lavoro tipico, altrimenti è possibile specificare INTERVAL con l'intervallo, misurato in minuti, trascorso il quale la misura viene terminata.

Alla fine delle misure l'aspetto potrebbe essere più o meno questo:
SQL> select SNAME, PNAME, PVAL1 from sys.aux_stats$ where SNAME = 'SYSSTATS_MAIN';

SNAME PNAME PVAL1
------------------------------ ------------------------------ ----------
SYSSTATS_MAIN CPUSPEEDNW 1606.781
SYSSTATS_MAIN IOSEEKTIM 7.469
SYSSTATS_MAIN IOTFRSPEED 52290.723
SYSSTATS_MAIN SREADTIM 5.912
SYSSTATS_MAIN MREADTIM 2.651
SYSSTATS_MAIN CPUSPEED 1614
SYSSTATS_MAIN MBRC 10
SYSSTATS_MAIN MAXTHR 105472
SYSSTATS_MAIN SLAVETHR

9 rows selected.


A che cosa serve tutto ciò? Le statistiche di sistema vengono utilizzate dal cost-based optimizer per determinare il miglior piano di esecuzione basandosi anche sul costo della CPU e della modalità di I/O (signolo blocco o multiblocco).

Manca ancora il costo di lettura dalla cache, ovvero la stima del costo basata sulla probabilità che un determinato blocco si ritrovi già in cache; ciò dipende soprattutto dalle statistiche derivabili da V$SEGSTAT, che misura l'attività relativa ai segmenti (dati e indici scritti su disco). Dovrò fare delle prove su 11g per vedere se ciò è stato implementato.

16 aprile 2008

Ruoli delle istanze nei cluster RAC

Continuiamo la serie dei post sul RAC a due nodi.

Stavolta mi è capitato di provare il parametro ACTIVE_INSTANCE_COUNT.

Con il RAC a due nodi è possibile specificare l'esistenza di una istanza primaria e di un'istanza secondaria.
Impostando il parametro ACTIVE_INSTANCE_COUNT a 1, solo nell'spfile, si impone che, al riavvio successivo del database, la prima istanza che monta il database diventi l'istanza primaria, mentre l'altra diventi ovviamente la secondaria.
Si può controllare lo stato delle istanze dalla colonna INSTANCE_ROLE di GV$INSTANCE, che assumerà i valori PRIMARY_INSTANCE e SECONDARY_INSTANCE.

Il risultato è che tutte le connessioni verranno dirette verso l'istanza primaria, mentre la seconda continuerà a rifiutare connessioni finché la prima istanza rimarrà attiva.

Anche i servizi RAC vengono avviati sull'istanza primaria, come se la secondaria fosse spenta.

Qual è il vantaggio? Non si trova molto sui manuali o su internet, comunque da questo articolo si deduce che il failover delle connessioni può essere più veloce.
Ho fatto una prova, ma personalmente non lo userei mai.

12 aprile 2008

1Z0-040: missione compiuta

Ieri ho aggiornato la mia certificazione Oracle OCP, passando l'esame 1Z0-040 e diventando OCP 10g.

L'esame non è dei più semplici per un paio di motivi: è meno popolare degli altri esami e deve concentrarsi sugli argomenti che costituiscono le novità della nuova release rispetto alla vecchia.
Il primo motivo ha come conseguenza che è più difficile reperire materiale di studio; il secondo che generalmente le domande riguardano aspetti minori del funzionamento del database, nonché poco interessanti e a volte addirittura noiosi.
Le domande a volte sono mal formulate, prestandosi a diverse interpretazioni, e a volte sembra che chi le ha formulate non aveva ben chiaro il concetto.
Come conseguenza di tutto ciò, mi sono trovato davanti a molte domande inaspettate ma, preso il toro per le corna, ragionando e sfruttando bene tutto il tempo a disposizione, ne sono uscito vincitore.

Per quanto riguarda il materiale di studio, mi sono affidato per la prima volta ad un testo Sybex che, sebbene più preciso dei testi Oracle Press per gli esami, latita dal punto di vista del software per la preparazione.
Il CD-ROM allegato al libro contiene una versione PC e una versione palmare delle esercitazioni. La prima è semplicemente in Flash, quindi fruibile con tutti i dispositivi dove ci sia un browser che supporti Flash, mentre sulla confezione del CD c'è scritto "per Windows". Misteri.

I testi Oracle Press, invece, avevano un software apposito per Windows, che comprensibilmente permetteva di fare di più rispetto a un'applicazione flash, sfruttando il fatto che poteva salvare su disco i risultati delle esercitazioni e indicare chiaramente quali fossero gli argomenti su cui insistere con lo studio, nonché mischiare le domande e le risposte per evitare che si memorizzassero meccanicamente.

La versione per palmare della Sybex è ancora più limitata di quella per PC, visto che si tratta solo di una serie di "schede" da compilare o a cui rispondere mentalmente, corredate da un tasto per far comparire la soluzione. Diciamo che si adattano al contesto in cui di solito viene usato il palmare, ovvero "on the road"; sono comunque un valido aiuto.

Ora pausa di qualche mese per finire i libri in coda, e poi chissà, ci sono molti esami interessanti da sostenere!

27 marzo 2008

OpenSuSE 10.3 x86_64: gli rpm per Oracle 10g

Tra tutte le installazioni Oracle 10g che ho fatto, escludendo Red Hat 4, mi sembra che la migliore distribuzione a cui appoggiarsi sia OpenSuSE 10.3.
L'unico problema che si potrebbe avere è nella versione a 32 bit, che probabilmente richiede la ricompilazione del kernel. Con le macchine attuali x86_64 il problema non si pone.

Riporto qui la lista degli rpm da installare oltre a quelli di default da DVD OpenSuSE 10.3 a 64 bit:

gcc-32bit-4.2-24.x86_64.rpm
gcc42-32bit-4.2.1_20070724-17.x86_64.rpm
glibc-32bit-2.6.1-18.x86_64.rpm
glibc-devel-32bit-2.6.1-18.x86_64.rpm
libgcc42-32bit-4.2.1_20070724-17.x86_64.rpm
libgomp42-32bit-4.2.1_20070724-17.x86_64.rpm
libmudflap42-32bit-4.2.1_20070724-17.x86_64.rpm


Nell'installazione grafica normale, alla selezione dei pacchetti da DVD, selezionare anche il Development e C/C++ development.
I pacchetti dell'elenco di sopra sono reperibili solo da repository web, quindi o si aggiunge l'URL del repository al SuSE online update, oppure si scaricano manualmente e si installano da linea di comando.
Vedere il sito SuSE per i mirror.

19 marzo 2008

RAC cluster interconnect: twisted!

Una delle "limitazioni" più famose delle implementazioni Oracle RAC a due nodi è l'impossibilità, secondo la documentazione, di utilizzare un'interconnect formata da un solo cavo diretto tra un server e l'altro.
Le FAQ di RAC riportano:
NO. CROSS OVER CABLES ARE NOT SUPPORTED.
The requirement is to use a switch:
Detailed Reasons:
1) cross-cabling limits the expansion of RAC to two nodes
2) cross-cabling is unstable:
a) Some NIC cards do not work properly with it. They are not able to negotiate the DTE/DCE clocking, and will thus not function. These NICS were made cheaper by assuming that the switch was going to have the clock. Unfortunately there is no way to know which NICs do not have that clock.
b) Media sense behaviour on various OS's (most notably Windows) will bring a NIC down when a cable is disconnected.
Either of these issues can lead to cluster instability and lead to ORA-29740 errors (node evictions).

Due to the benefits and stability provided by a switch, and their afforability ($200 for a simple 16 port GigE switch), and the expense and time related to dealing with issues when one does not exist, this is the only supported configuration.
Please see certify.us.oracle.com as well.

Vorrei però precisare quanto segue:
  1. Per gli switch moderni a 1 Gb i cavi "cross" sono equivalenti a quelli normali; a me risulta che siano equivalenti anche a 100 Mb (verificato sul mio router di casa).
  2. L'instabilità non è giustificata, a meno che si pensi ai SO Microsoft e ad eventuali versioni Linux che spengono la scheda di rete in caso di inattività prolungata o assenza di segnale all'altro capo in fase di avvio.
  3. Per il funzionamento effettivo del cross-link, basta provare e vedere se funziona
Aggiungiamo che le schede di rete recenti (es. e1000) hanno tutte le migliori caratteristiche desiderabili, e soprattutto possono essere configurate in bonding.

Gli scenari da confrontare sarebbero due:
  1. I 2 nodi collegati a uno switch
  2. I due nodi collegati tra loro
Gli oggetti che si possono rompere, nel caso del "sistema interconnect", sono:
  1. lo switch
  2. i due cavi di rete
  3. le quattro schede di rete
I cavi di rete di per sè sono molto poco propensi a rompersi, visto che strutturalmente sono molto semplici; eventualmente potrebbero essere soggetti a sollecitazioni meccaniche esterne. Sono due, quindi devono rompersi entrambi nello stesso periodo per dare problemi.
Le schede di rete hanno più o meno la stessa probabilità di rompersi di qualsiasi altro elemento attivo. Sono due per server, quindi la ridondanza abbassa di molto la probabilità di disservizio.
Lo switch è unico. Per avere una certa affidabilità e velocità bisogna acquistare qualcosa di più di "$200 for a simple 16 port GigE switch"; qualcosa di molto costoso rispetto ai server. Sta di fatto che è un elemento unico; se si vogliono due switch i costi raddoppiano.

Veniamo ora agli scenari problematici:
  1. Shutdown di una delle due istanze, più o meno volontario
  2. Reset o shutdown software di un server
  3. Spegnimento togliendo la corrente
Le istanze RAC comunicano via interconnect e voting disk. Un reset o uno spegnimento di un nodo sarebbe facilmente risolto dal voting-disk, in teoria. Tra le configurazioni con e senza switch di mezzo c'è una differenza: la mancanza di alimentazione a uno dei capi dell'interconnect, ad esempio per spegnimento di un server, provoca l'errore di link down.
Consideriamo solo il caso senza switch: gli scenari peggiori quindi sono l'interruzione totale e improvvisa dell'alimentazione per un nodo, e il distacco di entrambi i cavi di rete.
La prima possibilità è realistica, e provoca il link down. La seconda possibilità è, consentitemi, praticamente irrealizzabile.

Pensiamoci un attimo: la differenza col caso switch è che in mezzo c'è un altro componente che potenzialmente può dare problemi. La cosa migliore è quindi che lo switch non sia presente! Con un solo switch in mezzo, in caso di spegnimento dello switch stesso per qualsiasi motivo, si realizzerebbe la condizione per cui i nodi non si sentono più via interconnect, hanno un link down, e le istanze sono entrambe nello stesso stato: è la situazione di gran lunga peggiore: quella del distacco dei due cavi di rete dell'interconnect. La configurazione con i cavi diretti è quindi, a mio modo di vedere, addirittura migliore di quella consigliata da Oracle senza appello.

Rimane da provare l'interruzione improvvisa dell'alimentazione per un nodo.
L'ho provata.
In questo caso le istanze non sono nello stesso stato: una non c'è più.
Ecco ciò che succede all'altra istanza:
Tue Mar 11 15:01:42 2008
ospid 1179: network interface with IP address 192.168.1.107 no longer running (check cable)
Tue Mar 11 15:01:52 2008
Reconfiguration started (old inc 2, new inc 4)
List of nodes:
0
Global Resource Directory frozen
* dead instance detected - domain 0 invalid = TRUE
...

Il link down viene rilevato. Tutto prosegue regolarmente. In caso di dubbio Clusterware avrebbe riavviato la macchina. Quindi tutto bene.
Gli indirizzi IP VIP vengono correttamente riconfigurati.

Al ripristino del nodo in failure si ottiene:
Tue Mar 11 15:12:42 2008
ospid 1179: network interface with IP address 192.168.1.107 is now running
Tue Mar 11 15:15:12 2008
Reconfiguration started (old inc 4, new inc 6)
List of nodes:
0 1
Global Resource Directory frozen
Communication channels reestablished
Master broadcasted resource hash value bitmaps
Non-local Process blocks cleaned out
...

Ottimo: link up e riconfigurazione del cluster. Tutto regolare.

In sintesi, per un sistema RAC a due nodi non espandibile, a quanto sembra, è molto meglio avere un'interconnect a cavi diretti piuttosto che avere di mezzo un apparato di rete.

05 marzo 2008

Restore in ambiente RAC

Per lavoro ho dovuto spostare un database RAC di test da un volume ASM ad un altro. Tralasciando i motivi, ho deciso di effettuare un restore completo della parte dati ASM a partire da un backup RMAN con catalogo.
Noto alcune cose interessanti:
  • Nonostate il catalogo, bisogna sempre impostare il DBID prima di tutto
  • È necessario ricreare la directory base sotto +<DISKGROUP>
  • Se proprio non si ha il pfile creato a mano dall'spfile, si può usare lo startup force nomount da RMAN, per avere un minimo server process in modo da accedere ad ASM e fare il restore dell'spfile.
  • Il restore dall'autobackup è molto comodo: si recupera sia il controlfile che l'spfile (separatamente)
  • Il restore dell'spfile va fatto specificando il filename di destinazione nel diskgroup condiviso (TO '...')
Ho notato anche due difetti di Enterprise Manager db control una volta che il database RAC è tornato a funzionare: per prima cosa la configurazione interattiva con emca non funziona, almeno nel mio caso di ASM home separata. Bisogna per forza usare la linea di comando di emca ricavandola da uno degli script di creazione del database fatti da dbca (consiglio vivamente di far creare sempre gli script di creazione del database da dbca).
Secondo difetto: nelle pagine EM su ASM, lo spazio utilizzato dal database viene visto come "internal" (tipo archivelog) e non come spazio allocato da un database. Questo aspetto è tradizionalmente difettoso, almeno in RAC: i nomi dei database che utilizzano un dato diskgroup sono a volte solamente quelli di una delle due istanze; in questo caso, nemmeno quello.

25 febbraio 2008

Oracle 10.2.0.4.0/x86 is out

Un veloce post perché stamattina ho trovato il patchlevel 3 di 10gR2 su Metalink, solo per x86, e lo sto scaricando.
A presto per eventuali commenti.

Aggiornamento (10:33): a quanto pare è stato fatto il backport di Real Application Testing da 11g a 10g.

Aggiornamento (11:24): Enterprise Manager Database Control ora è di default via HTTPS!

Aggiornamento (10-3): risolto anche il problema della tabella ROUT troppo grande nel catalogo di RMAN.

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

26 dicembre 2007

Una buona azione a Natale

A Natale per me è arrivato il riposo tanto atteso e un pranzo un po' più abbondante del solito. Ma a rimanere tutto il giorno senza fare proprio nulla non ci riesco.

È ormai tradizione dedicare una parte della giornata ad un'installazione Oracle.
D'accordo, non sarà un'azione nobile come aiutare il prossimo, ma è una scusa per fare passare il tempo e un'occasione per imparare qualcosa di nuovo.

Per questo Natale ho aggiornato l'istanza Oracle sul mio Mac Mini. Come dovreste sapere, Oracle 10g si è fermato alla versione 10gR1 su Mac OS X. La versione originale è la 10.1.0.3.0, io l'ho aggiornata all'ultima disponibile, la 10.1.0.5.0; a quanto pare non ci saranno altri aggiornamenti.

DBUA non esiste, quindi bisogna aggiornare a mano il catalogo con catpatch.sql in "startup upgrade", e poi ricompilare gli oggetti invalidati dall'operazione di upgrade.

Tutto qui. Proseguiremo presto con altri post interessanti (a differenza di questo!).
Mi raccomando, sotto con i commenti, non fatevi pregare! :-)
E Buone Feste a tutti!

18 dicembre 2007

ASM su USB

Preso dagli acquisti natalizi (seee) ho ceduto all'offerta delle chiavette USB da parte di Carrefour a 8.90 € per 1 GB. Ne ho comprate 3, per provare almeno la redundancy HIGH oppure un disco spare. Non ho acquistato altro, tranne un paio di cuffie con microfono per Skype.

Ho inserito le tre chiavette in altrettante prese USB di quelle saldate sulla scheda madre, per ottenere un'alimentazione corretta.
Ho creato un volume ASM "DONKEYS" (da "dongle-keys") con ridondanza HIGH.
Come prima prova ho messo sul volume tre copie degli online-log dell'istanza 11g di prova.
Non è stato esaltante: 2 minuti e mezzo per creare ognuno dei logfile da 50 MB.

Ipotesi:
  1. Il protocollo di scambio dati tra scheda madre e USB è assai inefficiente

  2. La HIGH redundancy è un carico troppo elevato per le chiavette

  3. Tre chiavette assorbono troppa corrente dal bus USB


Ho creato i nuovi logfile su Oracle 11g, di cui sto lentamente provando il nuovo Enterprise Manager, in vista di una recensione.

09 dicembre 2007

oROCKole

"Ask Tom Live" European Tour 2008.

OK, pagherei per andare a sentire Tom Kyte, ma qui esagerano un po', e non è certo la prima volta. Evidentemente hanno piuttosto successo con queste iniziative.

Ma anche con altre: chi può resistere al fascino di tre gadget di questa levatura al solo costo di un corso?

Keep rockin'.

02 dicembre 2007

Orion e il mio PC

Orion è un tool per la valutazione della risposta dell'I/O di un server nell'ottica di utilizzo come database server, senza però dovere installare il motore del database e senza dovere predisporre i dati e le applicazioni di test.
Orion riesce a simulare l'I/O di Oracle perché utilizza le stesse librerie; può simulare sia un carico di lavoro a piccoli blocchi (8 KB), che a blocchi larghi (1 MB) sia sequenziali che casuali, o combinazioni dei due.
Il risultato dei test sono tre misure:
  1. Il throughput in MB/s

  2. Il numero di operazioni di I/O al secondo (IO/s)

  3. Il tempo medio di latenza (ms)


Stavolta mi gira di pubblicare le misure effettuate sul mio megaserver qui a casa, con i suoi "bei" dischi SATA2 e il sistema operativo a 64 bit (AMD64). Poi si sa, io sono un fisico e quando vedo delle misure non resisto.

Per prima cosa ho creato due logical volume da 10 GB con LVM su due dischi distinti, ma fisicamente uguali (Maxtor 250 GB SATA2). Ho dovuto usare l'eseguibile a 32 bit e non quello a 64 perché si lamentava dell'assenza di librerie strane. Non ho molta pazienza per queste cose quando il programma in questione non è null'altro che un file singolo eseguibile; d'altra parte la differenza 32-64 bit in questo caso potrebbe influenzare il risultato in qualche misura, come numero di operazioni a disco (più operazioni eseguite negli stessi cicli I/O) e quantità di dati trasferiti (il doppio dei dati con gli stessi cicli I/O); non penso però che in assoluto i valori massimi possano essere molto diversi. Vedremo in futuro, se possibile.

Ho quindi collegato a due raw device i due logical volume, e gli ho cambiato l'ownership per permettere al mio utente di poterci scrivere.

Ho configurato Orion come segue: 2 dischi, simulazione striping ASM, carico random.
I primo test è stato in sola lettura, mentre per il secondo ho impostato una scrittura al 50%.
I risultati sono abbastanza interessanti.

Un aiuto per leggere i grafici: Small e Large indicano il numero di processi concorrenti con letture/scritture di 8 KB (Small) e 1 MB (Large). Ho impostato Orion in modo che venissero fatte misure di processi concorrenti, presumendo che fosse il caso peggiore, altrimenti è possibile fare misure separate.

Prima prova: sola lettura
Ecco il throughput (MB/s):

Come si vede, all'aumentare dei processi small concorrenti, diminuisce il throughput, tendendo a un valore limite. Contemporaneamente, all'aumentare dei processi large, il throughput aumenta decisamente, ma solo grazie alla dimensione molto maggiore dei blocchi: si vede bene infatti che dopo il terzo processo concorrente il throughput cessa di salire all'improvviso (la differenza tra il grafico giallo e verde è piccola).

Traffico operazioni:

Facendo attenzione all'orientazione dell'asse dei blocchi large (cresce verso il lettore), qui si può notare come il numero di operazioni diminuisce all'aumentare dei blocchi large perché i dischi sono sempre più impegnati a leggere più blocchi large concorrenti; il numero aumenta invece all'aumentare dei processi small, ma dopo i 3 processi small concorrenti il trend di salita non è più molto significativo. Sembra che il limite di 3 processi sia una caratteristica del sistema.

Tempo medio di latenza:

Qui si nota come il tempo medio di latenza cresca quasi linearmente: si vede infatti che c'è una specie di plateau nell'intorno di 3 processi small concorrenti, specie con 4 processi large contemporanei.


Seconda prova: 50% scrittura
Throughput:

Questo grafico è molto simile a quello del caso in sola lettura. Non riesco a dedurre nulla di utile.

Traffico operazioni:

L'unica cosa notevole in questo grafico è che lo scalino nella crescita dell'IO/s rispetto al numero di processi è maggiormente evidente nel caso di processi large assenti. Il numero di processi limite (3) è ancora più determinante.

Tempo medio di latenza:

La latenza risulta maggiore nel caso lettura/scrittura in modo uniforme, tranne per il caso processi large, dove l'aumento è maggiore, probabilmente per l'"effetto soglia" sulla cache interna dei dischi (8 MB).

Il numero 3 dovrebbe essere una caratteristica dovuta ai gradi di libertà del sistema: il server ha due CPU (è un dual core), l'I/O è in striping su due dischi, quindi delle due l'una: o il sistema riesce a sopportare un processo in più di quello che gli è consentito dall'hardware, oppure uno in meno. In pratica i gradi di libertà dovrebbero essere quattro, considerando i possibili accoppiamenti CPU-disco (sto immaginando). Il limite deriverebbe secondo me dall'economicità dell'hardware, che in qualche fase dell'elaborazione ha un collo di bottiglia.

Spero di riuscire presto a fare qualche prova su hardware professionale come storage DAS SCSI320 o SAN; in tal caso proverò a fare una prova comparativa con i grafici.

29 novembre 2007

Oracle XE e Apache

Sto provando, a tempo perso, Oracle Application Express come framework per lo sviluppo rapido di applicazioni web. Lo scopo sarebbe di appoggiarsi su XE per piccole applicazioni web collaborative da utilizzare in gruppi limitati di persone, con tecnologia Oracle (gratuita).
Una delle prime cose che ho notato è che XE poggia direttamente sul db per quanto riguarda il protocollo HTTP, quindi non c'è Apache, ma risponde direttamente il listener.
La seconda cosa è che virtualmente il database è piuttosto lento nel rispondere alle chiamate da web, anche per un piccolo bacino di utenti; un buon indizio di ciò è anche che di default il listener risponde solo per localhost sulla porta 8080.

Un buon metodo per pubblicare l'interfaccia di XE con la flessibilità, la sicurezza e la velocità di un webserver è di utilizzare Apache come reverse proxy con il modulo mod_proxy.

Installate Apache a corredo della vostra distribuzione preferita, selezionando anche, se necessario, il modulo mod_proxy. Apache può fare da proxy per vari protocolli, in questo caso utilizziamo il proxy HTTP mod_proxy_http.

Configurate un VirtualHost di Apache. L'esempio è il seguente:
<VirtualHost *>
ServerName sbrillo2-xe
ServerAdmin your@email.address

<Proxy http://localhost:8080/*>
Order deny,allow
Allow from all
</Proxy>

ProxyPass / http://localhost:8080/
ProxyPassReverse / http://localhost:8080/
</VirtualHost>

In questo modo tutte le richieste mandate al server che risponde a sbrillo2-xe sulla porta 80 vengono automaticamente riindirizzate alla porta 8080 del loopback, con la possibilità ora di limitare gli accessi, impostare password HTTP, riscrivere gli URL.

C'è un ulteriore passo che si può fare: XE sarà comunque lento nelle risposte, visto che chi risponde non è sicuramente ottimizzato per servire pagine web. Possiamo utilizzare il modulo mem_cache, che sgrava il database da servire anche quegli oggetti statici che ogni pagina contiene. Aggiungete le seguenti righe nella vostra sezione del virtualhost:
<IfModule mod_mem_cache.c>
CacheEnable mem /
# 40 MB cache
MCacheSize 40960
MCacheMaxObjectCount 1000
MCacheMinObjectSize 1
# 20 KB max per oggetto
MCacheMaxObjectSize 20480
</IfModule>

modificando a piacere i valori di cache size, numero massimo di oggetti, dimensione massima degli oggetti da memorizzare, URL.

Ora la navigazione è molto più fluida e il vostro server è pronto per la pubblicazione su web. Nulla vi vieta, comunque, di usare reverse proxy come squid.
Da parte mia, servirebbe un po' di manualità nella programmazione.
Vi aggiornerò nel caso in cui riesca a mettere assieme una piccola applicazione.

25 novembre 2007

Modifica SPFILE in RAC

In ambiente cluster, per impostare il valore delle variabili nell'SPFILE per tutte le istanze, si usa la sintassi:
ALTER SYSTEM SET <parameter name>=<value> SCOPE=<scope> SID='*'
che ha effetto per tutte le istanze del cluster.

Ma, una volta assegnato il valore della variabile per tutte le istanze, come si fa a rimuovere il parametro per una sola istanza in caso di necessità?
Esiste una nuova estensione del comando ALTER SYSTEM:
ALTER SYSTEM RESET <parameter name> SCOPE=<scope> SID=<SID istanza>

20 novembre 2007

Multiplex controlfile con RAC e ASM

Avete creato un database RAC con ASM e vi siete trovati con un solo controlfile? Avete bisogno di duplicare il controlfile su più destinazioni o anche solo in posti diversi dello stesso storage?
Il problema maggiore è che ASM non è accessibile se non da un processo server di Oracle.

Ho elaborato un metodo molto efficace, che ho pubblicato sui forum Oracle.

Probabilmente al posto del punto 5 si può anche scrivere
restore controlfile from '+ASMDISK_DATA/prea/controlfile/current.256.636907509';
lasciando ad Oracle capire quali e quante sono le copie del controlfile da ripristinare, in quanto le conosce dal parametro control_files appena impostato.

19 novembre 2007

Oracle VM, prova 1

Ho provato ad installare Oracle VM su una coppia di server virtuali VMware :-), ma ho qualche difficoltà nell'installazione del server principale, che non riesce a vedere il resto della rete.
Qualche difficoltà ma alla fine tutto bene con il management server, basato su Enterprise Linux, OC4J e Oracle XE, tutto piuttosto automatico.

18 novembre 2007

Creazione RAC con script dbca

Ho avuto l'occasione di creare un database Oracle RAC senza poter usare dbca, ma avendo a disposizione degli script fatti creare a dbca in occasione della creazione del primo database di un cluster.
Infatti proprio lì stava il problema: volevo creare un database partendo da un nodo del cluster che non fosse il primo. Il problema era che dbca non riconosceva l'istanza ASM locale, forse perché installata su una home propria e nel contempo perché non era la prima.
L'installazione tramite gli script dbca avviene in modalità singola istanza; vengono solo aggiunte le cluster database views al catalogo, e i principali parametri di inizializzazione RAC. Alla fine degli script, però, ci si ritrova ancora un po' a largo, e serve qualche intervento manuale, riportato qui.
Gli interventi sui nodi diversi dal primo sono molto marginali: la modifica del pfile per farlo puntare all'spfile, la creazione delle directory *dump.

In pratica gli interventi finali, a database anche solo in nomount, consistono nella modifica di alcuni parametri (tra cui far diventare il database realmente in cluster con CLUSTER_DATABASE=TRUE), nella popolazione del tnsnames.ora per tutti i nodi del cluster (notare una delle poche applicazioni dei parametri *listener), e nella modifica dell'OCR per fargli riconoscere il nuovo database e le sue istanze.

Generalmente srvctl viene chiamato dai wizard come dbca durante le fasi di configurazione o installazione del database o dei servizi. Nel nostro caso (aggiunta di un database in cluster) Clusterware è piuttosto facile da configurare:
srvctl add database -d <name> -o <oracle_home>
A questo punto Clusterware vuole sapere solo quali sono le istanze associate:
srvctl add instance -d <name> -i <inst_name> -n <node_name>
Pochi parametri, quelli essenziali: il nome dell'istanza, a quale cluster è associata, e su quale nodo gira. Tutto qua.

14 novembre 2007

Old-style: Enterprise Manager Console

Siete anche voi dei fan della vecchia console di Enterprise Manager in Java?
Bene, prima di tutto, lo saprete già benissimo, non è sparita, ma è sempre presente nel client CD e nel companion CD: basta scaricarli e installarli.
Il funzionamento della console, però, sembra fermo alle funzionalità della release 9i. Nonostante ciò, a mio parere molte funzionalità sono sempre migliori di quelle riscritte in EM Database Control via web, incluso di default nella 10g. Il problema è che alcune di queste funzionalità hanno bisogno preferibilmente di un repository, ovvero di uno schema su un database Oracle, per salvare i propri dati.

Oggi ad esempio ho provato a configurare il Change Manager, che si basa sul repository di EM. Attenzione: il repository di EM versione Java è ancora quello della vecchia versione; non si tratta del nuovo repository di Enterprise Manager DB Control (10g).
Nell'help della Console c'è la sezione "Requirements before creating a standalone repository", in cui viene spiegato come creare il tablespace e l'utente per il repository. Le istruzioni funzionano anche per 10g, tranne per i permessi dell'utente/schema.

Per prima cosa bisogna creare il tablespace del repository, di circa 20M con un massimo di 2G, con un nome qualsiasi (io ho adottato OEM9REP). Probabilmente si può utilizzare SYSAUX, ma non vorrei che la presenza di segmenti "sconosciuti" nel tablespace possa dare fastidio al nuovo EM.
La "difficoltà" è nella creazione dell'utente: i privilegi/ruoli richiesti sono CONNECT, SELECT_CATALOG_ROLE, CREATE TRIGGER, CREATE PROCEDURE, EXECUTE ANY PROCEDURE, CREATE TYPE, EXECUTE ANY TYPE, SELECT ANY TABLE. C'è un problema: il ruolo CONNECT da 10gR2 in poi non ha gli stessi permessi che aveva nelle vecchie versioni; per la sola creazione del repository mancano i privilegi CREATE SESSION, CREATE TABLE, CREATE VIEW, CREATE SYNONYM, CREATE DATABASE LINK, CREATE CLUSTER, CREATE SEQUENCE, ALTER SESSION. Volendo si possono riassegnare al ruolo CONNECT mediante l'esecuzione dello script ?/rdbms/admin/rstrconn.sql.
Il repository viene creato dall'interfaccia grafica alla prima connessione; vengono eseguiti una serie di script sql presi dall'installazione del client locale.

13 novembre 2007

Oracle VM

A sorpresa, Oracle ha annunciato la sua versione della virtualizzazione del sistema operativo, basata su Xen.

Da domani si potrà già scaricare gratuitamente dal sito. Immagino che saranno in molti a provare questa nuova tecnologia, me compreso. Molti, però, che dovranno avere almeno due server "vuoti" a disposizione, come si legge nel data sheet. Praticamente due macchine virtuali VMware :-)

05 novembre 2007

Limiti della log history

Tsè, ho perso due ore per una bazzeccola: RMAN mi ha dato un errore sul backup degli archivelog perché non trovava il record corrispondente nel controlfile.
Credevo che ciò fosse dovuto al parametro MAXLOGHISTORY di creazione del controlfile; in realtà avevo aspettato troppo tra un backup e l'altro, più della recovery window, quindi Oracle aveva cancellato le entry troppo vecchie dal controlfile, quelle più vecchie di CONTROL_FILE_RECORD_KEEP_TIME (in giorni); tra l'altro l'avevo impostato io con la policy di RMAN!

MAXLOGHISTORY ha senso solo in RAC. Praticamente dà il numero di righe della tabella V$LOG_HISTORY.
Il numero di entry varia dinamicamente, adattandosi alle esigenze della receovery window.

25 ottobre 2007

DBCA non sente ASM

Ho installato (per lavoro) un nuovo RAC a due nodi, con una nuova politica di storage da provare.
Proprio durante la creazione del DB mi sono imbattuto in una specie di bug di dbca che avevo già trovato a casa, ma a cui non avevo dato peso, visto che non capita tutte le volte che si crea un database, e a me è capitato una sola volta.
Utilizzando il Database Configuration Assistant, nella pagina della scelta dello storage il programma non riconosce l'istanza ASM attiva sul cluster (ma càpita anche su single-instance), e chiede di riconfigurarla:
DBCA could not startup the ASM instance configured on this node. To proceed with the database creation using ASM, ASM instance needs to be up and running. Do you want to recreate ASM instance on this node?

È strano che non si trovi praticamente nulla su internet né su Metalink. Qualcosa ho trovato in un blog di un collega (click sul titolo del post), che però lascia senza una soluzione concreta.
Ebbene, la soluzione esiste.
Si trova sul manuale del corso Oracle RAC 10gR2, ma non riguarda questo errore, solo un invisibile prerequisito per eseguire dbca, che passerebbe inosservato a chiunque. Avevo scritto qualche nota a margine nel manuale sulla pagina in questione, ora capisco perché.

Soluzione: Si tratta di impostare le variabili d'ambiente Oracle da zero, partendo da un ambiente senza variabili Oracle definite, esclusivamente in questo modo (esempio):

export ORACLE_BASE=/u01/app/oracle
export ORACLE_SID=<SID del database da creare (NON di ASM)>
export ORACLE_HOME=/u01/app/oracle/product/10.2.0
export PATH=$PATH:$ORACLE_HOME/bin:$CRS_HOME/bin


Non serve null'altro! In questo modo funziona anche l'installazione con un'ORACLE_HOME separata per ASM.

Mi raccomando, se questo post vi è stato utile... almeno un piccolo commento!

(17-11) Aggiornamento: la procedura descritta non ha funzionato in occasione dell'aggiunta di un database RAC a un cluster esistente, su un nodo diverso dal primo. Nonostante le varie prove fatte, non sono riuscito a fare riconoscere l'istanza ASM a DBCA, anche se esistente e regolarmente funzionante.
Alla fine ho dovuto optare per la creazione del database mediante script, procedura per nulla automatica nel caso di RAC. Ma per questo ci sarà una blog-entry in seguito.

24 ottobre 2007

Nuovo RAC a 64 bit (2)

L'installazione di 10.2.0.1.0 è andata bene e il RAC era a posto.
I problemi sono arrivati dall'aggiornamento a 10.2.0.3.0. Subito si è ripresentato l'errore di scrittura su disco di VMware, quando il server virtuale tenta di allocare lo spazio sul disco reale in seguito alla crescita dell'occupazione del filesystem virtuale.
Quindi, regola generale:
Allocate SEMPRE PRIMA tutto lo spazio su disco necessario per tutto lo storage virtuale che intendete usare.
Fortunatamente questa regola è di facile applicazione con i dischi moderni da desktop, praticamente della dimensione minima di 500 GB, a poco più di 100 euro sul mercato.
Nel mio caso i problemi si avevano quando trasferivo gli zip di aggiornamento su un nodo e poi scompattavo gli archivi.

Per prima cosa ho aggiornato Clusterware. L'operazione è possibile in rolling-upgrade, ovvero spegnendo Clusterware solo su un sottoinsieme di nodi che si vogliono aggiornare in contemporanea; normalmente può essere gradito aggiornare un nodo del cluster alla volta; altrimenti si spegne tutto e buonanotte. Una particolarità è che, aggiornando solo il primo nodo, con i comandi crsctl per mostrare la versione, si può evidenziare come la versione che è installata è quella aggiornata (dopo l'upgrade), mentre la versione in esecuzione è quella vecchia, per via dei rimanenti nodi del cluster non ancora aggiornati.

In seguito ho aggiornato il database; quasi tutto regolare, a parte piccoli errori strani che non sono sicuro siano ricondicibili al database.

22 ottobre 2007

Nuovo RAC a 64 bit

Tramonta l'idea di mettere su un RAC con Solaris/64 su macchine virtuali. L'avventura con Solaris sembrava partita bene, invece al momento di aggiungere una scheda di rete in più e qualche hd virtuale in più, le macchine virtuali andavano in kernel panic (con dump relativo). Peccato, quando funzionavano erano molto veloci.

Bene, domenica ho resistito forzatamente alla voglia di uscire nonostante il freddo, e ho provato qualche novità per il mio megaserver a casa, in particolare con l'accoppiata 10gR2/64 - OpenSuSE/64 che è appena uscita in versione 10.3.
Ho aggiornato anche il kernel del mio megaserver, aggiungendo ai repository della SuSE anche quelli nVidia, così ad ogni aggiornamento del kernel i driver nVidia andranno a posto automaticamente :-)
VMware, con la nuova versione 1.0.4, sembra avere meno problemi. A proposito, consiglio di preallocare sempre i dischi virtuali di VMware, perché le operazioni di I/O pesante con estensione dei volumi non sono molto affidabili, a volte si bloccano (almeno sul mio megaserver).

OpenSuSE 10.3 sembra fatta apposta per fare andare Oracle. Stavolta (10.3) il tema è verdino. L'installatore presenta persino la possibilità di fare bonding delle schede di rete.
Prima avvertenza: controllate scrupolosamente tutti i prerequisiti software di Oracle! Ho perso lunghe ore a cercare di capire perché l'installazione non andava a buon fine anche se avevo risolto in modo corretto tutti i problemi di librerie. L'importante è avere i pacchetti richiesti prima di fare partire l'installer.

Stavolta ho usato ASM come storage condiviso: solite due schede di rete, 2 dischi per OCR e voting, e un disco per ASM.
Due trucchi molto interessanti:
  1. Se l'installer non parte con un errore Xlib.lock di Java, è colpa di SuSE che ha lasciato qualche errorino in giro; meno male che basta una variabile d'ambiente

  2. Per fare funzionare vipca e srvctl è necessario aggiungere la riga
    unset LD_ASSUME_KERNEL
    nei rispettivi script di avvio (loro stessi) con un editor di testo, appena dopo che la variabile viene impostata.

  3. Durante la partenza di vipca, alla fine della creazione del cluster, se non ci sono interfacce di rete "vip" già configurate, l'installer esce con un errore di "lista di interfacce". Un eccellente workaround è configurare a mano almeno un'interfaccia con oifcfg (leggere le istruzioni con l'help o il manuale). Dopo vipca parte senza problemi.

Ora è necessario un upgrade a 10.2.0.3.0. Sarà il mio primo upgrade di un cluster. O al massimo il secondo. A presto con le novità.

21 ottobre 2007

Oracle 11g/x86_64

È arrivata da un paio di giorni la nuova versione di 11g per x86_64.
Ovviamente non ho resistito e l'ho installata subito su OpenSuSE 10.2/64. Nessun problema, funziona alla grande.

Ho già preparato un lungo post sulle novità in fase di sperimentazione, anche se purtroppo non includono più Solaris. A presto anche per un'analisi più approfondita su 11g.

16 ottobre 2007

Se manca TEMP

Dopo un restore completo del database o una creazione di uno standby fisico mancano sempre i datafile dei tablespace temporanei.
Ammettiamo di avere un solo TEMP con un datafile, su uno standby. All'apertura del db l'alert_log darà un errore perché Oracle non trova il datafile temporaneo. È sufficiente crearlo, a database aperto (in read only nel caso dello standby):

SQL> ALTER TABLESPACE TEMP ADD TEMPFILE '<file name>' SIZE <n>M[G, ...];

Controllate poi che tutto sia a posto in V$TEMPFILE.

13 ottobre 2007

Da 64 a 32 bit (e viceversa)

Nei giorni scorsi ho dovuto affrontare un'emergenza: una macchina di produzione Itanium (IA64) ha smesso di funzionare per ragioni relative allo storage esterno. Rimaneva lo standby fisico a 32 bit, che comunque doveva andare presto in produzione al posto dell'IA64.

Pazienza, dopo avere applicato gli ultimi log all'istanza standby, ho cominciato la procedura di failover.
Subito ho avuto un piccolo problema per via della R1 del database 10g, che aveva una sintassi leggermente diversa per il failover manuale (grrr!), ma alla fine il role transition è andato bene.
Ma non tutto è andato per il verso giusto. Infatti, entrando come utente qualsiasi nel database, spuntava fuori l'errore:

ORA-06553: PLS-801: internal error [56319]
Error accessing package DBMS_APPLICATION_INFO


Suonava come un problema di dizionario dati. E infatti, a quanto si intuiva dalla documentazione, bisogna fare uso di ?/rdbms/admin/utlirp.sql, seguito da utlrp.sql, come si può leggere nelle istruzioni nell'header del file stesso (da seguire assolutamente).
Il dizionario è andato a posto e il db ha ricominciato a funzionare correttamente.