mercoledì 10 giugno 2015

Oracle e dba_segments

Oggi ho dovuto recuperare i dati necessari a creare i tablespace per la migrazione di diversi DB Oracle sotto un'unica istanza.
Per capire quali tablespace erano utilizzati dagli utenti oggetto di migrazione ho utilizzato la tabella dba_segments con la seguente query
SELECT owner, segment_type, tablespace_name , count(*)
FROM dba_segments 
GROUP BY owner, segment_type, tablespace_name 
ORDER BT owner
che mi ha dato evidenza di dove gli oggetti dei vari utenti erano.
Con l'utilizzo poi di dba_data_files ho estratto i data file associati.

giovedì 26 febbraio 2015

Creare un utente con i relativi tablespace in Oracle

Negli ultimi due giorni mi sono cimentato con manipolazione di datafile, tablespace e utenti su Oracle 11gR2.
Prima di iniziare è sempre utile verificare quali datafile e tablespace sono presenti sul sistema andando a interrogare le tabelle DBA_TABLESPACES, DBA_DATA_FILES, , DBA_TEMP_FILES.
Se non ci sono tablespace adatti ad ospitare lo schema per l'utente che si intende creare è necessario predisporre un nuovo tablespace con relativo datafile:

CREATE TABLESPACE <TBS_NAME> DATAFILE '<DBF_FILENAME>' SIZE <SIZE>
EXTENT MANAGEMENT LOCAL AUTOALLOCATE;

E' possibile agire in maniera analoga anche per creare un temporary tablespace:

CREATE TEMPORARY TABLESPACE <TEMP_TBS_NAME> TEMPFILE '<TEMP_DBF_FILENAME>' SIZE <SIZE>
REUSE;

Se i tablespace esistono, ma non sono abbastanza grandi, è possibile aggiungere datafile:

ALTER TABLESPACE <TBS_NAME> ADD DATAFILE '<DBF_FILENAME>' SIZE <SIZE>;

Oppure estendere i datafile:

ALTER DATABASE DATAFILE '<DBF_FILENAME>' RESIZE <NEW_SIZE>;

Le stesse attività possono essere fatte anche su i Temporary Tablaspace cambiano la parola DATAFILE in TEMPFILE.

Una volta che i tablespace e i datafile sono stati creati è possibile procedere alla creazione di un utente:
CREATE USER <USER> IDENTIFIED BY <PASSWORD>
DEFAULT TABLESPACE <TBS_NAME>
TEMPORARY TABLESPACE<TEMP_TBS_NAME>;

Una volta creato l'utente è necessario procedere all'assegnazione degli opportuni grant:

GRANT <GRANT1>, <GRANT2>, <GRANT3>, <GRANTN> TO <USER>;

Ora è possibile utilizzare l'utente per i proprio scopi.

martedì 20 gennaio 2015

Oracle: Abilitare e disabilitare Archive Log 10g/11g

Mi è capitato oggi di trovarmi di fronte a problemi di spazio su un database Oracle in ambiente di collaudo.
Andando a esplorare ho notato che il problema era legato agli archive log che dopo anni di sedimentazione avevano occupato una cosa come 60G di spazio.
Essendo il database non di produzione e essendo in fase di dismissione, per non sapere né leggere né scrive, mi sono prodigato per la disattivazione della modalità archive.
Come sempre google mi ha risolto il problema con questo vademecum 
Ovviamente per risolvere il mio problema è bastata la sola parte di disabilitazione composta dai seguenti passi:

  1. Verifica dello stato degli archive log tramite il comando archive log list
  2. Se attivo spegnere il database con shutdown immediate
  3. Far ripartire il database con startup mount
  4. Disabilitare l'archiving con il comando alter database noarchivelog
  5. Aprire il database con alter database open
  6. Verifica dello stato degli archive log tramite il comando archive log list 
La verifica dello stato degli archive log tramite il comando archive log list restiruisce un output come questo se disabilitato:

Database log mode              No Archive Mode
Automatic archival             Disabled
Archive destination            /u02/app/oracle/oradata/orcl/arch
Oldest online log sequence     26
Current log sequence           28

Oppure come questo se abilitato:

Database log mode              Archive Mode
Automatic archival             Enabled
Archive destination            /u02/app/oracle/oradata/orcl/arch
Oldest online log sequence     26
Next log sequence to archive   28
Current log sequence           28

venerdì 7 febbraio 2014

