Annexe F. Connaître l'espace disque occupé par les données (dbsize)

Table des matières

F.1. Dbsize - directement dans le backend de PostgreSQL -
F.2. Script Shell
F.3. Script PHP

Avertissement

Depuis la version 8.1.0, le sous-répertoire contrib/dbsize ne fait plus partie de la distribution des sources de PostgreSQL - pour une raison que j'ignore d'ailleurs -. Mais il était présent pour les versions 8.0.X. Pour voir les modifications apportées, merci de consulter le lien suivant

http://traduc.postgresqlfr.org/pgsql-8.1.1-fr/release-8-1.html

La gestion des données dont doit s'acquiter un administrateur de PostgreSQL est une tâche parfois bien ardu. Cette dernière concerne notamment la gestion du volume physique occupée par les données. Il existe à ce jour des solutions logiciels pour pouvoir gérer ce genre de problématique. Mais ici, on travaille à l'ancienne = "Je n'ai foi qu'en ce que je vois d'écrit dans mon terminal Shell" dixit Gerald.... "Ouais! Mais c'est moi qui me tape la doc!", dixit David... Avant toute chose, la solution ici exposée n'est pas nécessairement la plus belle.

Il est tout à fait possible de connaître la taille qu'occupent les bases ou les tables en ayant recours à des requêtes, ou en utilisant VACUUM etc... - voir pour cela C:\PostgreSQL\8.2.1\doc\postgresql\html\diskusage.html -...Celle que nous avons retenue est dbsize qui est fournie avec les sources de PostgreSQL.

F.1. Dbsize - directement dans le backend de PostgreSQL -

Dbsize faisait partie des outils de contribution de PostgreSQL. Il a été directement inclut maintenant dans le backend de PostgreSQL: les fonctions de ce module sont maintenant "incluses" dans PostgreSQL. Pour avoir une liste des fonctions disponibles avec ce module, on pourra essayer par exempel depuis MinGW la commande

psql -d template1 -AtF " " -c "\df pg_*_size" | awk '{print $2}'

qui nous renverra

pg_column_size
pg_database_size
pg_database_size
pg_relation_size
pg_relation_size
pg_tablespace_size
pg_tablespace_size
pg_total_relation_size
pg_total_relation_size

F.2. Script Shell

Avec MinGW, il est possible par exemple d'utiliser le script suivant

hote="localhost"
base="madatabase"
port="5432"
user="david"

liste_Tables="$(psql -h ${hote} -p ${port} -U ${user} -d ${base} -c "select \
tablename from pg_tables where (tablename not like 'pg_%') and \
 (tablename not like 'sql%' ) order by tablename" \
 | grep -v "\-\-\-" | grep -v "tablename" | grep -v "(")"

for j in ${liste_Tables}
do
echo -n $j..................
Taille_Table="select \
pg_size_pretty(tablesize+indexsize+toastsize+toastindexsize) \
FROM \
(SELECT pg_relation_size(cl.oid) AS tablesize, \
 COALESCE((SELECT SUM(pg_relation_size(indexrelid))::bigint \
      FROM pg_index WHERE cl.oid=indrelid), 0) AS indexsize, \
 CASE WHEN \
      reltoastrelid=0 THEN 0 \
          ELSE pg_relation_size(reltoastrelid) \
      END AS toastsize, \
 CASE WHEN reltoastrelid=0 THEN 0 \
      ELSE pg_relation_size((SELECT reltoastidxid FROM pg_class ct  \
                             WHERE ct.oid = cl.reltoastrelid))  \
      END AS toastindexsize \
FROM pg_class cl \
      WHERE relname = '${j}') ss"

psql -h ${hote} -p ${port} -U ${user} -d ${base} -c "${Taille_Table}" |\
 grep -v "\-\-\-" | grep -v "pg_size_pretty" | grep -v "("
done

qui nous renverra en sortie par exemple

buildings.................. 40 kB

geometry_columns.................. 24 kB

great_roads.................. 40 kB

mapserver_desc.................. 32 kB

parcs.................. 40 kB

personnes.................. 40 kB

rivers.................. 40 kB

small_roads.................. 40 kB

spatial_ref_sys.................. 2104 kB

F.3. Script PHP

Est proposé ci-dessous un petit script php permettant de connaître la taille de chacune des tables d'une base. Est pris en compte le toasting et l'indexage éventuel (voir la doc officielle de PostgreSQL pour de plus amples informations)

<?php
//
// Ce script permet de connaitre la taille des diverses tables contenues sur la 
// base ...
//
// Paramètres à adapter pour la connexion à PostgreSQL
//
$hote="localhost";
$base_de_donnees="ma_base_de_donnees";
$utilisateur="utilisateur";
$mot_de_passe="mot_de_passe";
//
// Chargement de la librairie PostgreSQL pour PHP
//
switch (PHP_OS)
{

case "WINNT": if (!extension_loaded('pgsql'))  dl("pgsql.dll");
              break;

default:  if (!extension_loaded('pgsql'))  dl("php_pgsql.so");
          break;

}
//
// Connexion au serveur PostgreSQL
//
	$db_handle = pg_connect("host=".$hote." dbname=".$base_de_donnees." 
                        user=".$utilisateur." password=".$mot_de_passe."");

$Requete_Listing_Table = "select tablename as nom_table from pg_tables 
where (tablename not like 'pg_%') and
(tablename not like 'spatial_ref_sys' ) and (tablename not like 'sql%' )
and (tablename not like 'geom%' ) order by tablename";

$Resultat_Listing_Table = pg_exec( $db_handle, $Requete_Listing_Table);

echo "<table border='1'>";

for($Iter_Table=0;$Iter_Table<pg_numrows($Resultat_Listing_Table);$Iter_Table++)
{
    $Nom_Table = pg_result( $Resultat_Listing_Table,$Iter_Table,0);
    
    
    $Requete_Table_Size = "SELECT 
    pg_size_pretty(tablesize+indexsize+toastsize+toastindexsize) AS totalsize
FROM
(SELECT pg_relation_size(cl.oid) AS tablesize,
        COALESCE((SELECT SUM(pg_relation_size(indexrelid))::bigint
                  FROM pg_index WHERE cl.oid=indrelid), 0) AS indexsize,
        CASE WHEN reltoastrelid=0 THEN 0
             ELSE pg_relation_size(reltoastrelid)
        END AS toastsize,
        CASE WHEN reltoastrelid=0 THEN 0
             ELSE pg_relation_size((SELECT reltoastidxid FROM pg_class ct
                                    WHERE ct.oid = cl.reltoastrelid))
        END AS toastindexsize
 FROM pg_class cl
 WHERE relname = '".$Nom_Table."') ss";
 
 $Resultat_Table_Size = pg_result( pg_exec( $db_handle, $Requete_Table_Size),0,0);
 
 echo "<tr><td>".$Nom_Table."</td><td>".$Resultat_Table_Size."</td></tr>\n";
    
}

echo "</table>";
	pg_close($db_handle);
	
?>