domenica 17 maggio 2009

Una nuova avventura

Nella vita, si sa, capita di porsi delle domande su quanto fatto fino ad un certo punto della propria esistenza, sia essa affettiva, lavorativa, ecc. Si tirano un pò le somme e questo è quanto è accaduto anche a me negli ultimi mesi, in particolare per quanto riguarda il mio lavoro.

Una premessa è d'obbligo: in questi due anni e mezzo di lavoro ho potuto collaborare con colleghi, soprattutto quelli del mio stesso ufficio, che mi hanno trattato bene, dal lato umano come da quello professionale, che mi hanno sopportato ogniqualvolta ho rotto le scatole con le mie guerre ideologiche Windows VS GNU/Linux ;), dai quali ho imparato molto (e ai quali spero di aver lasciato qualcosa, nel mio modestissimo piccolo bagaglio di conoscenze).

In secondo luogo, il mio attuale lavoro, sistemista e dba Oracle, mi piace molto e ho sempre cercato di portarlo avanti con passione, condividendo conoscenze con tanti altri appassionati del settore, il che mi ha molto aiutato a crescere professionalmente.

Tuttavia, forse per la giovane età (27 anni compiuti l'altro ieri ;), forse per la necessità di fare qualche nuova esperienza, di tagliare un pò il cordone ombelicale che ti lega alle comodità, alla famiglia, al lavoro attaccato a casa, ho cercato un'altra opportunità di lavoro, trovandola!
Come indicato molto chiaramente dall'immagine di apertura del post, una via si sta per chiudere, ossia la mia attività di dba Oracle e un'altra si apre al suo posto, il mio nuovo lavoro: sistemista GNU/Linux (hehehehehe).

Cambierà un pò tutto: dal pubblico passo al privato, da dba Oracle e sistemista generico, passo a sistemista GNU/Linux a tempo pieno, da Ferrara mi sposterò in quel di Casalecchio di Reno, dalla vita in casa con i miei, alla vita indipendente in appartamento (devo solo trovarlo ;) ) e chissà quante altre cose. Ma cavolo, se non lo faccio ora, ho come l'impressione che non lo farei mai più!!!

Insomma, questo è un pò il post conclusivo del mio blog che, comunque, ho deciso di non eliminare dato che contiene il frutto di due anni di lavoro con Oracle, di smanettamenti, di ore passate su siti, forum, mailing list per cercare (e qualche volta dare) soluzioni ai problemi che ogni giorno si presentano nella vita di un dba!

Un saluto a tutti! Simone

martedì 28 aprile 2009

Ubuntu e Oracle SQL Developer

Qualche giorno fa, stanco delle continue infezioni di Conficker e forte del fatto che il mio pc è una semplice workstation dalla quale mi collego sulle macchine vere e proprie con cui lavoro (un misto di ambienti Windows Server 2003 e GNU/Linux, reali e virtualizzati), ho pensato di formattare il mio pc che montava Windows XP per passare ad Ubuntu 8.10.

Uno strumento che uso ormai da qualche tempo e che mi dà le stesse soddisfazioni di Toad (ma in più è free e non richiede licenze) è Oracle SQL Developer. Questo software è realizzato in Java quindi è disponibile per diverse piattaforme, tra cui GNU/Linux, anche se non esiste un pacchetto deb per le distribuzioni Debian e Debian like. Volendo è possibile usufruire del tool Alien per convertire l'rpm in deb, oppure si può sempre scaricare un file zip contenente l'intero ambiente già pronto per l'uso.

La versione per GNU/Linux non viene fornita con il Java SDK, necessario per far girare l'interfaccia di SQL Developer, ma con Ubuntu 8.10, ad esempio, si può facilmente porre rimedio alla mancanza con:
$ sudo aptitude install sun-java6-jdk

Supponendo di voler utilizzare il file zip fornito da Oracle, lo si può scompattare, ad esempio, in /usr/src/:
$ tar xzf sqldeveloper-1.5.4.59.40-no-jre.zip
$ sudo mv sqldeveloper /usr/src/