Oracle: Vincoli e tabelle

In questo periodo sto leggendo il libro SQL Certified Expert Exam Guide di Steve O'Hearm e mi sono imbattuto in alcune tematiche che ritengo interessanti e che voglio segnare in questo blog per futura memoria.
Una di queste tematiche riguarda la creazione di vincoli (constraint) contestualmente alla creazione delle tabelle in Oracle.
In Oracle ci sono cinque tipologie di vincoli che poso essere definite nell'atto di creare una tabella:
  • NOT NULL
  • UNIQUE
  • PRIMARY KEY
  • FOREIGN KEY
  • CHECK
In realtà, con l'eccezione di NOT NULL, questi vincoli possono essere definiti tramite un comando di ALTER TABLE anche a valla della creazione di una tabella.
Il vincolo NOT NULL può essere definito solo "inline" sia in fasi di creazione di una tabella:
CREATE TABLE PORTS(
PORT_ID NUMBER,
PORT_NAME VARCHAR2(40) NOT NULL
);
oppure in fase di modifica:
ALTER TABLE PORTS MODIFY PORT_NAME NOT NULL;
Un'altra peculiarità di questo genere di vincolo è la possibilità di specificare un nome per il vincolo stesso:
CREATE TABLE PORTS(
PORT_ID NUMBER,
PORT_NAME VARCHAR2(40) CONSTRINT PORTS_NN NOT NULL
);
oppure:
ALTER TABLE PORTS MODIFY PORT_NAME CONSTRINT PORTS_NN NOT NULL
Quanto appena detto vale anche per gli altri vincoli:
CREATE TABLE VENDORS(
VENDOR_ID NUMBER PRIMARY KEY,
VENDOR_NAME VARCHAR2(30),
STATUS NUMBER(1) CONSTRAINT VENDORS_CHECK CHECK (STATUS IN (4,5)),
CATEGORY VARCHAR2(5)
);
I vincoli di PRIMARY KEY, FOREIGN KEY, CHECK e UNIQUE possono essere definiti anche in "out line":
CREATE TABLE PORTS(
PORT_ID NUMBER,
PORT_NAME VARCHAR2(40),
CONSTRAINT PORTS_PK PRIMARY KEY (PORT_ID)
);
oppure:
ALTER TABLE PORTS ADD CONSTRAINT PORTS_PK PRIMARY KEY (PORT_ID);

lunedì 4 novembre 2013

Oracle: free space on datafile

Per recuperare dello spazio disco è possibile restringere i DATAFILE di Oracle. Per farlo è sufficiente usare il comando:

ALTER DATABASE DATAFILE '<path_to_datafile>' RESIZE <size>;

Per non andare per tentativi con questa procedura SQL è possibile ricavare quanto spazio libero ci sia per ogni DATAFILE, raggruppando il tutto per TABLESPACE:

SET PAUSE ON
SET PAUSE 'Press Return to Continue'
SET PAGESIZE 60
SET LINESIZE 300
COLUMN "Tablespace Name" FORMAT A20
COLUMN "File Name" FORMAT A80
 
SELECT  Substr(df.tablespace_name,1,20) "Tablespace Name",
        Substr(df.file_name,1,80) "File Name",
        Round(df.bytes/1024/1024,0) "Size (M)",
        decode(e.used_bytes,NULL,0,Round(e.used_bytes/1024/1024,0)) "Used (M)",
        decode(f.free_bytes,NULL,0,Round(f.free_bytes/1024/1024,0)) "Free (M)",
        decode(e.used_bytes,NULL,0,Round((e.used_bytes/df.bytes)*100,0)) "% Used"
FROM    DBA_DATA_FILES DF,
       (SELECT file_id,
               sum(bytes) used_bytes
        FROM dba_extents
        GROUP by file_id) E,
       (SELECT Max(bytes) free_bytes,
               file_id
        FROM dba_free_space
        GROUP BY file_id) f
WHERE    e.file_id (+) = df.file_id
AND      df.file_id  = f.file_id (+)
ORDER BY df.tablespace_name,
         df.file_name


Solaris: Memoria e Core

Oggi ho dovuto recuperare informazioni hardware per i sistemi Solaris. Riporto un po' dei comandi che ho utilizzato.
Per recuperare le informazioni relative alla memoria il comando è
prtconf | grep Mem
Per recuperare informazioni relative ai Core il comando è
psrinfo -pv
Oltre a questi comandi sono utili anche
uname -a
isainfo -kv
per recuperare informazioni sul sistema operativo.

