DB2 Express-C

DB2 e' il potente DBMS relazionale distribuito da IBM. Questo documento introduttivo si riferisce alla versione 9.7.2 di DB2 Express-C su Linux (CentOS 5.5) per x86_64 ma e', mutatis mutandis, valido anche per le altre versioni. Questo documento nei prossimi paragrafi presenta diversi aspetti di DB2: Installazione, Utilizzo, Amministrazione, Funzionalita' avanzate, Architettura, Configurazione e tuning, Backup and Recovery, Compatibilita' Oracle, ... Sul partizionamento in DB2 si trova un breve capitolo in DIVIDE ET IMPERA !
Ma naturalmente la documentazione ufficiale IBM e' molto piu' completa... Tra i moltissimi documenti sicuramente questa introduzione e' molto utile anche se la piu' veloce da leggere e' questa pagina Wiki!

Installazione

Sono disponibili i binari per le piattaforme Linux/Unix/Windows. E' sufficiente scaricare il software corretto dal sito IBM e lanciare il semplice setup grafico... ma vediamolo passo per passo!

Innanzi tutto bisogna scaricare dal sito il software corretto. Basta collegarsi su e scegliere DB2 Express-C 9.7.2 for Linux 64-bit (NdE Maggio 2011: e' stata rilasciata la versione 9.7.4). Compilato il form di registrazione viene scaricato il file db2exc_972_LNX_x86_64.tar.gz. Se x.x.x.x e' l'indirizzo IP del nostro client X, i comandi successivi da eseguire come utente root sono:

# gunzip db2exc_972_LNX_x86_64.tar.gz
# tar xvf db2exc_972_LNX_x86_64.tar
# cd expc 
# DISPLAY=x.x.x.x:0
# export DISPLAY
# nohup ./db2setup &

Il comando lancia il launchpad che e' il wizard di installazione. Ora si passa su una serie di semplici videate guidate...

Installazione DB2 1/n

Naturalmente bisogna scegliere di installare un prodotto...

Installazione DB2 2/n

Si puo' scegliere il tipo di installazione tra Tipical, Compact e Custom.
Con un'installazione Custom e' possibile selezionare singolarmente le features da installare...

Installazione DB2 3/n Installazione DB2 4/n

Quindi viene richiesto se salvare le risposte al wizard e/o effettuare l'installazione (eg. entrambe), il path della directory di installazione (eg. /opt/ibm/db2/V9.7), l'utente ed il gruppo di amministrazione (eg user dausr1 group dasadm1 con password obbligatoria), la creazione di una istanza, l'utente ed il gruppo proprietari dell'istanza (eg. user db2inst1 group db2iadm1 con password obbligatoria), l'utente fenced ed il gruppo relativo (eg. user db2fenc1 group db2fadm1 con password obbligatoria). Il fenced user e' quello utilizzato per l'esecuzione delle UDF (User Defined Function) e delle stored procedures. ...
Controllate tutte le impostazioni si preme il bottone Finish e finalmente parte l'installazione.
Naturalmente abbiamo fatto tutto giusto e l'installazione termina con successo!

Installazione DB2 5/n ... Installazione DB2 6/n

La procedura ha creato tutte le utenze (eg. db2inst1 l'utente da utilizzare per richiamare i comandi DB2), installato il software ed attivato l'instanza.
Ora non ci resta che utilizzare la nostra base dati!

Utilizzo

Per collegarsi alla base dati e' necessario utilizzare un'utenza correttamente impostata. Di default viene creato l'utente db2inst1 che ha gia' un environment completo (/home/db2inst1/sqllib/db2profile). Pronti? Via!

Login: db2inst1
...
$ db2
(c) Copyright IBM Corporation 1993,2007
Command Line Processor for DB2 Client 9.7.2
db2 => create database sample 
db2 => activate database sample 
db2 => list active databases 
                           Active Databases
Database name                              = SAMPLE
Applications connected currently           = 0
Database path                              = /home/db2inst1/db2inst1/NODE0000/SQL00001/

db2 => connect to sample 
db2 => create table emp7(EMPNO integer not null,ENAME VARCHAR(10),SAL float,DEPTNO integer) 
db2 => create unique index pkemp7 on emp7(EMPNO) 
db2 => insert into emp7(empno, ename, deptno) values(1,'SMITH',10) 
db2 => select * from emp7 

Ora si utilizza il solito SQL: facile, vero?
I parametri del CLP (Command Line Processor... insomma il comando db2) sono molteplici. Tra questi e' utile -z per indicare il file di output e -f per leggere uno script. Per registrare i tempi delle query e' utilizzato il comando db2batch.
Su DB2 sono disponibili anche le Stored Procedure realizzate con il linguaggio procedurale di DB2 (SQL PL). Se il file dimmi.sql contiene:

CREATE PROCEDURE dimmi3()
LANGUAGE SQL
BEGIN
  DECLARE i INT DEFAULT 0;

  WHILE i < 3 DO
    insert into messaggio values ('Ti amo!');
    SET i = i + 1;
  END WHILE;
END
@
Con db2 -td@ -f dimmi.sql viene creata la stored procedure dimmi3 (naturalmente deve esistere una tabella messaggio con un campo testo). L'SQL PL e' molto completo ed aderente allo standard SQL:2003. Con l'Inline SQL PL, un sottoinsieme dell'SQL PL (eg. no COMMIT, no PREPARE), possono essere create funzioni e trigger.

Per accedere via JDBC a DB2 la connessione si crea con:

String url = "jdbc:db2://xeniadb2.xenialab.it:50000/sample";
String user = "db2inst1";String password = "db2inst1";Connection con = DriverManager.getConnection(url, user, password);

Naturalmente e' necessario avere nel CLASSPATH il file db2jcc4.jar.

Ordinaria Amministrazione

L'amministrazione di una base dati richiede competenze specifiche. Tuttavia ci sembra utile una breve panoramica sui principali comandi di "ordinaria amministrazione"... Torneremo su altri aspetti importanti per l'amministrazione dopo aver visto meglio l'architettura di DB2.

DB2 Data Studio Lo strumento grafico principale per la gestione della base dati e lo sviluppo in SQL e' Data Studio. Data Studio e' basato su Eclipse e la versione piu' recente, rilasciata assieme a DB2 9.7 e' la 2.2 (NdE e' ora disponibile la versione Data Studio 2.2.1). Data Studio ha sostituito i tool precedenti che sono ancora distribuiti ma non piu' sviluppati (eg. Control Center, Command Editor).

Sono molte le utility che e' possibile lanciare su linea di comando...
Per la gestione delle istanze i principali comandi sono: db2start db2stop db2ilist. Per conoscere l'istanza corrente e le configurazioni attive: db2 get instance; db2 get dbm cfg; db2set -all. Per verificare le licenze installate: db2licm -l
Il comando db2 permette di eseguire istruzioni SQL da linea di comando. Per la gestione dei database i principali comandi db2 sono: create database, drop database, connect to db_name, get db cfg for db_name, ... Per controllare le connessioni attive: list applications e per disconnetterle tutte: force applications all.
Ma soprattutto dall'interfaccia db2 sono disponibili tutti i comandi SQL di DDL (eg. CREATE TABLE, CREATE INDEX) e DML (eg. SELECT, INSERT, UPDATE, DELETE).

Ecco qualche esempio del lancio di comandi:

$ db2 get dbm cfg
          Database Manager Configuration
     Node type = Database Server with local and remote clients
 Database manager configuration release level            = 0x0d00
 CPU speed (millisec/instruction)             (CPUSPEED) = 1.889377e-07
 Max number of concurrently active databases     (NUMDB) = 8
 Federated Database System Support           (FEDERATED) = NO
 Transaction processor monitor name        (TP_MON_NAME) = 
 Default charge-back account           (DFT_ACCOUNT_STR) = 
 Java Development Kit installation path       (JDK_PATH) = /home/db2inst1/sqllib/java/jdk64
 Diagnostic error capture level              (DIAGLEVEL) = 3
 Notify Level                              (NOTIFYLEVEL) = 3
 Diagnostic data directory path               (DIAGPATH) = /home/db2inst1/sqllib/db2dump
 Size of rotating db2diag & notify logs (MB)  (DIAGSIZE) = 0
 Default database monitor switches
   Buffer pool                         (DFT_MON_BUFPOOL) = OFF
   Lock                                   (DFT_MON_LOCK) = OFF
   Sort                                   (DFT_MON_SORT) = OFF
   Statement                              (DFT_MON_STMT) = OFF
   Table                                 (DFT_MON_TABLE) = OFF
   Timestamp                         (DFT_MON_TIMESTAMP) = ON
   Unit of work                            (DFT_MON_UOW) = OFF
 Monitor health of instance and databases   (HEALTH_MON) = ON
 SYSADM group name                        (SYSADM_GROUP) = DB2IADM1
...

$ db2set -all
[i] DB2PROCESSORS=0,1
[i] DB2COMM=tcpip
[i] DB2AUTOSTART=YES
[g] DB2_COMPATIBILITY_VECTOR=MYS
[g] DB2SYSTEM=xeniadb2
[g] DB2INSTDEF=db2inst1
[g] DB2ADMINSERVER=dasusr1

$ db2 get db cfg for sample
       Database Configuration for Database sample
 Database configuration release level                    = 0x0d00
 Database release level                                  = 0x0d00
 Database territory                                      = US
 Database code page                                      = 1208
 Database code set                                       = UTF-8
 Database country/region code                            = 1
 Database collating sequence                             = IDENTITY
 Alternate collating sequence              (ALT_COLLATE) = 
 Number compatibility                                    = OFF
 Varchar2 compatibility                                  = OFF
 Date compatibility                                      = OFF
 Database page size                                      = 4096
 Dynamic SQL Query management           (DYN_QUERY_MGMT) = DISABLE
 Statement concentrator                      (STMT_CONC) = OFF
 Discovery support for this database       (DISCOVER_DB) = ENABLE
...

Funzionalita' avanzate

DB2 ha un insieme molto ampio di funzionalita' avanzate. Riportarle tutte sarebbe inutilmente lungo, ma cercheremo di dare un accenno alle principali.

DB2 e' da sempre il riferimento degli standard sull'SQL. In effetti l'SQL e' "nato" in IBM... anche se ovviamente e' passato un bel po' di tempo! La sintassi SQL, le strutture di programmazione come la SQLCA, le viste, le stored procedures (realizzate con il linguaggio SQL/PL), le foreign key, i constraint, ... sono tutte funzionalita' presenti.
Molto piu' recente ed evoluta e' invece la gestione dell'XML che viene trattato in modo nativo con il pureXML.
DB2 ha una serie di moduli aggiuntivi come il Text Search e lo Spatial Extender.
L'architettura e la configurazione dei sistemi tendono a diventare sempre piu' efficienti ma anche piu' complessi. La gestione ottimale dei sistemi richiede competenze sempre maggiori. Per ridurre il tempo necessario alla gestione di DB2 IBM ha investito molto nel rendere automatiche un'ampia serie di impostazioni e parametrizzazioni.

DB2 e' disponibile in differenti edizioni con un numero crescente di funzionalita'.

La storia delle ultime versioni di DB2 e le relative funzionalita' e' riportato su questa pagina web.

Architettura

In questo capitolo cerchiamo di riassumere i principali aspetti dell'architettura di DB2. L'architettura e' piuttosto complessa poiche' DB2 e' adatto anche a grandi e complesse installazioni e tutte le sue edizioni, anche la Express-C, sono comunque complete.

Innanzi tutto e' necessario un minimo di nomenclatura... L'installazione di DB2 viene effettuata su un server ospite, un Linux nel nostro caso, lo chiameremo host. E' possibile effettuare piu' installazioni sullo stesso host, ma generalmente viene effettuata una sola installazione. La procedura di installazione crea un Database Administration Server (DAS) che consente di gestire le diverse istanze di DB2.
Ogni istanza ha un insieme distinto di risorse ed e' completamente indipendente dalle altre (eg. instanze di sviluppo, test, produzione). Per ogni istanza e' presente una porta socket per effettuare la connessione alla base dati via TCP-IP. Di default la porta e' la 50000. Ogni istanza infine ospita uno o piu' database.
Il database contiene tutte le tabelle, gli indici, ... insomma tutti gli oggetti normalmente presenti su una base dati relazionale.
Riassumento: Host -> DAS -> Istanza -> Database.

Il sistema ospite, il DA Server ed ogni istanza hanno una serie di processi e strutture. La struttura dei processi presenta una serie di processi di sistema, che appartengono ad utenti diversi: root (l'amministratore Unix), dauser1 (Database Administration Server), db2inst1 (l'owner dell'istanza), db2fenc1 (l'utente con cui vengono eseguite le UDF e le SP).

Il processo principale di DB2 e' db2sysc: senza questo processo la base dati non funziona, ma sono molteplici i processi lanciati a loro volta per attivita' specifiche o per controllo. La porta di accesso alla base dati, per le connessioni via rete, e' definita nel file /etc/services (default 50000 su Linux, e 446 su AIX). Ad ogni connessione, sia locale che remota, viene associato un processo db2agent che si occupa di tutte le richieste necessarie all'applicazione e colloquia via IPC con i processi di sistema di DB2. Al comando db2 viene sempre associato un processo db2bp che si occupa di lanciare effettivamente gli statement SQL.
Il processo db2fmcd (DB2 Fault Monitor Coordinator) viene controllato con un respawn in /etc/inittab; e' presente un solo processo per host. I controllo dei fault a livello di istanza viene eseguito dal processo db2fmd; vi e' un processo per ogni istanza. Il processo db2wdog e' il cane da guardia lanciato come utente root e sempre come root sono lanciati i processi db2ckpwd che si occupano dell'autenticazione.

La presenza di molti processi dipende dalla configurazione... Il processo db2pfchr si occupa di leggere da disco e porre i dati nel buffer pool mentre il processo db2pclnr si occupa di scrivere su disco i dati modificati. Il processo db2loggw scrive sui log del DB mentre il processo db2loggr si occupa delle eventuali letture (eg. in caso di rollback) Il processo db2dlock controlla eventuali deadlock. Il processo db2gds (Global Daemon Spawner) si occupa di lanciare tutti gli altri processi necessari all'occorrenza per l'istanza cui e' associato.
Facile fino ad ora? Ma se si utilizza la connection concentration, oppure e' attivo l'intra-partition parallelism, oppure se si utilizzano i partitioned databases... il numero dei processi cresce e l'architettura si complica. Magari lo vediamo un'altra volta! Anche perche' i processi da descrivere sarebbero piu' di 70... meglio vedere l'esempio di quanto realmente presente su Linux dopo l'attivazione di un'istanza ed un paio di connessioni alla base dati:

root      7581     1  0 09:02 ?        00:00:08 /data/ibm/db2/V9.7/bin/db2fmcd 
root     14702     1  0 09:03 ?        00:00:00 db2wdog   
root     14705 14704  0 09:03 ?        00:00:00 db2ckpwd                                        
root     14706 14704  0 09:03 ?        00:00:00 db2ckpwd                                        
root     14707 14704  0 09:03 ?        00:00:00 db2ckpwd  

dasusr1   7044     1  0 09:02 ?        00:00:00 /home/dasusr1/das/adm/db2dasrrm
dasusr1   7614     1  0 09:02 ?        00:00:00 /data/ibm/db2/V9.7/das/bin/db2fmd -i dasusr1 -m /data/ibm/db2/V9.7/das/lib/libdb2dasgcf.so.1
                                      
db2inst1 14704 14702  0 09:03 ?        00:01:51 db2sysc                                                                           
db2inst1 14719 14702  0 09:03 ?        00:00:01 db2acd   ,0,0,0,1,0,0,0,1,0,8a6678, ...
db2inst1 22456     1  0 10:21 pts/0    00:00:00 /home/db2inst1/sqllib/bin/db2bp 20952A502 5 A
db2inst1  2082     1  0 12:38 pts/1    00:00:00 /home/db2inst1/sqllib/bin/db2bp 1977A502 5 A

db2fenc1 23217 14702  0 10:30 ?        00:00:00 db2fmp ( ,0,0,0,0,0,0,0,1,0,8a6678, ...
db2fenc1 18045 14702  0 15:43 ?        00:00:00 db2fmp ( ,1,0,0,0,0,0,0,1,0,8a6678, ...

Architettura DB2 I processi colloquiano tra loro con un'ampio numero di segmenti di memoria condivisa, semafori e message queue:

------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status      
0x1e343474 4521991    db2inst1  767        40182512   6                       
0x1e343461 4554760    db2inst1  701        49610752   5                       
0x00000000 4587529    db2fenc1  701        268435456  3                       
0x1e343568 4620298    db2inst1  761        58720256   1                       

------ Semaphore Arrays --------
key        semid      owner      perms      nsems       
0x1e343474 7143440    db2inst1  767        1         
0x00000000 7241745    db2inst1  761        1         
0x00000000 7208978    db2inst1  761        1  
0x00000000 7634974    db2fenc1  767        3         
0x00000000 7733280    db2inst1  761        1         
...
       
------ Message Queues --------
key        msqid      owner      perms      used-bytes   messages    
0x00000000 1736707    db2inst1   701        0            0           
0x00000000 1802244    db2inst1   701        0            0           
0x00000000 1835013    db2inst1   701        0            0           
0x00000000 1867782    db2fenc1   700        0            0           
0x1e343471 1900551    db2inst1   763        0            0           
...

Per ottimizzare le prestazioni DB2 utilizza quattro distinti tipi di buffer pools in memoria: buffer pool (blocchi dati), RID pool (record identifier), EDM pool (environmental descriptor manager), Sort pool (ordinamento in memoria).

La gestione delle transazioni in DB2 e' molto completa. Il Locking e' gestito a livello di riga con un'escalation automatica a tabella quando si supera un parametro di sistema. Il riconoscimento dei deadlock e' automatico e DB2 fa effettuare il rollback ad una transazione quando questo avviene.
L'ottimizzatore di DB2 e' molto potente e, nella modalita' piu' esaustiva, anche piuttosto pesante per la CPU. E' quindi possibile definire il livello di analisi che deve condurre sulle query. DB2 utilizza lo static binding dei query plan.
Le strutture dati e la gestione dello storage sono molto sofisticate, permettono il massimo del controllo al DBA e consentono di ottenere ottime prestazioni anche con basi dati di enormi dimensioni. La sicurezza e' basata sull'autenticazione al sistema operativo.

Configurazione e tuning

Una volta installato DB2 puo' essere utilizzato immediatamente.
IBM definisce il DB2 un sistema autonomic ovvero in grado di gestirsi da solo! In effetti nel tempo sempre piu' parametri sono diventati AUTOMATIC... pero' non si puo' certo dire che sia proprio semplicissimo.
Con il comando reorgchk le strutture dati vengono analizzate e riorganizzate. E' quindi importante che venga lanciato periodicamente e quando avvengono pesanti modifiche sulla base dati. Altre attivita' importanti oltre al REORG sono il RUNSTATS ed il REBIND e possono essere automatizzate definendo una finsetra temporale.
E' possibile scegliere il dettaglio dell'analisi che deve svolgere l'ottimizzatore sulle query. Se il livello e' basso il parsing delle query impegnera' poco la CPU. Con un livello alto anche le query piu' complesse verranno elaborate in modo ottimale.
Vi sono diversi parametri che e' possibile verificare ed impostare... Alcuni a livello di istanza (dbm cfg) ed altri per ogni database (db cfg). MaxAppls e MaxAgents riguardano il numero dei processi dedicati alle connessioni alla base dati. Il pool si ottimizza con il parametro buffpage. Per il locking si utilizzano diversi parametri i principali sono: locktimeout maxlocks locklist...
Meglio fare qualche esempio. Prima controlliamo le impostazioni:

get dbm cfg
get db cfg for sample
select * from syscat.bufferpools
Poi effettuiamo le modifiche (ovviamente i valori tra parentesi sono range):
alter bufferpool IBMDEFAULTBP size -1
Set current query optimization = 1 (1-9)
update db cfg for sample using LOCKTIMEOUT -1 [-1-30000]
update db cfg for sample using MAXLOCKS n [1-100]
update db cfg for sample using LOCKLIST n [4-60000]

Quanto riportato vale solo come esempio dei comandi di configurazione... se non si conosce bene il DB2 meglio non modificare nulla!

Backup e Restore

Sono disponibili strumenti di backup e restore che possono essere impostati anche per un'esecuzione automatica.
Il modo piu' semplice di effettuare il backup e' con il comando DB2 BACKUP DATABASE dbname cui puo' essere aggiunta la clausola TO path. Nel path di default, o in quello specificato verra' creato un file contenente l'intero backup e con un lungo nome che riporta i dettagli del tipo di backup ed il timestamp. Per default le operazioni avvengono in offline, quindi non vi debbono essere connessioni attive (eg. lanciare db2 force applications all).

Il comando per il restore e'... RESTORE
Sono possibili diverse modalita' di restore comprese quelle piu' complesse (eg. point-in-time). Per evitare che facciate danni... non vi dico piu' nulla!

Compatibilita' Oracle

DB2 ed Oracle sono molto differenti dal punto di vista applicativo. Vi sono differenze nell'SQL, nelle modalita' di locking, nel parsing/binding, nel PL/SQL, nei data type, nelle funzioni, ... La versione 9.7 di DB2 ha una serie di features di compatibilita' verso Oracle che consentono di migrare le applicazioni da Oracle a DB2 con poche modifiche. Anche se non sono presenti in DB2 Express-C il PL/SQL, la libreria di package built-in ed il CLPPlus, la compatibilita' con Oracle e' un aspetto molto importante che richiede almeno una veloce presentazione.

L'analogo dell'sqlplus e' il comando clpplus dove si utilizzano gli stessi comandi cui gli utenti Oracle sono abituali. L'SQL di Oracle contiene diversi costrutti non standard... tra gli altri il DB2 v.9.7 supporta le clausole CONNECT BY, (+) outer join, MINUS, SELECT INTO FOR UPDATE, la tabella DUAL, le pseudo colonne ROWNUM, ROWID, i PUBBLIC SYNONYM, ...
DB2 v.9.7 include un compilatore PL/SQL parallelo al compilatore SQL PL. Il PL/SQL viene cosi' compilato in modo nativo senza necessita' di precompilazioni o conversioni. Sono forniti alcuni package dei principali sistema (eg. DBMS_OUTPUT DBMS_SQL DBMS_ALERT DBMS_PIPE DBMS_JOB DBMS_LOB DBMS_UTILITY UTL_FILE UTL_MAIL ...).
Naturalmente vi sono anche una serie di funzionalita' implementate in modo differente tra DB2 ed Oracle (eg. database link vs. federated database) oppure non presenti, che richiedono una conversione manuale all'interno delle applicazioni.

Per impostare la compatibilita' con Oracle sono necessari alcuni passi... In particolare va impostato il parametro di compatibilita' Oracle e va riavviata l'istanza prima di creare la base dati. Il parametro e' DB2_COMPATIBILITY_VECTOR: un vettore con bit di switch... ma per fortuna c'e' un alias!

db2set DB2_COMPATIBILITY_VECTOR=ORAdb2set -all [i] DB2_COMPATIBILITY_VECTOR=ORA [i] DB2COMM=tcpip
 ...db2stopdb2startdb2 "create database testora PAGESIZE 32 K"

db2set DB2_DEFERRED_PREPARE_SEMANTICS=YES
db2set DB2_ATS_ENABLE=YES

connect to testora;db2 update db cfg using auto_reval DEFERRED_FORCE;db2 update db cfg using decflt_rounding ROUND_HALF_UP;db2 connect reset;db2 deactivate db testora;db2 connect to testora;

Una trattazione piu' ampia della compatibilita' Oracle si trova nel documento EnterpriseDB che descrive l'implementazione realizzata su PostgreSQL Advanced Server (NdE la cui origine e' comune).


Testo: DB2 Express-C
Data: 1 Aprile 2011
Versione: 1.0.1 - 31 Aprile 2011
Autore: mail@meo.bogliolo.name