Lo script da lanciare è contenuto in /usr/src/sqldeveloper (il path è da adattare a seconda della directory di installazione scelta):
$ cd /usr/src/sqldeveloper
$ ./sqldeveloper.sh

Tuttavia, si può notare la comparsa sul terminale di un messaggio di errore:
Oracle SQL Developer
Copyright (c) 2008, Oracle. All rights reserved.

Type the full pathname of a J2SE installation (or Ctrl-C to quit), the path will be stored in ~/.sqldeveloper/jdk

In questo caso, bisogna terminare la creazione dello script con Ctrl-C, quindi creare una directory chiamata .sqldeveloper (attenzione al punto prima del nome, in quanto si tratta di una directory nascosta) nella propria home e all'interno di tale directory creare un file chiamato jdk. Tale file deve contenere il path alla jvm quindi:
$ mkdir /home/username/.sqldeveloper
$ cd ~/.sqldeveloper
$ touch jdk
$ echo /usr/lib/jvm/java-6-sun > jdk

Fatto ciò si può avviare SQL Developer in tutta tranquillità!

Windows Vista e SP2-1503

Un mio collega ha appena acquistato il classico portatile con Microsoft Windows Vista Home Premium SP1 (eh vabbè...) e, dato che la sua attività routa attorno alla creazione di web apps che si interfacciano ad Oracle, ha provato ad installare, sul suddetto portatile, Oracle Instant Client 10.2.0.1. Ha seguito la procedura standard, optando per un'installazione da amministratore, impostato il tnsnames.ora con le entries corrette, eppure, lanciando un prompt di sqlplus, oppure Toad, ecc, si presenta il seguente errore:



Sul forum di OTN si consiglia di:

1) impostare correttamente le variabili d'ambiente ORACLE_HOME, TNS_ADMIN, LD_LIBRARY_PATH e PATH
2) controllare le impostazioni di protezione di Windows in quanto mancherebbe il permesso "create global objects"

Ora, la soluzione numero 1 non ha funzionato e, a quanto pare, in Windows Vista Home Premium SP1 non c'è la possibilità, o almeno io non l'ho trovata, di accedere alle policies locali di sicurezza, quindi non ho potuto verificare l'effettiva mancanza del privilegio "create global objects" per il mio utente.

San Google, come al solito, è venuto in mio aiuto con questo articolo di Christian Shay in cui l'autore indica che per Windows Vista è disponibile un pacchetto che consente di installare Oracle Client 10.2.0.3 direttamente, ossia senza la necessità, come avveniva in precedenza, di installare il client nella versione 10.2.0.1 per poi patcharla alla 10.2.0.3 che, di fatto, risolve il problema SP2-1503.
Riporto a mia volta il link per il download del client Oracle versione 10.2.0.3 per Windows Vista/windows 2008!

Installato questo pacchetto tutto è filato liscio, finchè non ho tentato una connessione al mio db di test con TOAD ritrovandomi con il seguente errore (bello Vista, sì sì):



Altra ricerca con Google ed approdo sul sito asktoad.com e più precisamente in questa FAQ; qui si legge che il problema è determinato da UAC: User Access Control, ossia il sistema di controllo degli accessi degli utenti di Windows Vista che, quando abilitato (e lo è per default), non consente ad un utente normale di accedere in scrittura alla directory Program Files. Sempre dalla FAQ si legge che quando Toad 9.5 viene installato crea un file chiamato lexlib.new che, nel momento in cui si lancia la GUI di Toad dovrebbe poter essere rinominato in lexlib.lxl, fatto non consentito proprio da UAC (a meno di eseguire Toad come utente Administrator).

Esistono due soluzioni:

* disabilitare UAC, ad esempio come indicato in questa guida
* eseguire Toad come utente amministratore

Io ho optato per la prima opzione, che è molto semplice da implementare!

giovedì 2 aprile 2009

Startup e shutdown

L'avvio e lo spegnimento di Oracle sono due procedure importanti che è necessario saper eseguire in modo corretto per garantire il funzionamento del DBMS stesso, nonchè l'integrità dei dati gestiti tramite esso.