Oracle: import di uno schema da un utente ad un altro.

Per questa attività è necessaria la creazione di una directory all'interno dell'istanza target di ORACLE su cui andrà messo il file da importare.
create or replace directory <TARGET_DIR> as '<path>';
grant read, write on directory <TARGET_DIR> to <user_target>;
I grant di read e write sulla directory vanno assegnati anche all'utente system.
La directory <path> sul File System deve essere accessibile in lettura e scrittura all'utente unix con cui il database viene eseguito (nel mio caso oracle).
Una volta superati questi check è sufficiente dare:
impdp system/<password> SCHEMAS=<schema> \
            remap_schema=<user_orig>:<user_target> \
            remap_tablespace=<user_orig>:<user_target> \
            directory=<TARGET_DIR> \
            dumpfile=<DMP_FILE> logfile=<LOG_FILE>

giovedì 3 gennaio 2013

Jboss e file di properties

Fin dal primo approccio a jboss mi sono imbattuto nel problema dei file di properties utilizzati dalle mie applicazioni java. Al contrario di quanto accade su tomcat, il deploy dei war non è di facile accesso e quindi modificare i file di properties risulta essere poco agevole. In contesti dove la stessa applicazione deve essere distribuita su più sistemi con diversi riferimenti questo inconveniente fa sicuramente sentire il suo peso.
Con l'ultimo sviluppo realizzato ho deciso di impegnarmi per aggirare l'ostacolo. Dopo alcune ricerche è saltata fuori la funzione

System.getProperty("jboss.server.config.dir")

che restituisce il path a <JBOSS_HOME>/standalone/configuration (per il deploy sotto jboss 7). Concatenando questo path al nome del file di properties ho così la possibilità di posizionare i file in una directory dove siano facilmente accessibili.
Al momento ho potuto verificare questa procedura solo per la modalità standalone di jboss.

mercoledì 21 marzo 2012

Oracle impdb, expdb

In queste ultime settimane mi sono trovato a lavorare con import e export di DB Oracle 11g.
Ho quindi preso confidenza con le utility di impdp e expdp.
Per maggiori dettagli consiglio di visitare questa pagina: Oracle Data Pump 10g


Creare la directory


per effettuare import/export su una directory specifica è necessario definire la directory all'interno del DB:

CREATE OR REPLACE DIRECTORY test_dir AS '/u01/app/oracle/oradata/';
GRANT READ, WRITE ON DIRECTORY test_dir TO scott;
Le directory così create sono visibili all'interno della vista ALL_DIRECTORIES.
Per far si che le operazioni su questa directory funzionino questa deve appartenere all'utente oracle.

Esempi di import/export

Table Exports/Imports

expdp scott/tiger@db10g tables=EMP,DEPT directory=TEST_DIR dumpfile=EMP_DEPT.dmp logfile=expdpEMP_DEPT.log

impdp scott/tiger@db10g tables=EMP,DEPT directory=TEST_DIR dumpfile=EMP_DEPT.dmp logfile=impdpEMP_DEPT.log
Schema Exports/Imports
expdp scott/tiger@db10g schemas=SCOTT directory=TEST_DIR dumpfile=SCOTT.dmp logfile=expdpSCOTT.log

impdp scott/tiger@db10g schemas=SCOTT directory=TEST_DIR dumpfile=SCOTT.dmp logfile=impdpSCOTT.log
Database Exports/Imports
expdp system/password@db10g full=Y directory=TEST_DIR dumpfile=DB10G.dmp logfile=expdpDB10G.log

impdp system/password@db10g full=Y directory=TEST_DIR dumpfile=DB10G.dmp logfile=impdpDB10G.log

Oracle Privileges

Combattendo con i privilegi di oracle 11g mi sono imbattuto in questa pagina: Recursively_list_privilege il cui contenuto riporto per futura memoria:


Users to roles and system privileges

This is a script that shows the hierarchical relationship between system privileges, roles and users.
select
  lpad(' ', 2*level) || granted_role "User, his roles and privileges"
from
  (
  /* THE USERS */
    select 
      null     grantee, 
      username granted_role
    from 
      dba_users
    where
      username like upper('%&enter_username%')
  /* THE ROLES TO ROLES RELATIONS */ 
  union
    select 
      grantee,
      granted_role
    from
      dba_role_privs
  /* THE ROLES TO PRIVILEGE RELATIONS */ 
  union
    select
      grantee,
      privilege
    from
      dba_sys_privs
  )
