[successivo] [precedente] [inizio] [fine] [indice generale] [violazione licenza] [translators] [docinfo] [indice analitico] [volume] [parte]
PostgreSQL (1) è un DBMS (Data base management system) relazionale esteso agli oggetti. In questo capitolo si vuole introdurre al suo utilizzo e accennare alla sua struttura, senza affrontare le particolarità del linguaggio di interrogazione. Il nome lascia intendere che si tratti di un DBMS in grado di comprendere le istruzioni SQL, anche se per il momento l'aderenza a quello standard è solo parziale.
PostgreSQL, a parte i programmi binari, gli script e la documentazione, colloca i file di gestione delle basi di dati a partire da una certa directory, che nella documentazione originale viene definita PGDATA. Questo è il nome di una variabile di ambiente che può essere utilizzato per informare i vari programmi di PostgreSQL della sua collocazione; tuttavia, di solito questo meccanismo della variabile di ambiente non viene utilizzato, specificando tale directory in fase di compilazione dei sorgenti.
Questa directory corrisponde solitamente anche alla directory iniziale dell'utente di sistema per l'amministrazione di PostgreSQL, che dovrebbe essere postgres, per cui si potrebbe anche indicare come ~postgres/.
In ogni caso, questa directory è normalmente /var/lib/pgsql/ e tutto ciò che si trova al suo interno appartiene all'utente postgres, anche se i permessi per il gruppo e gli altri utenti variano a seconda della circostanza.
Inizialmente, questa directory dovrebbe contenere una serie di file il cui nome inizia per pg_*. Alcuni di questi sono file di testo, altri sono dei cataloghi, ovvero delle tabelle che servono alla gestione del DBMS e non fanno parte delle basi di dati normali. Se per qualche ragione si utilizza l'utente postgres, essendo questa la sua directory personale, potrebbero apparire altri file che riguardano la personalizzazione di questo utente (.profile, .bash_history, o altre cose simili, in funzione dei programmi che si utilizzano).
All'interno di questa directory si trova normalmente la sottodirectory base/, da cui si articolano le basi di dati che vengono create di volta in volta: ogni base di dati ottiene una sua sottodirectory ulteriore. Per creare una nuova base di dati, PostgreSQL fa uso di una base di dati di partenza: template1. I file di questa si trovano all'interno di base/template1/.
Tutti i programmi che compongono il sistema di PostgreSQL, che hanno la necessità di sapere dove si trovano i dati, oltre al meccanismo della variabile di ambiente PGDATA permettono di indicare tale directory attraverso un'opzione della riga di comando. I programmi più importanti, precisamente postmaster e createdb, riconoscono l'opzione -D. Come si può intuire, l'utilizzo di questa opzione, o di un'altra equivalente per gli altri programmi, fa in modo che l'indicazione della variabile PGDATA non abbia effetto.
Una particolarità di PostgreSQL sta nella definizione dell'amministratore di questo servizio. In pratica potrebbe trattarsi di una persona diversa dall'amministratore del sistema, l'utente root, corrispondente di solito all'utente postgres.
Quando la propria distribuzione GNU/Linux è già predisposta per PostgreSQL, l'utente postgres dovrebbe già essere stato previsto (non importa il numero UID che gli sia stato abbinato), ma quasi sicuramente la parola d'ordine dovrebbe essere «impossibile», come nell'esempio seguente:
|
Come si vede, il campo della parola d'ordine è occupato da un punto esclamativo che di fatto impedisce l'accesso all'utente postgres.
A questo punto si pongono due alternative, a seconda che si voglia affidare la gestione del DBMS allo stesso utente root oppure che si voglia incaricare per questo un altro utente. Nel primo caso non occorrono cambiamenti: l'utente root può diventare postgres quando vuole con il comando su.
# su postgres[Invio]
Nel secondo caso, l'attribuzione di una parola d'ordine all'utente postgres permette a una persona diversa di amministrare il DBMS.
# passwd postgres[Invio]
È bene ripetere che la directory iniziale di questo utente fittizio (in questo caso /var/lib/pgsql/) coincide con il punto di inizio della struttura dei dati del DBMS.
La prima volta che si installa PostgreSQL, è molto probabile che venga predisposta automaticamente la directory ~postgres/. Se così non fosse, o se per qualche motivo si dovesse intervenire manualmente, si può utilizzare initdb, che però potrebbe risiedere al di fuori dei percorsi normali contenuti nella variabile $PATH; precisamente potrebbe trattarsi della directory /usr/lib/postgresql/bin/.
|
|
Lo schema sintattico mostra in modo molto semplice l'uso di initdb. Se si definisce correttamente la variabile di ambiente PGDATA, si può fare anche a meno delle opzioni, diversamente diventa necessario dare questa informazione attraverso l'opzione -D.
Volendo fare tutto da zero, occorre predisporre la directory iniziale di proprietà dell'utente fittizio postgres:
# mkdir ~postgres[Invio]
# chown postgres: ~postgres[Invio]
Prima di avviare initdb, è bene utilizzare l'identità dell'utente amministratore di PostgreSQL:
# su postgres[Invio]
Successivamente, si deve avviare initdb specificando la directory a partire dalla quale si devono articolare i file che costituiscono le basi di dati. La directory in questione è normalmente ~postgres/data/:
postgres$ /usr/lib/postgresql/bin/initdb --locale=it_IT --encoding=UNICODE \
\--pgdata=~postgres/data[Invio]
The files belonging to this database system will be owned by user "postgres".
This user must also own the server process.
The database cluster will be initialized with locale it_IT.
This locale setting will prevent the use of indexes for pattern matching
operations. If that is a concern, rerun initdb with the collation order
set to "C". For more information see the Administrator's Guide.
creating directory /var/lib/postgres/data... ok
creating directory /var/lib/postgres/data/base... ok
creating directory /var/lib/postgres/data/global... ok
creating directory /var/lib/postgres/data/pg_xlog... ok
creating directory /var/lib/postgres/data/pg_clog... ok
creating template1 database in /var/lib/postgres/data/base/1... ok
creating configuration files... ok
initializing pg_shadow... ok
enabling unlimited row size for system tables... ok
initializing pg_depend... ok
creating system views... ok
loading pg_description... ok
creating conversions... ok
setting privileges on built-in objects... ok
vacuuming database template1... ok
copying template1 to template0... ok
Success. You can now start the database server using:
/usr/lib/postgresql/bin/postmaster -D /var/lib/postgres/data
or
/usr/lib/postgresql/bin/pg_ctl -D /var/lib/postgres/data -l logfile start
|
Nell'esempio sono state usate anche due opzioni il cui significato dovrebbe risultare intuitivo.
Tabella 389.1. Alcune opzioni per l'uso di initdb.
Teoricamente, initdb fa tutto quello che è necessario fare; in pratica potrebbe non essere così. La prima cosa da considerare sono i file di configurazione, che, seguendo l'esempio mostrato, vengono collocati nella directory ~postgres/data/. Molto probabilmente la propria distribuzione GNU è organizzata per avere i file di configurazione in una directory /etc/postgresql/, o simile. Se le cose stanno così, bisogna provvedere a sostituire i file di configurazione nella directory ~postgres/data/ con dei collegamenti simbolici appropriati.
Le distribuzioni GNU possono avere la necessità di passare alcune informazioni, tramite variabili di ambiente, all'utente fittizio postgres, cosa che si ottiene con un file ~postgres/.profile appropriato. Se si vuole ricreare la directory ~postgres/ da zero, ma si nota la presenza di file di configurazione della shell, è necessario accertarsi del loro contenuto e provvedere di conseguenza nella ricostruzione della directory.
Un'ultima questione importante da sistemare è la directory ~postgres/dumpall/, che serve a contenere versioni vecchie degli eseguibili di PostgreSQL, con lo scopo di recuperare i dati dalle versioni vecchie delle basi di dati. Normalmente è sufficiente recuperare la directory già usata in precedenza.
Il DBMS di PostgreSQL si basa su un sistema cliente-servente, in cui, il programma che vuole interagire con una base di dati determinata deve farlo attraverso delle richieste inviate a un servente. In questo modo, il servizio può essere esteso anche attraverso la rete.
L'organizzazione di PostgreSQL prevede la presenza di un demone sempre in ascolto (può trattarsi di un socket di dominio Unix o anche di una porta TCP, che di solito corrisponde al numero 5 432). Quando questo riceve una richiesta valida per iniziare una connessione, attiva una copia del servente vero e proprio (back-end), a cui affida la connessione con il cliente. Il demone in ascolto per le richieste di nuove connessioni è postmaster, mentre il servente è postgres.
|
Probabilmente, la scelta del nome «postmaster» è un po' infelice, dal momento che potrebbe far pensare all'amministratore del servizio di posta elettronica. Come al solito occorre un po' di attenzione al contesto in cui ci si trova. |
Generalmente, il demone postmaster viene avviato attraverso la procedura di inizializzazione del sistema, in modo indipendente dal supervisore dei servizi di rete. In pratica, di solito si utilizza uno script collocato all'interno di /etc/init.d/, o in un'altra collocazione simile, per l'avvio e l'interruzione del servizio.
Durante il funzionamento del sistema, quando alcuni clienti sono connessi, si può osservare una dipendenza del tipo rappresentato dallo schema seguente:
|
|
|
postmaster è il demone che si occupa di restare in ascolto in attesa di una richiesta di connessione con un servente postgres (il programma terminale, o back-end in questo contesto). Quando riceve questo tipo di richiesta mette in connessione il cliente (o front-end) con una nuova copia del servente postgres.
Per poter compiere il suo lavoro deve essere a conoscenza di alcune notizie essenziali, tra cui in particolare: la collocazione di postgres (se questo non è in uno dei percorsi della variabile PATH) e la directory da cui si dirama il sistema di file che costituisce il sistema delle varie basi di dati. Queste notizie possono essere predefinite, nella configurazione usata al momento della compilazione dei sorgenti, oppure possono essere indicate attraverso la riga di comando.
Segue la descrizione di alcuni esempi.
# su postgres -c 'postmaster -S -D/var/lib/pgsql'[Invio]
L'utente root, avvia postmaster dopo essersi trasformato temporaneamente nell'utente postgres (attraverso su), facendo in modo che il programma si disassoci dalla shell e dal terminale, diventando un discendente da Init. Attraverso l'opzione -D si specifica la directory di inizio dei file della base di dati.
# su postgres -c 'postmaster -i -S -D/var/lib/pgsql'[Invio]
Come nell'esempio precedente, specificando che si vuole consentire, in modo preliminare, l'accesso attraverso la rete.
|
Per consentire in pratica l'accesso attraverso la rete, occorre anche intervenire all'interno del file di configurazione |
# su postgres -c 'nohup postmaster -D/var/lib/pgsql \
\> /var/log/pglog 2>&1 &'[Invio]
L'utente root, avvia postmaster in modo simile al precedente, dove in particolare viene diretto lo standard output all'interno di un file, per motivi diagnostici. Si osservi l'utilizzo di nohup per evitare l'interruzione del funzionamento di postmaster all'uscita del programma su.
# su postgres -c 'nohup postmaster -D/var/lib/pgsql -d 1 \
\> /var/log/pglog 2>&1 &'[Invio]
Come nell'esempio precedente, con l'attivazione del primo livello diagnostico nei messaggi emessi.
A partire dalla versione 6.4 di PostgreSQL, inizia l'introduzione di un sistema di gestione delle localizzazioni. La sua attivazione dipende dalle opzioni che vengono definite in fase di compilazione, per cui potrebbe anche succedere che la propria distribuzione GNU/Linux disponga di una versione di PostgreSQL che non è in grado di gestire la localizzazione.
La localizzazione va applicata al servente, ovvero al sistema di gestione dei dati, mentre ciò non serve dalla parte del cliente. Questa è una situazione un po' strana rispetto al solito, dove ogni utente configura per sé il proprio ambiente. Infatti, la scelta della localizzazione dei dati, deve essere fatta al livello della base di dati, senza poter essere cambiata a piacimento, a seconda dei punti di vista.
Di conseguenza, la configurazione delle variabili LC_*, o eventualmente di LANG, deve avvenire per l'ambiente riferito al funzionamento di postmaster, per cui occorre preparare uno script apposito.
|
Lo script che si vede sopra, serve a definire la variabile di ambiente LANG, a esportarla e ad avviare postmaster. Questo script deve essere avviato dalla procedura di inizializzazione del sistema, all'interno della quale viene utilizzato presumibilmente su, in modo da attribuire l'identità dell'utente amministratore di PostgreSQL. Se si usa un sistema di script per l'avvio o la conclusione dei servizi, cosa che di solito si colloca nella directory /etc/init.d/, o un'altra simile, potrebbe essere necessario intervenire su quello che si occupa di avviare postmaster.
|
Quello che si vede sopra, è lo scheletro della struttura case tipica di un tale script. Volendo modificare la localizzazione predefinita in fase di compilazione, occorre lo script mostrato prima. Si suppone che lo script con il quale si modificano le variabili di localizzazione e si avvia postmaster, sia /usr/bin/avvia_postmaster; la modifica da apportare all'esempio appena visto è quella seguente:
|
Oltre alla localizzazione attraverso le variabili di ambiente tradizionali, si può intervenire sulla variabile PGDATESTYLE, il cui scopo è quello di definire la forma di visualizzazione delle date. La tabella 389.3 elenca le parole chiave che si possono assegnare a questa variabile e l'effetto che ne deriva.
Tabella 389.3. Elenco dei formati di data gestibili con PostgreSQL.
| Stile | Descrizione | Esempio |
| ISO | ISO 8601 | 2007-12-31 |
| SQL | Tipo tradizionale | 12/31/2007 |
| German | 31.12.2007 |
Normalmente la cosa migliore è utilizzare il formato ISO, che potrebbe anche essere quello predefinito. Volendo estendere lo script per l'avvio di postmaster, presentato all'inizio, basta aggiungere l'impostazione della variabile PGDATESTYLE:
|
Come è stato descritto fino a questo punto, è possibile influenzare il comportamento del servente PostgreSQL attraverso opzioni della riga di comando e variabili di ambiente. Oltre a questi metodi, è possibile intervenire nel file ~postgres/postgresql.conf, attraverso direttive che assomigliano all'assegnamento di variabili. Il loro significato dovrebbe risultare intuitivo. Viene mostrato un esempio completo di questo file:
|
Si può osservare la direttiva tcpip_socket = 1, che abilita l'accesso al servente attraverso la rete.
Per fare in modo che gli utenti possano accedere al DBMS, occorre che siano stati registrati all'interno del sistema di PostgreSQL stesso. In pratica, può trattarsi solo di utenti già riconosciuti nel sistema operativo, che vengono aggiunti e accettati anche da PostgreSQL. Per l'inserimento di questi utenti si utilizza createuser, come nell'esempio seguente:
# su postgres[Invio]
postgres$ createuser[Invio]
Enter name of user to add---> tizio[Invio]
Enter user's postgres ID or RETURN to use unix user ID: 500 -> [Invio]
In tal modo è stato definito l'inserimento dell'utente tizio, confermando il suo numero UID.
Is user "tizio" allowed to create databases (y/n) y[Invio]
All'utente tizio è stato concesso di creare delle nuove basi di dati.
Is user "tizio" allowed to add users? (y/n) n[Invio]
All'utente non viene concesso di aggiungere altri utenti.
createuser: tizio was successfully added |
Da questo esempio si può comprendere quali siano le possibilità di attribuzione di privilegi ai vari utenti del sistema DBMS. In particolare, è opportuno osservare che ogni base di dati appartiene all'utente che lo ha creato, il quale diventa il suo amministratore particolare (per la precisione il DBA).
L'eliminazione di un utente PostgreSQL avviene in modo simile attraverso destroyuser, come nell'esempio seguente:
# su postgres[Invio]
postgres$ destroyuser[Invio]
Enter name of user to delete ---> tizio[Invio]
destroyuser: delete of user tizio was successful. |
|
L'eliminazione di un utente PostgreSQL comporta anche l'eliminazione delle basi di dati a lui appartenenti. |
Inizialmente, l'utilizzo di PostgreSQL si può dimostrare poco intuitivo, soprattutto per ciò che riguarda le segnalazioni di errore, spesso troppo poco esplicite. Per permettere di avere una visione un po' più chiara di ciò che accade, sarebbe bene fare in modo che postmaster produca dei messaggi diagnostici, possibilmente diretti a un file o a una console virtuale inutilizzata.
Nella sezione in cui si descrive il funzionamento di postmaster appaiono alcuni esempi di avvio di questo programma, in modo da generare e conservare queste informazioni diagnostiche. L'esempio seguente, in particolare, avvia postmaster in modo manuale e, oltre a conservare le informazioni diagnostiche in un file, le visualizza continuamente attraverso una console virtuale inutilizzata (l'ottava).
# su postgres[Invio]
$ nohup postmaster -D/var/lib/pgsql -d 1 > /var/log/pglog 2>&1 &[Invio]
$ exit[Invio]
# nohup tail -f /var/lib/pgsql > /dev/tty8 &[Invio]
L'accesso alle basi di dati viene consentito attraverso un sistema di autenticazione. I sistemi di autenticazione consentiti possono essere diversi e dipendono dalla configurazione di PostgreSQL fatta all'atto della compilazione dei sorgenti.
Il file di configurazione pg_hba.conf (Host-based authentication), che si trova della directory iniziale dell'utente postgres, cioè l'inizio della struttura delle basi di dati, serve per controllare il sistema di autenticazione una volta installato PostgreSQL.
L'autenticazione degli utenti può avvenire in modo incondizionato (trust), cosa che si fa di solito quando chi accede è un utente del sistema presso cui è in funzione PostgreSQL stesso; in pratica ci si fida del sistema di controllo fatto dal sistema operativo.
L'autenticazione può essere semplicemente disabilitata, nel senso di impedire qualunque accesso incondizionatamente. Questo può servire per impedire l'accesso da parte di un certo gruppo di nodi.
L'accesso può essere controllato attraverso l'abbinamento di una parola d'ordine agli utenti di PostgreSQL. Queste parole d'ordine possono essere conservate in un file di testo con una struttura simile a quella di /etc/passwd, oppure nel file ~postgres/pg_shadow, che in pratica è una tabella (questo particolare viene ripreso in seguito).
Inoltre, l'autenticazione può avvenire attraverso un sistema Kerberos, oppure attraverso il protocollo IDENT (capitolo 211). In questo ultimo caso, ci si fida di quanto riportato dal sistema remoto il quale conferma o meno che la connessione appartenga a quell'utente che si sta connettendo.
Il file ~postgres/pg_hba.conf permette di definire quali nodi possono accedere al servizio DBMS di PostgreSQL, eventualmente stabilendo anche un abbinamento specifico tra basi di dati e nodi di rete.
Le righe vuote e il testo preceduto dal simbolo # vengono ignorati. I record (cioè le righe contenenti le direttive del file in questione), sono suddivisi in campi separati da spazi o caratteri di tabulazione. Il formato può essere riassunto nei due modelli sintattici seguenti:
|
|
|
|
Nel primo caso si intendono controllare gli accessi provenienti da clienti avviati nello stesso sistema locale, utilizzando un socket di dominio Unix; nel secondo si fa riferimento ad accessi attraverso la rete (connessioni TCP).
Il secondo campo del record serve a indicare il nome di una base di dati per la quale autorizzare l'accesso; in alternativa si può usare la parola chiave all, in modo da specificare tutte le basi di dati in una sola volta.
I campi indirizzo_ip e maschera_degli_indirizzi rappresentano un gruppo di indirizzi di nodi che hanno diritto di accedere a quella base di dati determinata.
Il campo autenticazione_utente rappresenta il tipo di autenticazione attraverso una parola chiave. Le più comuni sono elencate nella tabella 389.4.
L'ultimo campo dipende dal penultimo. Nel caso di autenticazione ident, si utilizza solitamente la parola chiave sameuser per indicare a PostgreSQL che i nomi usati dagli utenti nei sistemi remoti da cui possono accedere, coincidono con quelli predisposti per la gestione del DBMS. Nel caso di autenticazione password rappresenta il nome del file di testo contenente le parole d'ordine.
Tabella 389.4. Parole chiave che possono essere usate nel campo autenticazione_utente.
| Autenticazione | Descrizione |
|
| L'autenticazione non ha luogo e si accetta il nome fornito dall'utente senza alcuna verifica. |
|
| La connessione viene rifiutata in ogni caso. |
|
| Viene richiesta una parola d'ordine riferita all'utente, verificandola in base al contenuto di un file indicato nel campo successivo, oppure in base a quanto riportato dal catalogo ~postgres/pg_shadow. |
|
| Viene richiesta una parola d'ordine riferita all'utente, verificandola in base al contenuto di ~postgres/pg_shadow. La differenza più importante rispetto a password sta nel fatto che in quel caso la parola d'ordine viene trasmessa in chiaro, mentre con crypt no. |
|
| L'autenticazione avviene attraverso il protocollo IDENT (capitolo 211), demandando il riconoscimento al sistema remoto. Si intende che questo metodo sia anche molto poco sicuro. |
Perché il sistema possa funzionare correttamente, sono sempre presenti almeno i record seguenti:
|
Ciò consente l'accesso senza altre misure di sicurezza a tutti i clienti che accedono dallo stesso sistema locale attraverso un socket di dominio Unix, e agli utenti dello stesso nodo locale (localhost), a tutte le basi di dati.
L'esempio seguente permette l'accesso da parte di utenti provenienti dalla rete locale 192.168.*.*, alla base di dati nostro_db, affidando il compito di riconoscimento al sistema remoto da cui avviene la connessione e utilizzando il nome dell'utente, fornito in questo modo, come nome di utente PostgreSQL.
|
L'esempio seguente, è simile al precedente, con la differenza che gli accessi dalla rete indicata richiedono una parola d'ordine, che PostgreSQL conserva nel file di testo ~postgres/passwd (il nome indicato nell'ultimo campo).
|
Questo file di configurazione viene fornito già con alcuni esempi commentati.
Con il sistema di autenticazione definito dalla parola chiave password è possibile utilizzare un file di testo simile a /etc/passwd o a /etc/shadow per annotare gli utenti PostgreSQL e le parole d'ordine cifrate relative. Per esempio, nel file ~postgres/pg_hba.conf potrebbe comparire il record seguente:
|
In tal caso, gli utenti che accedono attraverso un cliente avviato dai nodi della sottorete 192.168.*.* devono identificarsi attraverso l'indicazione di una parola d'ordine che PostgreSQL può trovare nel file di testo ~postgres/utenti. Questo file potrebbe essere simile a quello seguente:
|
Se questo file dovesse contenere dei campi aggiuntivi (separati con i soliti due punti), questi verrebbero semplicemente ignorati.
La parola d'ordine cifrata che si colloca nel secondo campo del record di questo file è ottenuta con la solita funzione di sistema crypt(). Per inserire facilmente un utente, o per cambiare la parola d'ordine di un utente registrato precedentemente, si utilizza il programma pg_passwd, indicando semplicemente in quale file intervenire.
|
|
L'utilizzo è banale, come si vede dall'esempio seguente in cui si aggiunge l'utente sempronio (è importante ricordare di operare in qualità di utente postgres).
# cd ~postgres[Invio]
# su postgres[Invio]
postgres:~$ pg_passwd utenti[Invio]
Username: sempronio[Invio]
New password: ******[Invio]
Re-enter new password: ******[Invio]
La distribuzione GNU/Linux Debian è molto attenta alla coerenza dei pacchetti che si installano; pertanto, nel caso di PostgreSQL, può essere controllato tutto a partire dai file che si trovano nella directory /etc/postgresql/. In particolare, si trova in questa directory il file pg_hba.conf e il file postgresql.conf che sono già stati descritti in precedenza; inoltre, si trova un file aggiuntivo che viene interpretato dallo script della procedura di inizializzazione del sistema che si occupa di avviare e di arrestare il servizio. Si tratta dei file /etc/postgresql/postmaster.conf, attraverso il quale si possono controllare delle piccole cose a cui non si può accedere con il file postgresql.conf, che altrimenti richiederebbero di intervenire attraverso le opzioni della riga di comando del demone relativo.
|
Per poter gestire una base di dati occorre prima crearla. Ciò si ottiene normalmente attraverso lo script createdb, avviato con i privilegi adatti, cioè quelli di un utente a cui ciò è consentito. Nello stesso modo, attraverso lo script dropdb, si può eliminare un'intera base di dati.
La creazione di una base di dati è in pratica la creazione di una serie di file all'interno di una directory con lo stesso nome usato per identificare la base di dati stessa. Questa operazione ha luogo utilizzando una struttura di partenza già predisposta: di solito si tratta di template1.
Le directory delle basi di dati si articolano a partire da ~postgres/base/. Quando si crea l'ipotetica base di dati mio_db, ciò che si ottiene in pratica è la copia della directory ~postgres/base/template1/ in ~postgres/base/mio_db/.
|
In ogni caso, la copia da sola non basta. Perché una base di dati sia riconosciuta come tale occorre che questa sia stata annotata nel file |
Come già accennato, una base di dati può essere creata solo da un utente autorizzato precedentemente per questo scopo. Di solito si utilizza lo script createdb, come nell'esempio seguente in cui si crea la base di dati mio_db.
$ createdb mio_db[Invio]
L'utente che ha creato una base di dati è automaticamente il suo amministratore, ovvero colui che può decidere eventualmente di eliminarla.
PostgreSQL pone dei limiti nella scelta dei nomi delle basi di dati. Non possono superare i 16 caratteri e il primo di questi deve essere alfabetico, oppure può essere un trattino basso.
|
La dimensione massima dei nomi dipende dal modo in cui sono stati compilati i sorgenti o dalle caratteristiche della piattaforma. Il limite di 16 caratteri è sufficientemente basso da andare bene in ogni circostanza. |
Se l'utente che tenta di creare una base di dati non è autorizzato per questo, quello che si ottiene è un messaggio di errore del tipo seguente:
|
L'amministratore di una base di dati, generalmente colui che la ha creata, è la persona che può anche eliminarla. Nell'esempio seguente si elimina la base di dati mio_db.
$ dropdb mio_db[Invio]
L'accesso a una base di dati avviene attraverso un cliente, ovvero un programma frontale, o front-end, secondo la documentazione di PostgreSQL. Questo si avvale generalmente della libreria LibPQ. PostgreSQL fornisce un programma cliente standard, psql, che si comporta come una sorta di shell tra l'utente e la base di dati stessa.
Il programma psql permette un utilizzo interattivo attraverso una serie di comandi impartiti dall'utente su una riga di comando; oppure può essere avviato in modo da eseguire il contenuto di un file o di un solo comando fornito tra gli argomenti. Per quanto riguarda l'utilizzo interattivo, il modo più semplice per avviarlo è quello che si vede nell'esempio seguente, dove si indica semplicemente il nome della base di dati sulla quale intervenire.
$ psql mio_db[Invio]
Welcome to the POSTGRESQL interactive sql monitor: Please read the file COPYRIGHT for copyright terms of POSTGRESQL type \? for help on slash commands type \q to quit type \g or terminate with semicolon to execute query You are currently connected to the database: mio_db mio_db=>_ |
Da questo momento si possono inserire le istruzioni SQL per la base di dati selezionata, in questo caso mio_db, oppure si possono inserire dei comandi specifici di psql. Questi ultimi si notano perché sono composti da una barra obliqua inversa (\), seguita da un carattere.
Il comando interno di psql più importante è \h che permette di visualizzare una guida rapida alle istruzioni SQL che possono essere utilizzate.
=> \h[Invio]
type \h <cmd> where <cmd> is one of the following:
abort abort transaction alter table
begin begin transaction begin work
cluster close commit
...
type \h * for a complete description of all commands
|
Nello stesso modo, il comando \? fornisce un riepilogo dei comandi interni di psql.
=> \?[Invio]
\? -- help \a -- toggle field-alignment (currenty on) \C [<captn>] -- set html3 caption (currently '') ... |
Tutto ciò che psql non riesce a interpretare come un suo comando interno viene trattato come un'istruzione SQL. Dal momento che queste istruzioni possono richiedere più righe, è necessario informare psql della conclusione di queste, per permettergli di analizzarle e inviarle al servente. Queste istruzioni possono essere terminate con un punto e virgola (;), oppure con il comando \g.
Si può osservare, utilizzando psql, che l'invito mostrato cambia leggermente a seconda del contesto: inizialmente appare nella forma =>, mentre quando è in corso l'inserimento di un'istruzione SQL non ancora terminata si trasforma in ->. Il comando \g viene usato prevalentemente in questa situazione.
-> \g[Invio]
Le istruzioni SQL possono anche essere raccolte in un file di testo normale. In tal caso si può utilizzare il comando \i per fare in modo che psql interpreti il suo contenuto, come nell'esempio seguente, dove il file in questione è mio_file.sql.
=> \i mio_file.sql[Invio]
Nel momento in cui si utilizza questa possibilità (quella di scrivere le istruzioni SQL in un file facendo in modo che poi questo venga letto e interpretato), diventa utile il poter annotare dei commenti. Questi sono iniziati da una sequenza di due trattini (--): tutto quello che vi appare dopo viene ignorato.
La conclusione del funzionamento di psql si ottiene con il comando \q.
=> \q[Invio]
Il programma cliente psql può funzionare in modo interattivo, come già accennato, oppure può eseguire le istruzioni contenute in un file. Questo può essere fornito attraverso l'opzione -f, oppure può provenire dallo standard input, attraverso una pipeline:
|
|
|
|
|
|
Il programma psql può funzionare solo in abbinamento a una base di dati determinata. In questo senso, se non viene indicato il nome di una base di dati nella riga di comando, psql tenta di utilizzarne una con lo stesso nome dell'utente. Per la precisione, si fa riferimento alla variabile di ambiente USER.
Oltre alle istruzioni SQL, psql riconosce dei comandi, alcuni dei quali vengono descritti di seguito.
Il programma psql può restituire i valori seguenti:
0 se tutte le istruzioni sono state eseguite senza errori;
1 se si sono verificati errori;
2 se è intervenuta una disconnessione da parte del servente sottostante.
Segue la descrizione di alcuni esempi.
$ psql mio_db[Invio]
Cerca di connettersi con la base di dati mio_db nel nodo locale, utilizzando il meccanismo del socket di dominio Unix.
$ psql -d mio_db[Invio]
Esattamente come nell'esempio precedente, con l'uso dell'opzione -d che serve a evitare ambiguità sul fatto che mio_db sia il nome della base di dati.
$ psql -u -d mio_db[Invio]
Come nell'esempio precedente, ma fa in modo che psql chieda all'utente il nominativo e la parola d'ordine da usare per collegarsi. È necessario usare questa opzione quando il servizio a cui ci si connette richiede un'autenticazione basata sull'uso di parole d'ordine.
$ psql -u -h dinkel.brot.dg -d mio_db[Invio]
Come nell'esempio precedente, ma questa volta l'accesso viene fatto a una base di dati con lo stesso nome presso il nodo dinkel.brot.dg.
$ psql -f istruzioni.sql -d mio_db[Invio]
Cerca di connettersi con la base di dati mio_db nel nodo locale, utilizzando il meccanismo del socket di dominio Unix, quindi esegue le istruzioni contenute nel file istruzioni.sql.
Il programma psql è sensibile alla presenza o meno della variabile di ambiente PAGER. Se questa esiste e non è vuota, psql utilizza il programma indicato al suo interno per controllare l'emissione dell'output generato. Per esempio, se contiene less, come si vede nell'esempio seguente che fa riferimento a una shell compatibile con quella di Bourne, si fa in modo che l'output troppo lungo venga controllato da Less:
|
Per eliminare l'impostazione di questa variabile, in modo da ritornare allo stato predefinito, basta annullare il contenuto della variabile nel modo seguente:
|
Un problema comune dei DBMS è quello della riorganizzazione periodica dei dati, in modo da semplificare e accelerare le elaborazioni successive. Nei sistemi più semplici si parla a volte di «ricostruzione indici», o di qualcosa del genere. Nel caso di PostgreSQL, si utilizza un comando specifico che è estraneo all'SQL standard: VACUUM.(2)
|
|
|
|
L'operazione di pulizia si riferisce alla base di dati aperta in quel momento. L'opzione VERBOSE permette di ottenere i dettagli sull'esecuzione dell'operazione; ANALYZE serve invece per indicare specificatamente una tabella, o addirittura solo alcune colonne di una tabella.
Anche se non si tratta di un comando SQL standard, per PostgreSQL è importante che venga eseguita periodicamente una ripulitura con il comando VACUUM, eventualmente attraverso uno script simile a quello seguente, da avviare per mezzo del sistema Cron.
|
In pratica, richiamando questo script con i privilegi dell'utente root, indicando come argomento il nome della base di dati (viene inserito al posto di $1 dalla shell), si ottiene di avviare il comando VACUUM attraverso psql.
Per riuscire a fare il lavoro in serie per tutte le basi di dati, si potrebbe scrivere uno script più complesso, come quello seguente. In questo caso, lo script deve essere avviato con i privilegi dell'utente postgres.
|
In breve, si utilizza la prima volta psql in modo da aprire la base di dati template1 (quella fondamentale, che permette di intervenire sui cataloghi di sistema), accedendo al catalogo pg_database per leggere la colonna contenente i nomi delle basi di dati. In particolare, l'opzione -t serve a evitare di inserire il nome della colonna stessa. L'elenco che si ottiene viene inserito nella variabile di ambiente BASI_DATI, che in seguito viene scandita da un ciclo for, all'interno del quale si utilizza psql per ripulire ogni singola base di dati.
All'inizio del capitolo si è accennato alla collocazione normale delle directory e dei file che compongono le basi di dati. Chi amministra il sistema di elaborazione che ospita PostgreSQL e le basi di dati, deve avere almeno un'idea di come maneggiare questi file. Per esempio deve sapere come comportarsi per le copie di sicurezza, soprattutto come ripristinarle.
Per comodità, la directory da cui si articolano i cataloghi e le basi di dati viene indicata come ~postgres/, ovvero la directory personale dell'utente postgres, cioè il DBA (l'amministratore delle basi di dati).
Quando si installa PostgreSQL si dovrebbe avere già una directory ~postgres/ organizzata in modo tale da poter iniziare a creare delle basi di dati. Per questo sono necessari alcuni file, detti cataloghi, e una base di dati di partenza: template1.
I cataloghi di PostgreSQL sono delle tabelle del DBMS che non appartengono ad alcuna base di dati e servono per gestire il DBMS stesso. Normalmente non si dovrebbe accedere a tali tabelle direttamente, ma solo tramite script o programmi specifici. Tuttavia ci sono situazioni in cui ciò potrebbe essere necessario, tenendo conto poi che la documentazione di PostgreSQL fa spesso riferimento a queste, per cui conviene almeno saperle consultare.
Dal momento che PostgreSQL consente di accedere a delle tabelle solo dopo avere specificato la base di dati, a queste si accede attraverso template1, in pratica con un comando simile a quello seguente:
postgres:~$ psql -d template1[Invio]
Il catalogo pg_user è una vista del catalogo pg_shadow, che contiene le informazioni sugli utenti di PostgreSQL. La figura 389.1 mostra un esempio di come potrebbe essere composta. La consultazione della tabella si ottiene con il comando SQL:
template1=> SELECT * FROM pg_user;[Invio]
|
Figura 389.1. Esempio di un catalogo pg_user.
|
Si può osservare che l'utente postgres ha tutti gli attributi booleani attivi (usecreatedb, usetrace, usesuper, usecatupd) e questo per permettergli di compiere tutte le operazioni all'interno delle basi di dati. In particolare, l'attributo usecreatedb permette all'utente di creare una base di dati e usesuper permette di aggiungere utenti. In effetti, osservando l'esempio della figura, l'utente tizio ha praticamente gli stessi privilegi dell'amministratore postgres.
Il catalogo pg_shadow è il contenitore delle informazioni sugli utenti, a cui si accede normalmente tramite la vista pg_user. Il suo scopo è quello di conservare in un file più sicuro (perché non è accessibile agli utenti comuni) i dati delle parole d'ordine degli utenti che intendono usare le forme di autenticazione basate su queste. Per il momento, nella documentazione di PostgreSQL non viene spiegato come usarlo, né se le parole d'ordine indicate devono essere in chiaro o cifrate in qualche modo. L'esempio della figura 389.2 mostra gli stessi utenti a cui non viene abbinata alcuna parola d'ordine. La consultazione della tabella si ottiene con il comando SQL:
template1=> SELECT * FROM pg_shadow;[Invio]
|
Figura 389.2. Esempio di un catalogo pg_shadow.
|
Il catalogo pg_database è una tabella che contiene le informazioni sulle basi di dati esistenti. La figura 389.3 mostra un esempio di come potrebbe essere composta. La consultazione della tabella si ottiene con il comando SQL:
template1=> SELECT * FROM pg_database;[Invio]
|
Figura 389.3. Esempio di un catalogo pg_database.
|
La prima colonna rappresenta il nome della base di dati, la seconda riporta il numero UID dell'utente che rappresenta il suo DBA, cioè colui che l'ha creata, la terza rappresenta il percorso in cui si trova. Per esempio, si può osservare che la base di dati prova2 è stata creata dall'utente 1 001, che da quanto riportato in pg_user è tizio.
La colonna che rappresenta il percorso della base di dati è più complessa da interpretare. In generale, i nomi che appaiono senza l'indicazione di un percorso si riferiscono alla directory ~postgres/base/, corrispondendo in pratica alla directory che contiene i file della base di dati. Per esempio, la base di dati prova2 è collocata nella directory ~postgres/base/prova2/. I percorsi assoluti vanno interpretati in modo speciale; in particolare, nel caso della base di dati prova, la directory corrispondente è in realtà /home/postgres/base/prova/ (si osservi l'inserzione di base/).
In generale, è normale che tutte le basi di dati vengano create a partire da ~postgres/base/, pertanto non si dovrebbero vedere percorsi assoluti in questa tabella. Viene mostrato in seguito quando può verificarsi questa condizione.
Prima di poter pensare a copiare o a spostare una base di dati occorre avere chiaro in mente che si tratta di file «binari» (nel senso che non si tratta di file di testo), contenenti informazioni collegate l'una all'altra in qualche modo più o meno oscuro. Queste informazioni possono a volte essere espresse anche in forma numerica; in tal caso dipende dall'architettura in cui sono state create. Questo implica due cose fondamentali: lo spostamento o la copia deve essere fatto in modo che non si perdano dei pezzi per la strada (i file della stessa base di dati devono essere raccolti tutti assieme) e lo spostamento in un'altra architettura non dovrebbe essere ammissibile.
La copia di una base di dati per motivi di sicurezza è un'operazione semplice e così anche il suo ripristino. Si tratta di archiviare e poi eventualmente ripristinare tutto il contenuto della directory che la contiene. L'esempio seguente archivia nel file base.tar.gz tutte le basi di dati che si articolano a partire da ~postgres/base/:
# tar czvf base.tar.gz ~postgres/base[Invio]
L'esempio seguente, invece, archivia nel file pubblico.tar.gz solo la base di dati pubblico, che si trova esattamente nella directory ~postgres/base/pubblico/:
# tar czvf pubblico.tar.gz ~postgres/base/pubblico[Invio]
Il recupero non è nulla di speciale, tranne per il fatto che si deve recuperare una basi di dati per intero, ovvero ciò che di solito si articola in una sottodirectory di ~postgres/base/. Se si dovessero perdere informazioni sui permessi, occorre ricordare che i file devono appartenere all'utente postgres, ovvero colui che rappresenta l'amministratore del DBMS.
Per poter spostare una base di dati nel file system occorre ricordare che l'informazione sulla sua collocazione è contenuta nel catalogo pg_database, per cui è su questo che occorre intervenire per informare PostgreSQL della nuova posizione che gli si vuole dare. Eventualmente, c'è sempre la possibilità di eliminare la base di dati con il comando dropdb, ricreandola nella nuova posizione, sostituendo poi tutti i file con quella vecchia. In pratica, all'interno dei file che compongono una base di dati non c'è l'informazione della loro collocazione, quindi, a parte il problema di modificare in qualche modo il catalogo pg_database, non si dovrebbero incontrare altre difficoltà.
Il comando createdb, se non viene specificato diversamente, crea la base di dati in una sottodirectory a partire da ~postgres/base/. Se si vuole definire una nuova posizione basta usare l'opzione -D, seguita dalla directory che deve essere presa in considerazione al posto di ~postgres/ (ovvero di PGDATA come si legge nella documentazione di PostgreSQL).
Perché la cosa funzioni, occorre che la directory ricevente sia pronta. Per esempio, volendo creare la base di dati mia a partire da /home/postgresql/, sapendo che poi in pratica la sottodirectory mia/ viene collocata su /home/postgresql/base/, occorre predisporre tutto questo.
# mkdir /home/postgresql[Invio]
# mkdir /home/postgresql/base[Invio]
# chown -R postgres: /home/postgresql[Invio]
La preparazione delle directory può essere fatta con l'aiuto di initlocation, ma questo comando non fa niente di particolare in più. Per completare l'esempio, viene mostrato il comando con cui si crea la base di dati mia, utilizzando come riferimento la directory /home/postgresql.
postgres:~$ createdb -D /home/postgresql mia[Invio]
Per concludere, se si osserva il catalogo pg_database, si può notare che il percorso indicato della base di dati appena creata è /home/postgresql/mia/, mentre invece la directory vera e propria è /home/postgresql/base/mia/.
Dopo aver visto in che modo è possibile copiare e archiviare una base di dati, rimanendo sulla stessa piattaforma, ma soprattutto, rimanendo nell'ambito della stessa versione di PostgreSQL, è necessario vedere in che modo si può risolvere il problema quando la piattaforma cambia, o quando cambia la versione di PostgreSQL.
Ricapitolando, quindi, i problemi sono due: la piattaforma e la versione di PostgreSQL. In linea di principio, non è possibile copiare una base di dati realizzata su GNU/Linux in una macchina i386 per portarla in un'altra macchina con architettura differente, anche se con lo stesso sistema operativo; nemmeno si può trasportare una base di dati, così come si trova, da un sistema operativo a un altro. Inoltre, PostgreSQL non è in grado di leggere, o di utilizzare in alcun modo, le basi di dati realizzate con altre versioni dello stesso.
Attualmente, l'unico modo per raggirare l'ostacolo è lo scarico dei dati (dump) in uno script che successivamente può essere dato in pasto a psql, per ricreare le basi di dati come in origine. Naturalmente, questa tecnica non è perfetta e funziona correttamente solo quando le basi di dati non contengono relazioni con tuple eccessivamente grandi.
Lo scarico di una base di dati si ottiene attraverso il programma pg_dump, che è parte integrante della distribuzione di PostgreSQL.
|
|
Se non si indicano delle opzioni e ci si limita a specificare la base di dati su cui intervenire, si ottiene il risultato attraverso lo standard output, composto in pratica dai comandi necessari a psql per ricostruire le relazioni che compongono la base di dati (la base di dati stessa deve essere ricreata manualmente). Tanto per chiarire subito il senso della cosa, se si utilizza pg_dump nel modo seguente, si ottiene il file di testo mio_db.dump:
$ pg_dump mio_db > mio_db.dump[Invio]
Questo file va verificato, ricercando la presenza eventuale di segnalazioni di errore che vengono generate in presenza di dati che non possono essere riprodotti fedelmente; eventualmente, il file può anche essere modificato se si conosce la sintassi dei comandi che vengono inseriti in questo script. Per fare in modo che le relazioni della base di dati vengano ricreate e caricate, si può utilizzare psql nel modo seguente:
$ psql -e mio_db < mio_db.dump[Invio]
Tabella 389.7. Alcune opzioni che possono essere usate con pg_dump.
Per copiare o trasferire tutte le basi di dati del sistema di PostgreSQL, si può utilizzare pg_dumpall:
|
|
Il programma pg_dumpall provvede a scaricare tutte le basi di dati, assieme alle informazioni necessarie per ricreare il catalogo pg_shadow (la vista pg_user si ottiene di conseguenza). Come si può intuire, si deve utilizzare pg_dumpall con i privilegi dell'utente postgres.
postgres$ /usr/lib/postgresql/bin/pg_dumpall > basi_dati.dump[Invio]
L'esempio mostra il modo più semplice di utilizzare pg_dumpall per scaricare tutte le basi di dati in un file unico. In questo caso, si ottiene il file di testo basi_dati.dump. Questo file va verificato alla ricerca di segnalazioni di errore che potrebbero essere generate in presenza di dati che non possono essere riprodotti fedelmente; eventualmente, può essere modificato se si conosce la sintassi dei comandi che vengono inseriti in questo script.
Il recupero dell'insieme completo delle basi di dati avviene normalmente in un'ambiente PostgreSQL, in cui il sistema delle basi di dati sia stato predisposto, ma non sia stata creata alcuna base di dati (a parte template1 la cui presenza è obbligatoria). Come si può intuire, il comando necessario per ricaricare le basi di dati, assieme alle informazioni sugli utenti (il catalogo pg_shadow), è quello seguente:
postgres$ psql -e template1 < basi_dati.dump[Invio]
La situazione tipica in cui è necessario utilizzare pg_dumpall per scaricare tutto il sistema delle basi di dati, è quella del momento in cui ci si accinge ad aggiornare la versione di PostgreSQL. In breve, in quella occasione, si devono eseguire i passaggi seguenti:
con la versione vecchia di PostgreSQL, si deve utilizzare pg_dumpall in modo da scaricare tutto il sistema delle basi di dati in un solo file di testo;
si elimina il contenuto della directory ~postgres/, ovvero quella che altrimenti viene definita PGDATA (prima conviene forse fare una copia di sicurezza);
si ricrea il sistema delle basi di dati, vuoto, attraverso initdb;
si ricaricano le basi di dati precedenti, assieme alle informazioni sugli utenti, attraverso psql, utilizzando il file generato in precedenza attraverso pg_dumpall.
Quello che manca, di solito si tratta del file ~postgres/data/pg_hda.conf per la configurazione dei sistemi di accesso e autenticazione, deve essere ripristinato manualmente.
PostgreSQL
Bruce Momjian, PostgreSQL: introduction and concepts
Al Dev (Alavoor Vasudevan), PostgreSQL HOWTO
<http://www.linux.org/docs/ldp/howto/HOWTO-INDEX/howtos.html>
Appunti di informatica libera 2004.10.10 --- Copyright © 2000-2004 Daniele Giacomini -- <daniele (ad) swlibero·org>, <daniele·giacomini (ad) poste·it>
1) PostgreSQL software libero con licenza speciale
2) Per comprendere bene il contenuto di questa sezione, può essere necessaria la lettura del prossimo capitolo. Queste informazioni sono collocate qui soltanto per una questione di ordine logico nella posizione delle stesse.
Dovrebbe essere possibile fare riferimento a questa pagina anche con il nome postgresql_struttura_e_preparazione.html
[successivo] [precedente] [inizio] [fine] [indice generale] [violazione licenza] [translators] [docinfo] [indice analitico]