I servizi (demoni in ambito GNU/Linux) da avviare prima di poter interagire con Oracle sono il listener e una o più istanze.
Con Microsoft Windows, i servizi a cui fare riferimento sono:

* OracleServiceSID: il servizio di bootstrap di oracle che permette l'avvio dell'istanza indicata dalla stringa "SID". Una volta avviato il servizio OracleServiceSID è possibile avviare/stoppare manualmente l'istanza
* OracleHOME_NAMETNSListener: è il servizio che si occupa di controllare il listener Oracle

Agli amministratori di Oracle su sistemi Microsoft Window consiglio di dare un'occhiata a questa descrizione (in inglese, ma molto chiara) dettagliata e completa dei servizi Oracle, delle variabili d'ambiente che è necessario impostare e delle chiavi di registro fondamentali per Oracle!

Se si predilige il sistema operativo GNU/Linux (come nel mio caso ;), Oracle mette a disposizione il comando "lsnrctl" per la gestione del listener e lo script "dbstart" per l'avvio di una o più istanze. Entrambi si trovano nella directory "$ORACLE_HOME/bin".
Al fine di automatizzare startup e shutdown di Oracle (listener + istanza/e, quindi), io utilizzo questo semplice script trovato in rete e che ho chiamato "gestoracle.sh":
#!/bin/bash
#
# Run-level Startup script for the Oracle Instance and Listener
#
# chkconfig: 345 91 19
# description: Startup/Shutdown Oracle listener and instance


#ORA_OWNR="oracle"

# if the executables do not exist -- display error

if [ ! -f $OH/bin/dbstart -o ! -d $OH ]
then
echo "Oracle startup: cannot start"
exit 1
fi

# depending on parameter -- startup, shutdown, restart
# of the instance and listener or usage display

case "$1" in
start)
# Oracle listener and instance startup
echo -n "Starting Oracle: "
$OH/bin/lsnrctl start
$OH/bin/dbstart $ORACLE_HOME
echo "OK"
;;
stop)
# Oracle listener and instance shutdown
echo -n "Shutdown Oracle: "
$OH/bin/lsnrctl stop
$OH/bin/dbshut $ORACLE_HOME
echo "OK"
;;
reload|restart)
$0 stop
$0 start
;;
*)
echo "Usage: $0 start|stop|restart|reload"
exit 1
esac
exit 0

Per lanciare lo script è sufficiente loggarsi sul db server con un utente appartenente al gruppo dba ed eseguire da command line:
$ ./gestoracle.sh start|stop|restart|reload

A seconda del parametro passato, gestoracle.sh avvia o stoppa il listener e lo script di gestione del'istanza da avviare.
Il risultato dell'esecuzione di gestoracle.sh è questo:
oracle@debiandb:~$ gestoracle.sh start
Starting Oracle:
LSNRCTL for Linux: Version 10.2.0.4.0 - Production on 02-APR-2009 08:58:14

Copyright (c) 1991, 2007, Oracle. All rights reserved.

Avvio di /u01/app/oracle/product/10.2.0/db_1/bin/tnslsnr: attendere...

TNSLSNR for Linux: Version 10.2.0.4.0 - Production
Il file dei parametri di sistema è /u01/app/oracle/product/10.2.0/db_1/network/
admin/listener.ora
Messaggi di log registrati in /u01/app/oracle/product/10.2.0/db_1/
network/log/listener.log
Ascolto su: (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1)))
Ascolto su: (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=debiandb)(PORT=1521)))

Connessione a (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC1)))
STATO del LISTENER
------------------------
Alias LISTENER
Versione TNSLSNR for Linux: Version 10.2.0.4.0 - Production
Data di inizio 02-APR-2009 08:58:14
Tempo di attività 0 giorni 0 ore 0 min. 0 sec.
Livello trace off
Sicurezza ON: Local OS Authentication
SNMP OFF
File di parametri listener/u01/app/oracle/product/10.2.0/db_1/network/admin/
listener.ora
File di log listener /u01/app/oracle/product/10.2.0/db_1/network/log/
listener.log
Summary table degli endpoint di ascolto...
(DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1)))
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=debiandb)(PORT=1521)))
Summary table dei servizi...
Il servizio "PLSExtProc" ha 1 istanze.
L'istanza "PLSExtProc", stato UNKNOWN, ha 1 handler per questo servizio...
Il comando è stato eseguito
OK