start with grantee is null
connect by grantee = prior granted_role;

System privileges to roles and users

This is also possible the other way round: showing the system privileges in relation to roles that have been granted this privilege and users that have been granted either this privilege or a role:
select
  lpad(' ', 2*level) || c "Privilege, Roles and Users"
from
  (
  /* THE PRIVILEGES */
    select 
      null   p, 
      name   c
    from 
      system_privilege_map
    where
      name like upper('%&enter_privliege%')
  /* THE ROLES TO ROLES RELATIONS */ 
  union
    select 
      granted_role  p,
      grantee       c
    from
      dba_role_privs
  /* THE ROLES TO PRIVILEGE RELATIONS */ 
  union
    select
      privilege     p,
      grantee       c
    from
      dba_sys_privs
  )
start with p is null
connect by p = prior c;

Object privileges

select
  case when level = 1 then own || '.' || obj || ' (' || typ || ')' else
  lpad (' ', 2*(level-1)) || obj || nvl2 (typ, ' (' || typ || ')', null)
  end
from
  (
  /* THE OBJECTS */
    select 
      null          p1, 
      null          p2,
      object_name   obj,
      owner         own,
      object_type   typ
    from 
      dba_objects
    where
       owner not in 
        ('SYS', 'SYSTEM', 'WMSYS', 'SYSMAN','MDSYS','ORDSYS','XDB', 'WKSYS', 'EXFSYS', 
         'OLAPSYS', 'DBSNMP', 'DMSYS','CTXSYS','WK_TEST', 'ORDPLUGINS', 'OUTLN')
      and object_type not in ('SYNONYM', 'INDEX')
  /* THE OBJECT TO PRIVILEGE RELATIONS */ 
  union
    select
      table_name p1,
      owner      p2,
      grantee,
      grantee,
      privilege
    from
      dba_tab_privs
  /* THE ROLES TO ROLES/USERS RELATIONS */ 
  union
    select 
      granted_role  p1,
      granted_role  p2,
      grantee,
      grantee,
      null
    from
      dba_role_privs
  )
start with p1 is null and p2 is null
connect by p1 = prior obj and p2 = prior own;

martedì 20 marzo 2012

Unix IF

Non mi capita molto spesso di scrivere script di shell, ma ogni volta mi capita di litigare con l'if di cui non ricordo mai la sintassi.
Questa volta ho trovato aiuto in questa pagina http://www.dreamsyssoft.com/sp_ifelse.jsp e ne riporto in parte il contenuto per comodità:


If/Else

In order for a script to be very useful, you will need to be able to test the conditions of variables. Most programming and scripting languages have some sort of if/else expression and so does the bourne shell. Unlike most other languages, spaces are very important when using an ifstatement. Let's do a simple script that will ask a user for a password before allowing him to continue. This is obviously not how you would implement such security in a real system, but it will make a good example of using if and else statements. 
#!/bin/sh
# This is some secure program that uses security.

VALID_PASSWORD="secret" #this is our password.

echo "Please enter the password:"
read PASSWORD

if [ "$PASSWORD" == "$VALID_PASSWORD" ]; then
 echo "You have access!"
else
 echo "ACCESS DENIED!"
fi
Remember that the spacing is very important in the if statement. Notice that the termination of the if statement is fi. You will need to use thefi statement to terminate an if whether or not use use an else as well. You can also replace the "==" with "!=" to test if the variables are NOT equal. There are other tokens that you can put in place of the "==" for other types of tests. The following table shows the different expressions allowed. 
Comparisons:
-eqequal to
-nenot equal to
-ltless than
-leless than or equal to
-gtgreater than
-gegreater than or equal to

File Operations:
-sfile exists and is not empty
-ffile exists and is not a directory
-ddirectory exists
-xfile is executable
-wfile is writable
-rfile is readable

mercoledì 14 marzo 2012

Installazione Oracle11gR2

Nuovo task questa settimana: installazione Oracle11 e creazione istanza su macchina Unix (Solaris 5.10) in remoto.
Non essendo ancora un vero DBA mi sono avvalso delle GUI messe a disposizione da Oracle e ho quindi sfruttato il fidatissimo Putty unito al buon Xming.

