[successivo] [precedente] [inizio] [fine] [indice generale] [indice analitico]
PostgreSQL è 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 home 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, e 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, e come accennato si tratta generalmente dell'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:
postgres:!:100:101:PostgreSQL Server:/var/lib/pgsql:/bin/bash
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
nel secondo caso, l'attribuzione di una parola d'ordine all'utente postgres permetterà a una persona diversa di amministrare il DBMS.
#
passwd postgres
È bene ripetere che la directory home 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 farlo si avvale di alcune informazioni contenute nella directory definita dalla variabile di ambiente PGLIB, che dovrebbe corrispondere a /usr/lib/pgsql/
.
initdb [ opzioni ]
Lo schema sintattico mostra in modo molto semplice l'uso di initdb. Se si definiscono correttamente le variabili di ambiente PGLIB e PGDATA, si può fare anche a meno delle opzioni, diversamente diventa necessario dare queste due informazioni attraverso le opzioni della riga di comando.
La directory definita dalla variabile PGLIB, ovvero quella che di solito corrisponde a /usr/lib/pgsql/
, serve a initdb per raggiungere due file: global1.bki.source
e local1_template1.bki.source
. Questi due sono in pratica degli script che servono rispettivamente a generare i file della directory iniziale del sistema di basi di dati, ovvero ~postgres/*
(/var/lib/pgsql/*
), e della base di dati template1, corrispondente di solito al contenuto della directory ~postgres/base/template1/
. In breve, template1 è lo scheletro utilizzato per la creazione di ogni nuova base di dati.
Prima di avviare initdb, è bene utilizzare l'identità dell'utente amministratore di PostgreSQL:
#
su postgres
Successivamente, avviando initdb, con le indicazioni corrette delle directory corrispondenti alle variabili PGLIB e PGDATA, si ottengono delle segnalazioni simili a quelle seguenti (si presume che la directory iniziale PGDATA sia già stata creata e appartenga all'utente postgres).
postgres$
initdb --pglib=/usr/lib/pgsql --pgdata=/var/lib/pgsql
We are initializing the database system with username postgres (uid=100). This user will own all the files and must also own the server process. Creating Postgres database system directory /var/lib/pgsql/base Creating template database in /var/lib/pgsql/base/template1 Creating global classes in /var/lib/pgsql/base Adding template1 database to pg_database... Vacuuming template1 Creating public pg_user view Creating view pg_rules Creating view pg_views Creating view pg_tables Creating view pg_indexes Loading pg_description
--pglib= directory_pglib | -l directory_pglib
Permette di definire la directory all'interno della quale initdb deve cercare gli script che servono a ricreare il sistema di basi di dati di PostgreSQL.
--pgdata= directory_pgdata | -r directory_pgdata
Stabilisce la directory iniziale del sistema di basi di dati di PostgreSQL che si vuole creare.
--username= amministratore | -u amministratore
Questa opzione, permette eventualmente di utilizzare initdb con i privilegi dell'utente root, definendo in questo modo chi debba essere l'amministratore di PostgreSQL. In generale, questa opzione potrebbe anche non funzionare, e per evitare problemi, conviene avviare initdb utilizzando l'identità dell'amministratore PostgreSQL.
--template | -t
Fa in modo di ricostruire lo scheletro template1, senza intervenire negli altri dati del sistema di basi di dati. Può essere utile se per qualche motivo template1 risulta danneggiato.
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, e in tal caso si tratta normalmente del numero 5432). 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.
Generalmente, il demone postmaster viene avviato attraverso la procedura di inizializzazione del sistema, in modo indipendente dal supervisore Inet. In pratica, di solito si utilizza uno script collocato all'interno di /etc/rc.d/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-+-postgres | |-postgres | `-postgres ...
postmaster [ opzioni ]
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.
-D directory_dei_dati
Permette di specificare la directory di inizio della struttura dei dati del DBMS.
-S
Specifica che il programma deve funzionare in modo «silenzioso», senza emettere alcuna segnalazione, e soprattutto, diventando un processo discendente direttamente da quello iniziale (Init), disassociandosi dalla shell e quindi dal terminale da cui è stato avviato.
Questa opzione viene utilizzata particolarmente per avviare il programma all'interno della procedura di inizializzazione del sistema, quando non sono necessari dei controlli di funzionamento.
-b percorso_del_programma_terminale
Se il programma terminale, ovvero postgres, non si trova in uno dei percorsi contenuti nella variabile di ambiente PATH, è necessario specificare la sua collocazione (il percorso assoluto) attraverso questa opzione.
-d [ livello_di_diagnosi ]
Questa opzione permette di attivare la segnalazione di messaggi diagnostici (debug), da parte di postmaster e da parte dei programmi terminali, a più livelli di dettaglio:
1, segnala solo il traffico di connessione;
2, o superiore, attiva la segnalazione diagnostica anche nei programmi terminali, oltre ad aggiungere dettagli sul funzionamento di postmaster.
Di norma, i messaggi diagnostici vengono emessi attraverso lo standard output da parte di postmaster, anche quando si tratta di messaggi provenienti dai programmi terminali. Perché abbia significato usare questa opzione, occorre avviare postmaster senza l'opzione -S.
-i
Abilita le connessioni TCP/IP. Senza l'indicazione di questa opzione, sono ammissibili solo le connessioni locali attraverso socket di dominio UNIX (UNIX domain socket).
-p porta
Se viene avviato in modo da accettare le connessioni attraverso la rete (l'opzione -i), specifica una porta di ascolto diversa da quella predefinita (5432).
#
su postgres -c 'postmaster -S -D/var/lib/pgsql'
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'
Come nell'esempio precedente, specificando che si vuole consentire, in modo preliminare, l'accesso attraverso la rete.
#
su postgres -c 'nohup postmaster -D/var/lib/pgsql > /var/log/pglog 2>&1 &'
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 &'
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, e non al 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, e non può 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, e per questo occorre preparare uno script apposito.
#!/bin/sh LANG=it_IT.ISO-8859-1 # LC_CTYPE=it_IT.ISO-8859-1 # LC_COLLATE=it_IT.ISO-8859-1 # LC_MONETARY=it_IT.ISO-8859-1 export LANG # export LC_CTYPE LC_COLLATE LC_MONETARY /usr/bin/postmaster -i -S -D/var/lib/pgsql
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 sarà 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 /etc/rc.d/init.d/
, potrebbe essere necessario intervenire su quello che si occupa di avviare postmaster.
#!/bin/sh case "$1" in start) echo -n "Avvio del servizio PostgreSQL: " su -l postgres -c '/usr/bin/postmaster -i -S -D/var/lib/pgsql' echo ;; stop) echo -n "Disattivazione del servizio PostgreSQL: " killall postmaster echo ;; *) echo "Utilizzo: postgresql {start|stop}" exit 1 esac
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:
... case "$1" in start) echo -n "Avvio del servizio PostgreSQL: " # su -l postgres -c '/usr/bin/postmaster -i -S -D/var/lib/pgsql' su -l postgres -c '/usr/bin/avvia_postmaster' echo ;; ...
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 12.1 elenca le parole chiave che si possono assegnare a questa variabile e l'effetto che ne deriva.
Stile | Descrizione | Esempio |
ISO | ISO 8601 | 1999-12-31 |
SQL | Tipo tradizionale | 12/31/1999 |
German | 31.12.1999 |
Tabella 12.1. Elenco dei formati di data gestibili con PostgreSQL.
Probabilmente, la cosa migliore è utilizzare il formato ISO, e questo potrebbe anche diventare quello predefinito nelle prossime versioni di PostgreSQL. Volendo estendere lo script per l'avvio di postmaster, presentato all'inizio, basta aggiungere l'impostazione della variabile PGDATESTYLE:
#!/bin/sh LANG=it_IT.ISO-8859-1 # LC_CTYPE=it_IT.ISO-8859-1 # LC_COLLATE=it_IT.ISO-8859-1 # LC_MONETARY=it_IT.ISO-8859-1 export LANG # export LC_CTYPE LC_COLLATE LC_MONETARY PGDATESTYLE=ISO export PGDATESTYLE /usr/bin/postmaster -i -S -D/var/lib/pgsql
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--->
daniele
[Invio]
Enter user's postgres ID or RETURN to use unix user ID: 500 ->
[Invio]
In tal modo è stato definito l'inserimento dell'utente daniele, confermando il suo numero UID.
Is user "daniele" allowed to create databases (y/n)
y
[Invio]
All'utente daniele è stato concesso di creare delle nuove basi di dati.
Is user "daniele" allowed to add users? (y/n)
n
[Invio]
All'utente non viene concesso di aggiungere altri utenti.
createuser: daniele 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 --->
daniele
[Invio]
destroyuser: delete of user daniele 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 home 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), e ciò 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 verrà ripreso in seguito).
Inoltre, l'autenticazione può avvenire attraverso un sistema Kerberos, oppure attraverso il protocollo IDENT (capitolo ##capitolo-ident##). In quest'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:
local database autenticazione_utente [ mappa ]
host database indirizzo_IP maschera_degli_indirizzi autenticazione_utente [ mappa ]
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 il successivo, maschera_degli_indirizzi , rappresentano un gruppo di indirizzi di nodi che hanno diritto di accedere a quella determinata base di dati.
Il campo autenticazione_utente rappresenta il tipo di autenticazione attraverso una parola chiave. Le più comuni sono:
trust -- l'autenticazione non ha luogo e si accetta il nome fornito dall'utente senza alcuna verifica.
reject -- la connessione viene rifiutata in ogni caso.
password -- viene richiesta una parola d'ordine riferita all'utente, e questa viene verificata in base al contenuto di un file indicato nel campo successivo, oppure in base a quanto riportato dal catalogo ~postgres/pg_shadow
.
crypt -- viene richiesta una parola d'ordine riferita all'utente, e questa viene verificata 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.
ident -- l'autenticazione avviene attraverso il protocollo IDENT (capitolo ##capitolo-ident##), e in pratica viene demandato il riconoscimento al sistema remoto;
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.
Perché il sistema possa funzionare correttamente, sono sempre presenti almeno i record seguenti:
# tipo database IP maschera autorizz. # local all trust host all 127.0.0.1 255.255.255.255 trust
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.
# tipo database IP maschera autorizz. # host nostro_db 192.168.0.0 255.255.0.0 ident sameuser
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).
# tipo database IP maschera autorizz. # host nostro_db 192.168.0.0 255.255.0.0 password passwd
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, se nel file ~postgres/pg_hba.conf
compare il record
host nostro_db 192.168.0.0 255.255.0.0 password utenti
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:
tizio:wsLHjp.FutW0s caio:a6%i/.45w2q4
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.
pg_passwd file
L'utilizzo è banale, come si vede dall'esempio seguente in cui si aggiunge l'utente semproni (è importante ricordare di operare in qualità di utente postgres).
#
cd ~postgres
[Invio]
#
su postgres
[Invio]
postgres:~$
pg_passwd utenti
[Invio]
Username:
semproni
[Invio]
New password:
******
[Invio]
Re-enter new password:
******
[Invio]
La distribuzione GNU/Linux Debian è molto attenta alla coerenza dei pacchetti che si installano, e 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
che è già stato descritto in precedenza; e in particolare, 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 del file /etc/postgresql/postmaster.init
, attraverso il quale si possono controllare tante piccole cose, che altrimenti andrebbero controllate attraverso le opzioni della riga di comando del demone relativo.
# /etc/postgresql/postmaster.init # # Copyright (c) Oliver Elphick 1997 # Part of the Debian package, postgresql. The Debian packaging is # licensed under GPL v.2 # # This is the configurable initialisation of the postgresql package # The defaults are shown, but are commented out. # POSTGRES_HOME=`grep '^postgres:' /etc/passwd | awk -F: '{print $6}'` if [ -z "$POSTGRES_HOME" ] then POSTGRES_HOME=/var/postgres fi # Where to find the PostgreSQL database files, including those that # define PostgreSQL users and permissions. # POSTGRES_DATA=/var/postgres/data # Where to send logging and debugging traces # POSTGRES_LOG=/var/log/postgres.log # The number of shared-memory buffers the postmaster is # to allocate for backend server processes. Each buffer is 8Kb. # PGBUFFERS=64 # Debugging level at which the backend servers are to operate. # 1: trace connection traffic only; >=2: turn on debugging in the backends # giving more information according to the debug level. Debug logs are # sent to $POSTGRES_LOG # PGDEBUG=0 # Whether to echo queries to the debug log: yes/no # PGECHO=no # Whether to disable the fsync() call after each transaction. (If fsync() is # disabled, performance will improve at the cost of an increased risk of data # corruption in the event of power or other hardware failure.): yes/no # PGFSYNC=yes # How to present dates to the frontend. The choices are American (mm-dd-yyyy) # or European (dd-mm-yyyy) # PGDATESTYLE=European # How much memory to use for internal sorts before resorting to the disk. # This value is in kilobytes. # PGSORTMEM=512 # Whether to print timing and other statistics after each query: yes/no # PGSTATS=no # Whether to allow connections through TCP/IP as well as through Unix # sockets: yes/no. # By default, for greater security, we do not allow TCP/IP access. # This means that only users on this machine can access the database. PGALLOWTCPIP=yes # The Internet TCP port on which postmaster is to listen for connections # from frontend applications. # PGPORT=5432 # Locale setting for the postmaster and backend to use: this is not # necessary for USA users, but most others will probably want to set it; it # controls things like the format of numbers and dates. # for example, use `LANG=en_GB' for British English. LANG=it_IT
Quello che si vede è l'esempio del file predefinito con alcuni ritocchi per adattarlo alle particolarità locali. È importante sottolineare che per motivi di sicurezza, l'accesso tramite la rete viene impedito inizialmente, per cui occorre abilitare la cosa in modo esplicito, attraverso la direttiva PGALLOWTCPIP=yes, come si vede dall'esempio stesso.
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 destroydb, 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/
.
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
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 simbolo di sottolineatura.
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:
Connection to database 'template1' failed. FATAL 1:SetUserId: user "tizio" is not in "pg_user" createdb: database creation failed on mio_db.
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.
$
destroydb mio_db
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 di essere avviato è 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]
psql [ opzioni ] [ database ]
psql è un programma frontale (front-end) interattivo per l'invio di istruzioni SQL e l'emissione del risultato corrispondente. Si tratta di un cliente come gli altri, di conseguenza richiede la presenza di postmaster per instaurare una connessione con una copia del servente postgres.
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.
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.
-c 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 database
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
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 host
Permette di specificare il nodo a cui connettersi per l'interrogazione del servente PostgreSQL.
-H
Fa in modo che l'emissione di tabelle avvenga utilizzando il formato HTML 3.0. In pratica, ciò è utile per costruire un risultato da leggere attraverso un navigatore web.
-o file_output
Fa in modo che tutto l'output venga inviato nel file specificato dall'argomento.
-p porta
Nel caso in cui postmaster sia in ascolto su una porta TCP diversa dal numero 5432 (corrispondente al valore predefinito), si può specificare con questa opzione il numero corretto da utilizzare.
-q
Fa in modo che psql funzioni in modo «silenzioso», limitandosi al puro output delle istruzioni impartite. Questa opzione è utile quando si utilizza psql all'interno di script che devono occuparsi di rielaborare il risultato ottenuto.
-t
Disattiva l'emissione dei nomi delle colonne. Questa opzione viene utilizzata particolarmente in abbinamento con -c o -q.
-T 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
Fa in modo che psql richieda il nominativo-utente e la parola d'ordine all'utente, prima di tentare la connessione. L'uso di questa opzione è indispensabile quando il servente impone una forma di autenticazione definita attraverso la parola chiave password.
Oltre alle istruzioni SQL, psql riconosce dei comandi, alcuni dei quali vengono descritti di seguito.
\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 UID dei rispettivi amministratori (gli utenti che li hanno creati), e il nome della directory in cui sono collocati fisicamente.
\connect database [ 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.
\d [ tabella ]
L'opzione \d usata da sola, elenca le tabelle contenute nella base di dati, altrimenti, se viene indicato il nome di una di queste tabelle, si ottiene l'elenco delle colonne. Se si utilizza il comando \d *, si ottiene l'elenco di tutte le tabelle con le informazioni su tutte le colonne rispettive.
\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.
Il programma psql può restituire i valori seguenti:
$
psql mio_db
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
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
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
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
Cerca di connettersi con la base di dati mio_db nel nodo locale, utilizzando il meccanismo del socket di dominio UNIX, e quindi esegue le istruzioni contenute nel file istruzioni.sql
.
psql è sensibile alla presenza o meno della variabile di ambiente PAGER. Se questa esiste, e non è vuota, psql userà 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,
PAGER=less export PAGER
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:
PAGER= export PAGER
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 [VERBOSE] [ANALYZE] [ nome_tabella ]
VACUUM [VERBOSE] ANALYZE [ nome_tabella [( colonna_1 [,... colonna_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 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 attraverso 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 <ttid>base di dati</ttid> 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 fondamentale, che permette di intervenire sui cataloghi di sistema), e da lì accedere al catalogo pg_database, in modo da 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 verrà 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, e comunque la documentazione di PostgreSQL fa spesso riferimento a queste, e quindi 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 attraverso un comando simile a quello seguente:
postgres:~$
psql -d template1
Il catalogo pg_user è una vista del catalogo pg_shadow, che contiene le informazioni sugli utenti di PostgreSQL. La figura 12.1 mostra un esempio di come potrebbe essere composta. La consultazione della tabella si ottiene con il comando SQL:
template1=>
SELECT * FROM pg_user;
usename |usesysid|usecreatedb|usetrace|usesuper|usecatupd|passwd |valuntil --------|--------|-----------|--------|--------|---------|--------|---------- postgres| 100|t |t |t |t |********|Sat Jan 31 nobody | 99|f |t |f |t |********| tizio | 1001|t |t |t |t |********| Figura 12.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 12.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;
usename |usesysid|usecreatedb|usetrace|usesuper|usecatupd|passwd|valuntil --------|--------|-----------|--------|--------|---------|------|---------- postgres| 100|t |t |t |t | |Sat Jan 31 nobody | 99|f |t |f |t | | tizio | 1001|t |t |t |t | | Figura 12.2. Esempio di un catalogo pg_shadow. |
Il catalogo pg_database è una tabella che contiene le informazioni sulle basi di dati esistenti. La figura 12.3 mostra un esempio di come potrebbe essere composta. La consultazione della tabella si ottiene con il comando SQL:
template1=>
SELECT * FROM pg_database;
datname |datdba|encoding|datpath ---------|------|--------|-------------------- template1| 100| 0|template1 pubblico | 100| 0|pubblico prova | 100| 0|/home/postgres/prova prova1 | 100| 0|prova1 prova2 | 1001| 0|prova2 Figura 12.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/
, e corrispondono 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, e forse conviene cercare di capirlo intuitivamente, chiarendo che 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/
, e quindi non si dovrebbero vedere percorsi assoluti in questa tabella. Verrà 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, e in tal caso dipendere 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. Per esempio,
#
tar czvf base.tar.gz ~postgres/base
archivia nel file base.tar.gz
tutte le basi di dati che si articolano a partire da ~postgres/base/
. Come esempio ulteriore,
#
tar czvf pubblico.tar.gz ~postgres/base/pubblico
archivia nel file pubblico.tar.gz
solo la base di dati pubblico, che si trova esattamente nella directory ~postgres/base/pubblico/
.
Il recupero non è nulla di speciale, tranne per il fatto che si deve recuperare una base dati per intero, ovvero ciò che di solito si articola in una sottodirectory di ~postgres/base/
. Se di 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, ed è 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 destroydb, e di ricrearla 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
#
mkdir /home/postgresql/base
#
chown -R postgres. /home/postgresql
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
Per concludere, se si osserva il catalogo pg_database, si noterà 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, e 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 erano 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.
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,
$
pg_dump mio_db > mio_db.dump
si ottiene il file di testo mio_db.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, ed eventualmente, può 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
-d
In condizioni normali, pg_dump salva i dati delle relazioni (le tabella secondo l'SQL) in una forma compatibile con il comando COPY che non è compatibile con lo standard SQL. Con l'opzione -d, utilizza il comando INSERT tradizionale.
-D
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
Permette di definire un file diverso dallo standard output, che si vuole generare con il risultato dell'elaborazione di pg_dump.
-h host
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
Nel caso in cui postmaster sia in ascolto su una porta TCP diversa dal numero 5432 (corrispondente al valore predefinito), si può specificare con questa opzione il numero corretto da utilizzare.
-s
Scarica soltanto la struttura delle relazioni, senza occuparsi del loro contenuto. In pratica, serve per poter riprodurre vuote le tabelle SQL.
-t nome_tabella
Utilizzando questa opzione, indicando il nome di una tabella SQL, si ottiene lo scarico di quell'unica tabella.
-u
Fa in modo che psql richieda il nominativo-utente e la parola d'ordine all'utente, prima di tentare la connessione. L'uso di questa opzione è indispensabile quando il servente impone una forma di autenticazione definita attraverso la parola chiave password.
-z
Include le informazioni sui permessi e la proprietà delle tabelle (GRANT/REVOKE).
Per copiare o trasferire tutte le basi di dati del sistema di PostgreSQL, si può utilizzare pg_dumpall, che in pratica è uno script che si avvale di pg_dump per compiere il suo lavoro.
pg_dumpall [ opzioni ]
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.
Gli argomenti della riga di comando di pg_dumpall, vengono passati tali e quali a pg_dump, quando questo viene utilizzato all'interno dello script per lo scarico di ogni singola base di dati.
postgres$
pg_dumpall > basi_dati.dump
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, ed 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
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/pg_hda.conf
per la configurazione dei sistemi di accesso e autenticazione, deve essere ripristinato manualmente.
PostgreSQL
The PostgreSQL Development Team, PostgreSQL Tutorial
/usr/share/doc/postgres*/tutorial/index.html
/usr/share/doc/postgres*/tutorial.ps*
The PostgreSQL Development Team, PostgreSQL User's Guide
/usr/share/doc/postgres*/user/index.html
/usr/share/doc/postgres*/user.ps*
The PostgreSQL Development Team, PostgreSQL Programmer's Guide
/usr/share/doc/postgres*/programmer/index.html
/usr/share/doc/postgres*/programmer.ps*
Al Dev (Alavoor Vasudevan), PostgreSQL HOWTO
1) 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.
2) Per consentire in pratica l'accesso attraverso la rete, occorre anche intervenire all'interno del file di configurazione ~postgres/pg_hda.conf
.
3) L'autenticazione IDENT prevede anche l'uso di un file di mappa aggiuntivo, che viene preso in considerazione quando al posto della parola chiave sameuser si indica qualcosa d'altro. Tuttavia, la documentazione sul modo in cui debba essere predisposto questo file non è disponibile allo stato attuale.
4) 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 ~postgres/pg_database
.
5) 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.
6) 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, e questo implica 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 5432. L'uso di queste variabili non è indispensabile, ma serve solo per non dover specificare queste informazioni attraverso opzioni della riga di comando.
7) 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.
8) 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. La configurazione normale prevede che il nodo locale (127.0.0.1) possa accedere con un'autenticazione di tipo trust, e ciò permette di cambiare il nome dell'utente in questo comando.
9) 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] [indice analitico]