Ora che il DBMS è attivo è possibile avviare l'istanza desiderata (assicurarsi sempre che la variabile di sistema ORACLE_SID sia correttamente impostata):
oracle@debiandb:~$ export ORACLE_SID=TEST
oracle@debiandb:~$ sqlplus /nolog

SQL*Plus: Release 10.2.0.4.0 - Production on Gio Apr 2 08:58:39 2009
Copyright (c) 1982, 2007, Oracle. All Rights Reserved.

SQL> conn/as sysdba
Connesso a un'istanza sospesa.

SQL> startup
Istanza ORACLE avviata.

Total System Global Area 1174405120 bytes
Fixed Size 1267116 bytes
Variable Size 620759636 bytes
Database Buffers 536870912 bytes
Redo Buffers 15507456 bytes
MOUNT del database eseguito.
Database aperto

La procedura di "apertura" di un database è composta da più livelli:

* LIVELLO 0 - database chiuso: l'istanza è spenta e gli utenti non possono eseguire login, accedere ai dati contenuti nel db, ecc.
* LIVELLO 1 - NOMOUNT: lanciando il comando
SQL> startup nomount
Oracle legge il contenuto del spfile che contiene le informazioni essenziali per l'avvio dell'istanza specificata dalla variabile di sistema ORACLE_SID (ad esempio, la dimensione delle varie aree di memoria RAM da riservare all'istanza, la dimensione dei blocchi di dati, il character set, ecc), quindi avviene l'avvio dell'istanza mediante allocazione di una certa quantità di memoria RAM e l'avvio dei background processes.
Il database non è ancora accessibile per gli utenti.
* LIVELLO 2 - MOUNT: raggiungibile dal livello 0 con il comando:
SQL> startup mount
oppure dal livello 1 con il comando
SQL> alter database mount;

In questo livello Oracle legge il contenuto del/i control file, la cui posizione su file system è indicata nel spfile, per determinare la posizione, sempre su file system, dei datafile di cui, tuttavia, non viene eseguita l'apertura.
* LIVELLO 3 - OPEN: lo stato di database aperto può essere raggiunto dal livello 0 direttamente con il comando
SQL> startup
oppure dai livelli 1 e 2 con il comando
SQL> alter database open

Oracle monta in sola lettura, o in lettura/scrittura i datafile, quindi i dati contenuti nel db diventano accessibili per gli utenti.

Come al solito, potete liberamente scaricare l'immagine di inizio post in quanto rilasciata con licenza Creative Commons Attribution-Noncommercial 2.0 Generic ;)

giovedì 26 marzo 2009

ORA-01940: Cannot drop a user that is currently connected

E' un pò di tempo che non scrivo sul mio blog, ma, ahimè, in questo periodo il lavoro con Oracle ha latitato e, di conseguenza, anche gli spunti da cui traggo i miei post :(
Questa mattina, tuttavia, una semplice operazione di DROP di un utente del mio db di test ha originato l'errore Oracle ORA-01940: cannot DROP a user that is currently connected
Premessa: lo schema di cui sopra costituisce il backend di un'applicazione web-based realizzata in jsp e gestita da Tomcat. Ovviamente, prima di eseguire, da utente system, la drop dello schema desiderato, mi sono preoccupato di avvertire gli utenti che stavano lavorando nell'ambiente di test di effetturare il logout, quindi, atteso un ragionevole lasso di tempo, ho stoppato il server Tomcat.
Svolgimento: ho pensato che eventuali sessioni appese a livello di db dovessero dipendere dalla presenza di qualche utente ancora connesso e con delle operazioni in corso nell'ambiente di test nel momento in cui ho eseguito lo stop del server Tomcat.

La vista v$session fornisce tutte le informazioni sulle sessioni attive/inattive/killate ed è proprio da questa che bisogna partire per fare un pò di diagnostica.
L'istruzione SELECT seguente interroga proprio tale vista in join con un'altra vista di sistema, ossia v$process in modo tale da ottenere l'id della, il codice seriale e lo status sessione, nonchè il pid del processo ad essa collegato.
SQL> select s.sid, s.serial#, s.status, p.spid
from v$session s, v$process p
where s.username = 'MYUSER'
and p.addr (+) = s.paddr;

Il risultato che si ottiene è qualcosa di simile:
SID SERIAL# STATUS SPID
---------- ---------- -----------------
136 48808 INACTIVE 12065
135 31595 INACTIVE 12030
132 12779 INACTIVE 11092

Ora, le sessioni inattive possono essere terminate con il seguente comando (da ripetere per ogni sessione da terminare, ovviamente e da lanciare in qualità di utente con privilegi da DBA):
SQL> alter system kill session '<#sid,#serial>';

Rieseguendo la query dalla vista v$session si otterrà che le sessioni sono passate allo stato "KILLED", tuttavia, come è successo a me, può capitare che dopo pochi istanti nuove sessioni (o persino le stesse appena killate) tornino nuovamente allo stato "INACTIVE" rendendo nuovamente impossibile eseguire il drop dell'utente.
Personalmente credo che Oracle cerchi di portare a termine i job sottomessi da Tomcat sul db server e incapsulati nelle sessioni di cui sopra, ma avendo ormai perso la connessione con il Tomcat, tali sessioni restano sempre nello stato "INACTIVE".
La soluzione in realtà è semplice, infatti basta mettere in lock l'utente prima di dropparne le sessioni inattive:
SQL> alter user MYUSER account lock;

Quindi si può procedere con il drop dell'utente in tutta tranquillità!

Conclusione: partendo dalle viste di sistema si risolve tutto! ;)