Ho provato quindi il runInstaller con l'opzione di installazione del software e configurazione di una nuova istanza, ma l'esecuzione si bloccava all'invocazione del dbca.
Ho quindi ripulito la macchina e effettuato l'installazione del solo software per cercare poi a parte di creare l'istanza con il solo dbca. L'installazione è andata a buon fine senza particolari problemi, ma l'utilizzo del dbca ha continuato a dare problemi non creando i datafile, nonostante avessi scelto un template che li contemplava.
A questo punto ho deciso di procedere manualmente alla creazione dell'istanza utilizzando la guida Creating a Database with the CREATE DATABASE Statement e seguendola alla lettera la mia istanza è up and running.

Un'ultima menzione per il netca che utilizzato per creare il listener ha funzionato senza particolari intoppi.

lunedì 5 marzo 2012

Eseguire procedure esterne con IBM Netcool Omnibus

Mi è capitato di recente di dover sincronizzare alla chiusura di un allarme su Omnibus l'esecuzione di uno script esterno.

Per fare questo ho creato una procedura:

create or replace procedure close_ttmars_ticket (in identifier character(255), in tt_id character(255))
executable '$OMNIHOME/utils/closeTTMARS.sh'
host 'localhost'
user 0
group 0
arguments '\'' + identifier + '\' \'' + tt_id + '\'';

e l'ho richiamata dall'interno di un trigger after reinsert.
Alla prima esecuzione della procedura all'interno del log del Process Agent deamon (PAD) viene intercettato il seguente errore:

Mar 2 15:46:16 2012: Error: Failed to find the specified group 0 for process launch.

La configurazione del PAD per l'Object Server (OS) in questione era la seguente:

nco_process 'ROS_Server'
{
Command '$OMNIHOME/bin/nco_objserv -name ROS -pa NCO_PA -listeningport 6970' run as 0
Host = 'hostname'
Managed = True
RestartMsg = '${NAME} running as ${EUID} has been restored on ${HOST}.'
AlertMsg = '${NAME} running as ${EUID} has died on ${HOST}.'
RetryCount = 0
ProcessType = PaPA_AWARE
}

Il PAD viene eseguito come utente root, così come l'OS.
Grazie al gruppo IBM Tivoli Netcool di linkedin ho scoperto che per superare l'errrore era sufficiente agganciare l'utente root al gruppo ncoadmin e restartare il PAD.
Alla successiva esecuzione della procedura lo script è stato richiamato correttamente.

lunedì 30 gennaio 2012

Wrap degli starkits in tcl

Mi è capitato di recente di dovere eseguire l'unwrap di un starkit tcl.
Il comando per eseguire l'unwrap è:

<tclkit> sdx unwrap <starkit>

Questo comando crea nella directory di esecuzione una direcotry <starkit>.vfs
Per eseguire il wrap partendo dalla directory .vfs il comando è:

<tclkit> sdx wrap <starkit> -interp <tclkit>


Lo <starkit> di questo comando è il nome della directory .vfs senza l'estensione. Perchè lo starkit generato da questo comando funzioni è necessario fornire un tclkit tramite l'opzione -interp. Il tclkit passato a questa opzione può essere lo stesso utilizzato per effettuare il wrap.
Se in alternativa all'opzione interp si usa l'opzione runtime, è necessario fornire un altro tclkit perchè quello utilizzato per il comando di wrap risulterebbe busy.

giovedì 10 novembre 2011

Caricamento file di properties in Java

Visto che perdo sempre una marea di tempo a cercare su Internet il modo per recuperare i file di properties all'interno delle WebApps, ho deciso di scrivere qui il codice che fin'ora ha dato il risultato migliore.

Fin'ora nelle mie webapp mi sono trovato a dover caricare file di properties all'interno di bean o Servlet.

Caricamento all'interno di un bean

Per caricare il file di properties all'interno dei bean (ma credo che per estensione il meccanismo funzioni benissimo anche all'interno di normalissime classi) il codice è il seguente:

InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("file.properties");
Properties props = new Properties();
props.load(inputStream);

Per questo caso il file di properties deve essere posizionato alla base del package in cui il bean risiede.

Caricamento all'interno di una servlet

Per caricare file di properties all'interno di una servlet viene sfruttato il ServletContext tramite questo codice:

Properties props = new Properties();
InputStream is = getServletContext().getResourceAsStream("/WEB-INF/classes/file.properties");
props.load(is);

In questo esempio il file di properties è posizionato in fase di deploy sotto la directory WEB-INF/classes della mia webapp.