[successivo] [precedente] [inizio] [fine] [indice generale] [indice ridotto] [indice analitico] [volume] [parte]


Capitolo 601.   PostgreSQL: gestione del DBMS

La gestione di un DBMS richiede di occuparsi di utenze e di basi di dati. PostgreSQL mette a disposizione degli script per facilitare la loro creazione ed eliminazione, ma in generale è meglio avvalersi di istruzioni SQL, anche se non sono standard.

Per poter impartire comandi in forma di istruzioni SQL, occorre collegarsi al DBMS attraverso un programma appropriato (di solito psql); per poter maneggiare gli utenti e le basi di dati è necessario disporre dei privilegi necessari. Generalmente, le prime volte si compiono queste operazioni in qualità di amministratore, pertanto con l'utenza postgres.

Per accedere al DBMS, occorre indicare una basi di dati, anche se le funzioni in questione non interagiscono direttamente con questa. Di solito, dato che inizialmente non è disponibile altro, ci si collega alla basi di dati template1.

Teoricamente, PostgreSQL non distingue tra lettere maiuscole e minuscole quando si tratta di nominare le basi di dati, le relazioni (le tabelle o gli oggetti a seconda della definizione che si preferisce utilizzare) e gli elementi che compongono delle relazioni. Tuttavia, in certi casi si verificano degli errori inspiegabili dovuti alla scelta dei nomi che in generale conviene indicare sempre solo con lettere minuscole.

601.1   Accesso a una base di dati

L'accesso a una base di dati avviene attraverso un cliente, ovvero un programma frontale, o front-end, secondo la documentazione di PostgreSQL. Questo programma 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 cliente tipico, dovrebbe riconoscere le variabili di ambiente PGHOST e PGPORT. La prima serve a stabilire l'indirizzo o il nome di dominio del servente, indicando implicitamente che la connessione avviene attraverso una connessione TCP e non con un socket di dominio Unix; la seconda specifica il numero della porta, ammesso che si voglia utilizzare un numero diverso da 5 432. L'uso di queste variabili non è indispensabile, ma serve solo per non dover specificare queste informazioni attraverso opzioni della riga di comando.

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 (--), come prescrive lo standard, e tutto quello che vi appare dopo viene ignorato.

La conclusione del funzionamento di psql si ottiene con il comando \q.

=> \q[Invio]

Per l'avvio di psql si può usare la sintassi seguente. L'opzione -f consente di indicare un file contenente istruzioni SQL da eseguire subito; in alternativa, un file di questo tipo può essere fornito attraverso lo standard input.

psql [opzioni] [base_di_dati]
psql -f file_di_istruzioni [altre_opzioni] [base_di_dati]
cat file_di_istruzioni | psql [opzioni] [base_di_dati]

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.

Questo dettaglio dovrebbe permettere di comprendere il significato della segnalazione di errore che si ottiene se si tenta di avviare psql senza indicare una base di dati, quando non ne esiste una con lo stesso nome dell'utente.

Tabella 601.4. Alcune opzioni per l'avvio di psql.

Opzione Descrizione
-c istruzione_sql
--command istruzione_sql
Permette di fornire un'istruzione SQL già nella riga di comando, ottenendone il risultato attraverso lo standard output e facendo terminare subito dopo l'esecuzione di psql. Questa opzione viene usata particolarmente in abbinamento a -q.
-d base_di_dati
--dbname base_di_dati
Permette di indicare il nome della base di dati da utilizzare. Può essere utile quando per qualche motivo potrebbe essere ambigua l'indicazione del suo nome come ultimo argomento.
-f file_di_istruzioni
--file file_di_istruzioni
Permette di fornire a psql un file da interpretare contenente le istruzioni SQL (oltre agli eventuali comandi specifici di psql), senza avviare così una sessione di lavoro interattiva.
-h nodo
--host nodo
Permette di specificare il nodo a cui connettersi per l'interrogazione del servente PostgreSQL.
-H
--html
Fa in modo che l'emissione in forma tabellare avvenga utilizzando il formato HTML. In pratica, ciò è utile per costruire un risultato da leggere attraverso un navigatore ipertestuale.
-o file_output
--output file_output
Fa in modo che tutto l'output venga inviato nel file specificato dall'argomento.
-p porta
--port porta
Nel caso in cui postmaster sia in ascolto su una porta TCP diversa dal numero 5 432 (corrispondente al valore predefinito), si può specificare con questa opzione il numero corretto da utilizzare.
-q
--quiet
Fa sì che psql funzioni in modo «silenzioso», limitandosi all'emissione pura e semplice di quanto generato dalle istruzioni impartite. Questa opzione è utile quando si utilizza psql all'interno di script che devono occuparsi di rielaborare il risultato ottenuto.
-t
--tuple-only
Disattiva l'emissione dei nomi degli attributi. Questa opzione viene utilizzata particolarmente in abbinamento con -c o -q.
-T opzioni_tabelle_html
--table-attr opzioni_tabelle_html
Questa opzione viene utilizzata in abbinamento con -H, per definire le opzioni HTML delle tabelle che si generano. In pratica, si tratta di ciò che può essere inserito all'interno del marcatore di apertura della tabella: <TABLE ...>.
-U utente
--username utente
Consente di specificare il nome dell'utente del DBMS.
-W
--password
Forza psql a richiedere una parola d'ordine, in ogni caso.