L'immagine di inizio post con i nanetti da giardino l'ho recuperata da qui ed è rilasciata con licenza Creative Commons Attribution-No Derivative Works 2.0 Generic (quindi è possibile copiarla e distribuirla). L'ho messa perchè uno dei nani ha degli occhiali da sole --> servono per vedere --> viste di Oracle --> sclero :-D

venerdì 13 febbraio 2009

Archivelog mode e nu metal

In quanto appassionato di Oracle e di musica metal (soprattutto nelle sue varianti nu ed heavy), quando ho visto questo video ho pensato di riproporlo!



Il video spiega come mettere un db Oracle 10g in archivelog mode e come sottofondo sonoro propone i mitici System Of A Down.
Per completezza, vi rimando all'ottimo blog dell'autore del video ed alla sua pagina personale su Youtube con altri video interessanti su Oracle.

Buona visione e buon ascolto!

martedì 3 febbraio 2009

Oracle Streams

Qualche giorno fa, incuriosito dalla lettura di un post di Chen Shapira, ho iniziato a studiare e a fare qualche prova con Oracle Streams, una tecnologia che permette la propagazione e la gestione di dati, transazioni ed eventi nell'ambito di un database, oppure tra un database sorgente ed uno di destinazione.

In sostanza, Oracle Streams consente di replicare uno schema presente su un db sorgente in un db di destinazione, inoltre, ogni istruzione DDL, oppure DML eseguita nell'ambito dello schema da replicare presente sul db sorgente verrà eseguita anche sullo schema replicato presente nel db di destinazione.
Su databases OLTP, il processo di estrazione dei dati non può essere eseguito direttamente poichè interferirebbe con le normali istruzioni DDL/DML, perciò l'architettura Oracle Streams utilizza gli archivelog, decisamente mento intrusivi.
Prima di poter utilizzare uno stream Oracle, è necessario assicurarsi che siano soddisfatti alcuni prerequisiti:

