forked from AkshayAgarwal007/Jekyll-Mono
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path2008-02-04-dalle-tabelle-ai-file.html
19 lines (14 loc) · 9.33 KB
/
2008-02-04-dalle-tabelle-ai-file.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
---
layout: post
title: Dalle tabelle ai file...
date: '2008-02-04T12:21:00.000+01:00'
author: Luca Ferrari
tags:
- postgresql
modified_time: '2008-02-04T14:03:23.975+01:00'
blogger_id: tag:blogger.com,1999:blog-1836481905487384887.post-4802978521742254334
blogger_orig_url: http://fluca1978.blogspot.com/2008/02/dalle-tabelle-ai-file.html
permalink: /:year/:month/:day/:title.html
---
<h1>~</h1>
Come ogni buon RDBMS, PostgreSQL gestisce in modo trasparente i dati su supporto fisico (disco fisso), lasciando all'utente la cognizione del solo livello di gestione dei dati (relazioni, indici, ecc.). E' comunque possibile consultare i cataloghi interni di PostgreSQL per sapere dove e come vengano salvati i dati sul supporto fisico. In questo post verrà mostrato come trovare la corrispondenza fra dati e file su disco, e come calcolare lo spazio disco occupato da un database o da una tabella. Negli esempi che seguiranno si farà riferimento ad un database <span style="font-style: italic;">testdb</span> che contiene la tabella <span style="font-style: italic;">clienti</span> definita di seguito:<br /><br /><pre>testdb=# \d clienti<br /> Table "public.clienti"<br />Column | Type | Modifiers<br />--------+---------+------------------------------------------------------<br />pk | integer | not null default nextval('clienti_pk_seq'::regclass)<br />name | text |<br />address | text |<br />Indexes:<br /> "clienti_pkey" PRIMARY KEY, btree (pk)<br /></pre><br />Per recuperare le informazioni relative a dove i dati sono memorizzati occorre consultare il catalogo di sistema. In particolare le tabelle che maggiormente interessano sono:<br /><ul><li><span style="font-style: italic;">pg_database</span> contiene le informazioni generali sul database (nome, proprietario, tablespace, encoding, ecc.);</li><li><span style="font-style: italic;">pg_tablespace</span> contiene le informazioni specifiche sui vari tablespace definiti (locazione su disco, proprietario, ecc.);</li><li><span style="font-style: italic;">pg_roles</span> contiene gli utenti definiti nel sistema e il loro id numerico;</li><li><span style="font-style: italic;">pg_class</span> contiene le informazioni circa le tabelle definite in ogni database.</li></ul>La prima cosa da fare, per trovare il proprio database su disco, è quella di interrogare il catalogo dei database:<br /><br /><pre>select db.oid, -- identificativo del db<br /> db.datname, -- nome simbolico del db<br /> db.datdba, -- amministratore del db<br /> r.rolname, -- nome dell'amministratore<br /> db.dattablespace, -- identificativo del tablespace<br /> ts.spcname, -- nome simbolico del tablespace<br /> ts.spcowner, -- identificativo proprietario tablespace<br /> r2.rolname, -- nome simbolico del proprietario<br /> ts.spclocation -- locazione su disco<br />from (((pg_database db join pg_roles r on db.datdba = r.oid)<br /> left join pg_tablespace ts on db.dattablespace = ts.oid)<br /> join pg_roles r2 on ts.spcowner = r2.oid);<br /><br /> oid | datname | datdba | rolname | dattablespace | spcname | spcowner | rolname | spclocation<br />------+----------------+--------+----------------+---------------+-------------------+----------+----------+-----------------------------------<br />17318 | testdb | 16388 | luca | 1663 | pg_default | 10 | postgres |<br /></pre><br />Le colonne interessanti in questo caso sono <span style="font-style: italic;">pg_database.oid</span>, che indica l'id del database stesso. In particolare, su disco esisterà una directory con nome pari all'id del database (e quindi 17318). Si noti come il database risulti contenuto nel tablespace di default (<span style="font-style: italic;">spcname = pg_default</span>) e per questi non sia indicata una location particolare. Questo significa che la directory che contiene i file del database si troverà sotto $PGDATA/base/17318. In effetti si ha che:<br /><br /><pre>ls -lhd $PGDATA/base/17318/<br />drwx------ 2 postgres postgres 4,0K 2008-02-04 11:26 17318/</pre><br />All'interno della directory 17318 sono contenuti una serie di file, generalmente uno per oggetto del database. Ad esempio, ogni tabella sarà identificata nei cataloghi tramite un OID numerico che troverà corrispondenza in un file su disco con nome pari allo stesso OID. Ad esempio, per la tabella clienti si ha che:<br /><br /><pre>testdb=# select oid,relname, relpages, reltuples from pg_class where relname='clienti';<br /> oid | relname | relpages | reltuples<br />------+---------+----------+-----------<br />17321 | clienti | 291 | 36864</pre><br />La cosa interessante da notare è che la tabella clienti ha un OID 17321 e che occupa su disco 291 pagine per 36864 tuple (lo stesso dato si ottiene da un count sulla tabella).<br /><br />Ipotizzando una dimensione delle pagine di 8kB (il valore dipende dall'installazione di PostgreSQL), si può usare il numero di pagine per capire la dimensione del file/tabella su disco:<br /><br /><pre>testdb=# select relname,<br /> (relpages * 8 * 1024) as size_bytes,<br /> ( (relpages * 8 * 1024) / (1024 * 1024) ) as size_MB<br /> from pg_class where relname='clienti';<br /><br />relname | size_bytes | size_mb<br />--------+------------+---------<br />clienti | 2383872 | 2</pre><br />Come si nota, ci si aspetta una dimensione di 2,3 MB su disco per la tabella 17321, e in effetti si ha che:<br /><br /><pre>ls 17318/17321 -lh<br />-rw------- 1 postgres postgres 2,3M 2008-02-04 11:32 17318/17321</pre><br />Riassumendo quindi si ha che:<br /><ol><li>ad ogni database viene associato un OID numerico, memorizzato nel catalogo di sistema. Tale OID corrisponde ad una directory su disco (all'interno di $PGDATA/base se non si ha un tablespace particolare, altrimenti la directory è contenuta nel tablespace);</li><li>ogni oggetto di database, ad esempio una tabella, ha a sua volta un OID che corrisponde ad un file su disco con nome pari all'OID.</li></ol>Esistono anche funzioni appositamente studiate per visualizzare la dimensione di un database o di una tabella, in particolare:<br /><ul><li><span style="font-style: italic;">pg_database_size('database_name')</span> mostra la dimensione in bytes del database specificato;</li><li><span style="font-style: italic;">pg_relation_size('relation_name')</span> mostra la dimensione dei soli dati della relazione specificata;</li><li><span style="font-style: italic;">pg_total_relation_size('relation_name')</span> mostra la dimensione complessiva di una relazione, inclusi i dati e gli indici;</li><li><span style="font-style: italic;">pg_size_pretty(value)</span> formatta un valore in un formato umanamente leggibile.</li></ul>Quindi, per sapere la dimensione del database si può eseguire:<br /><br /><pre>testdb=# select pg_database_size('testdb'),<br /> pg_size_pretty(pg_database_size('testdb'));<br /><br />pg_database_size | pg_size_pretty<br />-----------------+----------------<br /> 6915800 | 6754 kB</pre>Il primo valore è in bytes, il secondo è in kB formattato automaticamente tramite la pg_size_pretty. Analogamente, per sapere la dimensione di una relazione si ha:<br /><br /><pre>testdb=# select pg_size_pretty( pg_relation_size('clienti') ),<br /> pg_size_pretty( pg_total_relation_size('clienti') );<br />pg_size_pretty | pg_size_pretty<br />----------------+----------------<br />2328 kB | 3000 kB</pre><br />Si noti come la dimensione dei soli dati corrisponde a 2,3 MB come già evidenziato, mentre si considerano anche gli indici si ha una dimensione di 3 MB.<br /><br />Si tenga presente che, per ragioni di praticità ed efficienza, PostgreSQL divide i dati di una relazione in gruppi da 1GB. Questo significa che se una relazione aumenta oltre 1GB, il relativo file su disco viene diviso anch'esso in blocchi da 1GB l'uno. Si supponga di aver aumentato la tabella clienti in modo da superare 1 GB di soli dati:<br /><br /><pre><br />testdb=# select pg_size_pretty( pg_relation_size('clienti') ),<br /> pg_size_pretty( pg_total_relation_size('clienti') );<br />pg_size_pretty | pg_size_pretty<br />---------------+----------------<br />1161 MB | 1484 MB<br /></pre><br />Su disco quello che è successo è che il file 17321 è stato diviso in due, nello specifico un 17321 (che contiene il primo GB di dati) e un 17321.1 (che contiene il secondo GB di dati). Qualora anche il secondo file raggiunga il suo limite, PostgreSQL provvederà a costruire un file 17321.2 e così via. A livello di catalogo di sistema questa cosa non viene mostrata, ovvero non esiste nella tabella pg_class un'entry per ogni file creato su disco, ma resta solo l'entry della relazione 17321 con il numero di pagine e tuple chiaramente aumentato.<br /><br /><pre>ls -lh 17318/17321*<br />-rw------- 1 postgres postgres 1,0G 2008-02-04 13:51 17318/17321<br />-rw------- 1 postgres postgres 138M 2008-02-04 13:52 17318/17321.1</pre><br />Una considerazione finale d'obbligo: sebbene si sia mostrato come risalire alla locazione fisica dei dati gestiti dal database si ricorda come manipolare manualmente tali dati possa risultare pericoloso per la stabilità e la coerenza dei dati stessi. E' quindi bene lasciare al database la gestione della corrispondenza fra lo spazio fisico e quello logico.