Tabella 601.5. Alcuni comandi che psql riconosce durante il funzionamento interattivo.

Comando Descrizione
\h [comando]
L'opzione \h usata da sola, elenca le istruzioni SQL che possono essere utilizzate. Se viene indicato il nome di una di queste, viene mostrata in breve la sintassi relativa.
\?
Elenca i comandi interni di psql, cioè quelli che iniziano con una barra obliqua inversa (\).
\l
Elenca tutte le basi di dati presenti nel servente. Ciò che si ottiene è una tabella contenente rispettivamente: i nomi delle basi di dati, i numeri di identificazione dei rispettivi amministratori (gli utenti che li hanno creati) e il nome della directory in cui sono collocati fisicamente.
\connect base_di_dati \
  \[nome_utente]
Chiude la connessione con la base di dati in uso precedentemente e tenta di accedere a quella indicata. Se il sistema di autenticazione lo consente, si può specificare anche il nome dell'utente con cui si intende operare sulla nuova base di dati. Generalmente, ciò dovrebbe essere impedito.
Se si utilizza un'autenticazione basata sul file pg_hba.conf, l'autenticazione di tipo trust consente questo cambiamento di identificazione, altrimenti, il tipo ident lo impedisce.
\d [relazione]
L'opzione \d usata da sola, elenca le relazioni contenute nella base di dati, altrimenti, se viene indicato il nome di una di queste relazioni, si ottiene l'elenco degli attributi. Se si utilizza il comando \d *, si ottiene l'elenco di tutte le relazioni con le informazioni su tutti gli attributi rispettivi.
\i file
Con questa opzione si fa in modo che psql esegua di seguito tutte le istruzioni contenute nel file indicato come argomento.
\q
Termina il funzionamento di psql.

Segue la descrizione di alcuni esempi.

601.1.1   Variabile di ambiente «PAGER»

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 POSIX o compatibile con quella di Bourne, si fa in modo che l'output troppo lungo venga controllato da Less:

PAGER=less
export PAGER

Per eliminare l'impostazione di questa variabile, in modo da ritornare allo stato predefinito, basta annullare il contenuto della variabile nel modo seguente:

PAGER=
export PAGER

601.2   Organizzazione degli utenti

La creazione di un utente per il DBMS si ottiene con l'istruzione CREATE USER, che nel modello seguente appare in modo semplificato:

CREATE USER nome_utente
    [WITH [PASSWORD 'parola_d'ordine']
         [CREATEDB|NOCREATEDB|CREATEUSER|NOCREATEUSER]]

Si comprende intuitivamente il significato delle parole chiave delle opzioni finali, con le quali è possibile concedere o negare i privilegi di creare o eliminare delle basi di dati e di creare o eliminare degli utenti. Si osservi che la parola d'ordine va indicata esattamente tra apici singoli. Se si omettono le opzioni finali, i privilegi relativi vengono negati, come se fossero state specificate implicitamente le parole chiave NOCREATEDB e NOCREATEUSER.

L'uso della parole chiave CREATEUSER nella creazione o nella modifica di un'utenza, concede a questa la facoltà di creare o eliminare delle utenze, senza limitazioni, oltre che di creare ed eliminare delle basi di dati. In altri termini, dà all'utente il ruolo di amministrazione del DBMS, con tutti i poteri necessari.

L'esempio seguente mostra i passaggi per la creazione, presso il DBMS locale, dell'utente tizio (con una parola d'ordine di esempio) a cui viene concesso di creare delle basi di dati, ma non di gestire delle utenze:

su postgres[Invio]

postgres$ psql template1[Invio]

template1=# CREATE USER tizio WITH PASSWORD 'segreta' \
  \          CREATEDB NOCREATEUSER;
[Invio]

CREATE USER

template1=# \q[Invio]

postgres$ exit[Invio]

Così come è stato creata, le caratteristiche di un'utenza possono essere modificate con l'istruzione ALTER USER, per esempio per modificare la parola d'ordine:

ALTER USER nome_utente
    [WITH [PASSWORD 'parola_d'ordine']
         [CREATEDB|NOCREATEDB]
         [CREATEUSER|NOCREATEUSER]]

Logicamente, se si tratta di modificare la parola d'ordine, può essere lo stesso utente che esegue questa istruzione; altrimenti, per cambiare i privilegi, è necessario che intervenga un utente che ha maggiori facoltà. Nell'esempio seguente, l'utente tizio creato in quello precedente, modifica la sua parola d'ordine; si osservi che la scelta della base di dati template1 è puramente casuale:

psql --username tizio template1[Invio]

Password: digitazione_all'oscuro[Invio]

template1=> ALTER USER tizio WITH PASSWORD 'segretissima';[Invio]

ALTER USER

template1=> \q[Invio]

L'eliminazione di un'utenza avviene con un'istruzione molto semplice, senza opzioni particolari:

DROP USER nome_utente

L'esempio seguente elimina l'utenza tizio e l'operazione viene svolta dall'utente postgres:

su postgres[Invio]

postgres$ psql template1[Invio]

template1=# DROP USER tizio;[Invio]

DROP USER

template1=# \q[Invio]

postgres$ exit[Invio]

601.3   Creazione ed eliminazione delle basi di dati

La creazione di una base di dati è consentita agli amministratori e agli utenti che hanno ottenuto questo privilegio. La base di dati può essere creata per sé, oppure per farla gestire da un altro utente.

CREATE DATABASE nome_base_di_dati
    [[WITH] [OWNER [=] utente_proprietario]
            [ENCODING [=] 'codifica']]

Il modello sintattico mostrato omette alcune opzioni, di utilizzo meno frequente. In particolare, sarebbe possibile specificare il modello di riferimento per la creazione della base di dati, ma in modo predefinito viene utilizzata la base di dati template1 per crearne una di nuova.

Nell'esempio seguente, l'utente tizio crea la base di dati mia_db, specificando espressamente la codifica; inizialmente accede facendo riferimento alla base di dati template1:

psql --username tizio template1[Invio]

Password: digitazione_all'oscuro[Invio]

template1=> CREATE DATABASE mia_db ENCODING 'UNICODE';[Invio]

CREATE DATABASE

template1=> \q[Invio]

L'eliminazione di una base di dati si ottiene con l'uso di un'istruzione molto semplice:

DROP DATABASE nome_base_di_dati

Questa istruzione può essere usata da un amministratore, oppure dall'utente che ne è proprietario. Nell'esempio seguente, l'utente tizio elimina la sua base di dati mia_db; per farlo, accede facendo riferimento a un'altra (la solita template1):

psql --username tizio template1[Invio]

Password: digitazione_all'oscuro[Invio]

template1=> DROP DATABASE mia_db;[Invio]

DROP DATABASE

template1=> \q[Invio]

601.4   La base di dati amministrativa

PostgreSQL memorizza le informazioni sugli utenti e sulle basi di dati all'interno di una sorta di base di dati amministrativa, senza nome. Alle relazioni di questa base di dati trasparente, si accede da qualunque posizione; in pratica, le relazioni sono accessibili quando si apre la base di dati template1, o qualunque altra, ma ovviamente, solo l'amministratore del DBMS ha la facoltà di modificarle direttamente.

Come conseguenza del fatto che le relazioni della base di dati amministrativa sono accessibili da qualunque posizione, si comprende che i nomi di queste relazioni non si possono utilizzare per la costruzione di nuove.

La documentazione originale di PostgreSQL individua queste relazioni, definendole «cataloghi». In questo documento, si preferisce indicarle come relazioni o tabelle della base di dati amministrativa.

Le relazioni più importanti della base di dati amministrativa sono pg_user, pg_shadow e pg_database. Vale la pena di osservare il loro contenuto.

postgres:~$ psql -d template1[Invio]

La relazione pg_user è in realtà una vista del catalogo pg_shadow, che contiene le informazioni sugli utenti di PostgreSQL. La figura 601.13 mostra un esempio di come potrebbe essere composta. La consultazione della relazione si ottiene con l'istruzione SQL seguente:

template1=> SELECT * FROM pg_user;[Invio]

Figura 601.13. Esempio del contenuto di pg_user.

  usename   | usesysid | usecreatedb | usesuper | usecatupd |  passwd  | valuntil | useconfig 
------------+----------+-------------+----------+-----------+----------+----------+-----------
 postgres   |        1 | t           | t        | t         | ******** |          | 
 pgnanouser |      100 | t           | f        | f         | ******** |          | 
 tizio      |     1001 | t           | t        | t         | ******** |          | 

Si può osservare che l'utente postgres ha tutti gli attributi booleani attivi (usecreatedb, 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.

La relazione 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, in quanto non accessibile agli utenti comuni, i dati delle parole d'ordine degli utenti che intendono usare le forme di autenticazione basate su queste. L'esempio della figura 601.14 mostra gli stessi utenti a cui non viene abbinata alcuna parola d'ordine (probabilmente perché accedono localmente e vengono identificati dal sistema operativo). La consultazione della relazione si ottiene con l'istruzione SQL seguente:

template1=> SELECT * FROM pg_shadow;[Invio]

Figura 601.14. Esempio del contenuto di pg_shadow.

  usename   | usesysid | usecreatedb | usesuper | usecatupd | passwd | valuntil | useconfig 
------------+----------+-------------+----------+-----------+--------+----------+-----------
 postgres   |        1 | t           | t        | t         |        |          | 
 pgnanouser |      100 | t           | f        | f         |        |          | 
 tizio      |     1001 | t           | t        | t         |        |          | 

La relazione pg_database contiene le informazioni sulle basi di dati esistenti. La figura 601.15 mostra un esempio di come potrebbe essere composta. La consultazione della relazione si ottiene con l'istruzione SQL:

template1=> SELECT * FROM pg_database;[Invio]

Figura 601.15. Esempio del contenuto di pg_database, diviso in due parti per motivi tipografici.

  datname  | datdba | encoding | datistemplate | datallowconn | datlastsysoid |  
-----------+--------+----------+---------------+--------------+---------------+--
 nanodb    |    100 |        6 | f             | t            |         17140 | 
 template1 |      1 |        6 | t             | t            |         17140 | 
 template0 |      1 |        6 | t             | f            |         17140 | 

      | datvacuumxid | datfrozenxid | datpath | datconfig |          datacl          
     -+--------------+--------------+---------+-----------+--------------------------
      |         8159 |   3221233632 |         |           | 
      |         8271 |   3221233744 |         |           | {postgres=C*T*/postgres}
      |          464 |          464 |         |           | {postgres=C*T*/postgres}

Il primo attributo rappresenta il nome della base di dati, il secondo riporta il numero di identificazione dell'utente che rappresenta il suo DBA, cioè colui che l'ha creata o che comunque deve amministrarla. Per esempio, si può osservare che la base di dati nanodb è stata creata dall'utente identificato dal numero 100, che da quanto riportato in pg_user è pgnanouser.

601.5   Manutenzione delle basi di dati

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.

VACUUM [altre_opzioni] [VERBOSE] [nome_relazione]
VACUUM [altre_opzioni] [VERBOSE] ANALYZE [nome_relazione [(attributo_1[,... attributo_n])]]

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 relazione, o addirittura solo alcuni attributi (le colonne delle tabelle) una relazione e avere informazioni su questi. Eventualmente, sono disponibili altre opzioni per ottenere una riorganizzazione dei dati più importante.

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:

#!/bin/sh
su postgres -c "psql $1 -c 'VACUUM'"

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.

#!/bin/sh
#
BASI_DATI=`psql template1 -t -c "SELECT datname from pg_database"`
#
echo "Procedimento di ripulitura e sistemazione delle basi di dati"
echo "di PostgreSQL."
echo "Se l'operazione dovesse essere interrotta accidentalmente,"
echo "potrebbe essere necessaria l'eliminazione del file pg_vlock"
echo "contenuto nella directory della base di dati relativa."
#
for BASE_DATI in $BASI_DATI
do
    echo -n "$BASE_DATI: "
    psql $BASE_DATI -c "VACUUM"
done

In breve, si utilizza la prima volta psql in modo da aprire la base di dati template1 (quella usata come modello, che si ha la certezza di trovare sempre), accedendo alla relazione pg_database, che fa parte della base di dati amministrativa, per leggere l'attributo contenente i nomi delle basi di dati. In particolare, l'opzione -t serve a evitare di inserire il nome dell'attributo stesso. 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.

601.6   Copie di sicurezza

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. Ciò implica due cose fondamentali: la copia deve essere fatta in modo che non si perdano dei pezzi per la strada; lo spostamento dei dati in forma binaria, in un'altra architettura, non è ammissibile.

La copia di sicurezza binaria, di tutto ciò che serve a PostgreSQL per la gestione delle sue basi di dati, si ottiene semplicemente archiviando quanto contenuto a partire da ~postgres/, così come si può comprendere intuitivamente. Ciò che conta è che il ripristino dei dati avvenga nello stesso contesto (architettura, sistema operativo, librerie, versione di PostgreSQL e configurazione).

Per una copia di sicurezza più «sicura», è necessario archiviare i dati in modo indipendente da tutto. Si ottiene questo generando un file di testo, contenente istruzioni SQL con le quali ricostruire poi una sola base di dati o anche tutte assieme. Per questo vengono in aiuto due programmi di PostgreSQL: pg_dump e pg_dumpall.

Non sempre il procedimento di trasferimento dei dati in forma di comandi SQL può essere portato a termine con successo. Può succedere che delle relazioni troppo complesse o con dati troppo grandi, non siano tradotte correttamente nella fase di archiviazione. Questo problema deve essere preso in considerazione già nel momento della progettazione di una base di dati, avendo cura di verificare, sperimentandolo, che il procedimento di scarico e recupero dei dati possa funzionare.

Lo scarico di una sola base di dati si ottiene attraverso il programma pg_dump, che, eventualmente, potrebbe risiedere al di fuori dei percorsi normali contenuti nella variabile $PATH e potrebbe trovarsi nella directory /usr/lib/postgresql/bin/:

pg_dump [opzioni] base_di_dati

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 601.18. Alcune opzioni che possono essere usate con pg_dump.

Autenticazione Descrizione
-d
--inserts
In condizioni normali, pg_dump salva i dati delle relazioni (le tabelle secondo l'SQL) in una forma compatibile con il comando COPY, che però non è compatibile con lo standard SQL. Con l'opzione -d, utilizza il comando INSERT tradizionale.
-D
--column-inserts
Come con l'opzione -d, con l'aggiunta dell'indicazione degli attributi (le colonne secondo l'SQL) in cui vanno inseriti i dati. In pratica, questa opzione permette di generare uno script più preciso e dettagliato.
-f file
--file=file
Permette di definire un file diverso dallo standard output, che si vuole generare con il risultato dell'elaborazione di pg_dump.
-h nodo
--host=nodo
Permette di specificare il nodo a cui connettersi per l'interrogazione del servente PostgreSQL. In pratica, se l'accesso è consentito, è possibile scaricare una base di dati gestita presso un nodo remoto.
-p porta
--port=porta
Nel caso in cui postmaster sia in ascolto su una porta TCP diversa dal numero 5 432 (corrispondente al valore predefinito), si può specificare con questa opzione il numero corretto da utilizzare.
-s
--schema-only
Scarica soltanto la struttura delle relazioni, senza occuparsi del loro contenuto. In pratica, serve per poter riprodurre le relazioni vuote.
-t nome_relazione
--table=nome_relazione
Utilizzando questa opzione, indicando il nome di una relazione, si ottiene lo scarico solo di quella.
-U nome
Specifica con quale nominativo utente identificarsi per eseguire l'operazione.
-W
Forza la richiesta di inserire una parola d'ordine, che comunque dovrebbe essere chiesta automaticamente se il DBMS la richiede.

Per copiare o trasferire tutte le basi di dati del sistema di PostgreSQL, si può utilizzare pg_dumpall, che, eventualmente, potrebbe risiedere al di fuori dei percorsi normali contenuti nella variabile $PATH e potrebbe trovarsi nella directory /usr/lib/postgresql/bin/:

[percorso]pg_dumpall [opzioni]

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'amministratore del DBMS (di solito l'utente postgres).

postgres$ 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 quelle standard, come template1). Come si può intuire, il comando necessario per ricaricare le basi di dati, assieme alle informazioni sugli utenti (la relazione 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:

  1. 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;

  2. si aggiorna PostgreSQL;

  3. si elimina il contenuto della directory ~postgres/data/, ovvero quella che altrimenti viene definita PGDATA (prima conviene forse fare una copia di sicurezza del suo contenuto, tale e quale, in forma binaria);

  4. si ricrea il sistema delle basi di dati, vuoto, attraverso initdb;

  5. 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, eventualmente, è la configurazione di PostgreSQL, in particolare per ciò che riguarda i sistemi di accesso e autenticazione (il file ~postgres/data/pg_hda.conf), che deve essere ripristinata manualmente.

601.7   Importazione ed esportazione dei dati

Al posto di utilizzare gli script già pronti per la copia e il recupero dei dati, è possibile avvalersi di comandi SQL. PostgreSQL fornisce un'istruzione speciale per permettere l'importazione e l'esportazione dei dati da e verso un file indipendente dalla piattaforma. Si tratta dell'istruzione COPY, la cui sintassi semplificata è quella seguente:

COPY relazione TO { 'file' | STDIN }
    [ [WITH]
        [BINARY]
        [DELIMITER [AS] 'delimitatore']]
COPY relazione FROM { 'file' | STDIN }
    [ [WITH]
        [BINARY]
        [DELIMITER [AS] 'delimitatore']]

Nella prima delle due forme, si esportano i dati verso un file o verso lo standard input; nella seconda si importano da un file o dallo standard output.

Se si usa l'opzione BINARY si ottiene un file «binario» indipendente dalla piattaforma; diversamente si ottiene un file di testo tradizionale. Nel caso del file di testo, ogni riga corrisponde a una tupla della relazione; gli attributi sono separati da un carattere di delimitazione, che in mancanza della definizione tramite l'opzione DELIMITER AS è un carattere di tabulazione. In ogni caso, anche se si specifica tale opzione, può trattarsi solo di un carattere. In pratica, sempre nell'ipotesi di creazione di un file di testo, ogni riga è organizzata secondo lo schema seguente:

attributo_1xattributo_2x...xattributo_n

Nello schema, x rappresenta il carattere di delimitazione, che, come si può vedere, non viene inserito all'inizio e alla fine.

Quando l'istruzione COPY viene usata per importare dati dallo standard input, in formato testo, è necessario che dopo l'ultima riga che contiene attributi da inserire nella relazione, sia presente una sequenza di escape speciale: una barra obliqua inversa seguita da un punto (\.). Il file ottenuto quando si esporta verso lo standard output contiene questo simbolo di conclusione.

Il file di testo in questione può contenere anche altre sequenze di escape, che si trovano descritte nella tabella 601.19.

Tabella 601.19. Sequenze di escape nei file di testo generati e utilizzati da COPY.

Escape Descrizione
\\
Una barra obliqua inversa.
\.
Simbolo di conclusione del file.
\N
NULL.
\delimitatore
Protegge il simbolo che viene già utilizzato come delimitatore.
\<LF>
Tratta <LF> in modo letterale.
\b
<BS>.
\f
<FF>.
\n
<LF>.
\r
<CR>.
\t
<HT> (tabulazione orizzontale).
\v
<VT> (tabulazione verticale).
\ooo
Codice per un byte espresso in ottale.

È importante fare mente locale al fatto che l'istruzione viene eseguita dal servente. Ciò significa che i file, quando non si tratta di standard input o di standard output, sono creati o cercati secondo il file system che questo servente si trova ad avere sotto di sé.

Segue la descrizione di alcuni esempi.

601.8   Riferimenti

Appunti di informatica libera 2007.02 --- Copyright © 2000-2007 Daniele Giacomini -- <daniele (ad) swlibero·org>


Dovrebbe essere possibile fare riferimento a questa pagina anche con il nome postgresql_gestione_del_dbms.htm

[successivo] [precedente] [inizio] [fine] [indice generale] [indice ridotto] [indice analitico]

Valid ISO-HTML!

CSS validator!