1) configurare opportunamente i due db server in modo tale che sia possibile eseguire tnsping dal db server sorgente a quello di destinazione e viceversa
2) porre in ARCHIVELOG MODE entrambi i database
3) creare un utente per la gestione dello stream Oracle ad entrambi i database
4) creare un db link per la creazione iniziale, da eseguire solo la prima volta, dello schema replica sul db di destinazione mediante le utilities di data pump
5) creare un db link dal db di destinazione a quello sorgente, utile nel caso in cui la creazione iniziale dello schema replica avvenga a livello di rete senza servirsi di un file dmp intermedio (io ho creato anche questo db link in ogni caso)
6) configurazione delle utilities expdp ed impdp sia sul database sorgente sia su qyello di destinazione
7) creare una directory Oracle e una corrispondente directory sul file system del db server sorgente per ospitare lo script generato dalla procedura DBMS_STREAMS_ADM.MAINTAIN_SCHEMAS che si occupa della replica dello schema via stream Oracle.

Supponendo, per comodità che i punti 1) e 2) siano già soddisfatti, parto direttamente dal punto 3). D'ora in poi, la sigla "PROD" identifica il database sorgente e la sigla "TEST" identifica quello di destinazione. Lo schema da replicare sarà l'onnipresente "SCOTT"!

1) OK
2) OK
3) creiamo un utente dedicato alla gestione dello stream, sia su PROD sia su TEST, connettendoci come utente SYS as SYSDBA:
CREATE TABLESPACE streams_tbs DATAFILE '/u01/app/oracle/oradata/streams_tbs.dbf' SIZE 25M;

CREATE USER strmadmin
IDENTIFIED BY strmadminpw
DEFAULT TABLESPACE streams_tbs
QUOTA UNLIMITED ON streams_tbs;

GRANT DBA TO strmadmin;

BEGIN
DBMS_STREAMS_AUTH.GRANT_ADMIN_PRIVILEGE(
grantee => 'strmadmin',
grant_privileges => true);
END;

4) impostiamo un db link da PROD a TEST per l'importazione iniziale dello schema da replicare:
-- su PROD
connect strmadmin/strmadminpw@PROD

CREATE DATABASE LINK TEST
CONNECT TO STRMADMIN
IDENTIFIED BY STRMADMINPW
USING 'TEST';

5) ora creiamo anche un db link da TEST a PROD:
-- su TEST
connect strmadmin/strmadminpw@TEST

CREATE DATABASE LINK PROD
CONNECT TO STRMADMIN
IDENTIFIED BY STRMADMINPW
USING 'PROD';

6) configuriamo le utilities di data pump sui due db server mediante la creazione di una directory Oracle chiamata "source" sul db server che ospita PROD e di una directory Oracle chiamata "dest" sul db server che ospita TEST. Le due directories a livello di sistema operativo vanno create con gli appositi comandi del sistema operativo in uso (mkdir, per GNU/Linux):
-- su PROD
conn sys@PROD as sysdba
CREATE OR REPLACE DIRECTORY source AS '/u01/app/oracle/oradata/source';
GRANT READ, WRITE ON DIRECTORY source TO strmadmin;

-- su TEST
conn sys@TEST as sysdba
CREATE OR REPLACE DIRECTORY dest AS '/u01/app/oracle/oradata/dest';
GRANT READ, WRITE ON DIRECTORY dest TO strmadmin;

7) creiamo una directory Oracle e una corrispondente directory sul file system del db server che ospita il database PROD. Questa directory conterrà lo script da eseguire per la replica dello schema SCOTT da PROD a TEST via stream Oracle:
CONNECT strmadmin/strmadminpw@PROD
CREATE OR REPLACE DIRECTORY SCRIPT_DIR AS '/home/oracle/script_dir';

Una volta soddisfatti tutti i requisiti, sul db server che ospita PROD mi sono creato uno script da lanciare come utente strmadmin con il seguente contenuto:
DBMS_STREAMS_ADM.MAINTAIN_SCHEMAS(
schema_names => 'scott',
source_database => 'prod',
destination_database => 'test',
capture_name => 'capture_scott',
capture_queue_table => 'rep_capture_queue_table',
capture_queue_name => 'rep_capture_queue',
capture_queue_user => null,
apply_name => 'apply_scott',
apply_queue_table => 'rep_dest_queue_table',
apply_queue_name => 'rep_dest_queue',
apply_queue_user => null,
propagation_name => 'prop_scott',
log_file => 'exp_scott.log',
bi_directional => false,
include_ddl => true,
instantiation => dbms_streams_adm.instantiation_schema,
perform_actions => false,
script_name => 'schema_replication.sql',
script_directory_object => 'script_dir'
);
END;

Direi che è d'obbligo una spiegazione dei parametri fondamentali impostati, altrimenti non si capisce molto:

* schema_names: il nome dello schema (o degli schemi, separati da virgole) da propagare (in questo caso scott)
* source_database: il database sorgente
* destination_database: il database di destinazione
* capture_name: il nome del processo di cattura configurato per acquisire le modifiche effettuate su PROD
* capture_queue_table: il nome della tabella di accodamento per ogni coda utilizzata da un processo di cattura
* capture_queue_name: il nome di ogni coda utilizzata da un processo di cattura
* capture_queue_user: va impostato a null per indicare che la procedura non può dare il grant di alcun privilegio
* propagation_name: il nome di ciascuna propagazione configurata per propagare le modifiche
* log_file: il nome del file di log generato da expdp
* bi_directional: se impostato a 'false' indica che la propagazione dele informazioni è monodirezionale dal db di produzione a quello di test
* include_dll: impostato a 'true' indica che sia le istruzioni DDL sia quelle DML vanno replicate dal db sorgente a quello di destinazione
* instantiation: se impostato a DBMS_STREAMS_ADM.INSTANTIATION_SCHEMA indica che l'istanziazione dello schema di destinazione verrà effettuata utilizzando le utilities expdp/impdp
* perform_action: se impostato a 'true' consente l'esecuzione dello script PL/SQL, se impostato a 'false' ne memorizza il risultato in un ulteriore script che verrà posizionato nella directory indicata dal parametro 'script_directory_object'
* script_name: impostato con la stringa 'schema_replication.sql'. Questo script verrà creato nella directory Oracle 'script_dir' (/home/oracle/script_dir) e conterrà tutti i passaggi per istanziare lo schema di replica
* script_directory_object: la directory Oracle in cui memorizzare lo script 'schema_replication.sql'

Lanciando lo script non viene avviato lo stream Oracle, quindi nemmeno il processo di replica dell'utente SCOTT sul db TEST, ma viene creato lo script schema_replication.sql nella directory /home/oracle/script_dir che andrà eseguito a parte sempre come utente strmadmin@PROD.
La creazione dello script intermedio consente di verificare se non vi sono stati errori durante l'esecuzione della procedura DBMS_STREAMS_ADM.INSTANTIATION_SCHEMA; in alternativa, è sempre possibile saltare la creazione dello script intermedio e lanciare direttamente la procedura DBMS_STREAMS_ADM.INSTANTIATION_SCHEMA con questi parametri:
DBMS_STREAMS_ADM.MAINTAIN_SCHEMAS(
schema_names => 'scott',
source_database => 'prod',
destination_database => 'test',
capture_name => 'capture_scott',
capture_queue_table => 'rep_capture_queue_table',
capture_queue_name => 'rep_capture_queue',
capture_queue_user => null,
apply_name => 'apply_scott',
apply_queue_table => 'rep_dest_queue_table',
apply_queue_name => 'rep_dest_queue',
apply_queue_user => null,
propagation_name => 'prop_scott',
log_file => 'exp_scott.log',
bi_directional => false,
include_ddl => true,
instantiation => dbms_streams_adm.instantiation_schema,
perform_actions => true
);
END;

Da notare che la direttiva "perform_actions" ora è impostata a true e non sono presenti le direttive "script_name" e "script_directory_object".
Se tutto funziona correttamente, sul db TEST sarà presente una replica esatta dello schema SCOTT del db PROD; ora non resta che testare se una qualsiasi istruzione DDL/DML eseguita sullo schema SCOTT@PROD viene replicata anche su SCOTT@TEST.
Buona replica!!!

Ah, lascio qualche utile link per approfondire l'argomento:
* http://www.dba-oracle.com/t_streams_schema_replication.htm
* http://ca.geocities.com/mosicr@rogers.com/OracleStreams101.htm
* http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14258/d_strm_a.htm#ARPLS305