Table des matières


Créé le: 2019-11-13 ; Révisé le: 2019-11-13

Bases de données - Libérer de l’espace

Toutes les bases de données qui persistent leurs données sur un disque dur se doivent de trouver la façon la plus efficace de le faire.

La façon la plus simple est de créer un répertoire par “table” et un fichier par “rangée”, mais ce n’est pas vraiment la plus efficace lorsque nous avons des millions de fichiers à créer. De plus, chaque requête qui doit retourner quelques milliers de rangées devrait ouvrir des milliers de fichiers et les refermer.

C’est pourquoi, la majorité des bases de données vont tenter d’ouvrir le moins de fichiers possibles et créer leur propre structure interne. Dans le cas d’une base de données avec toutes les tailles maximales de colonnes connues d' avance, la structure interne aurait la même taille pour chaque rangée. S’il utilise un fichier par table, il devient facile de garder le fichier ouvert entre les requêtes et de sauter à des rangées précises puisqu’elle connaît la taille fixe à sauter. Lire et créer de nouvelles rangées est très facile dans ce cas.

Là où ça se corse, c’est lorsqu’il faut effacer des données. Prenons ce fichier avec une entrée par rangée:

Actif ID Valeur
Oui 1 aaa
Oui 2 bbb
Oui 3 ccc
Oui 4 ddd

Si nous voulons effacer la dernière rangée (ID 4), il suffit de tronquer le fichier après l’entrée précédente (ID 3). Par contre, si nous voulons effacer la rangée avec le ID 2, il n’est pas possible de faire un trou dans le fichier. Les bases de données vont donc simplement modifier l’indicateur “Actif” et le fichier deviendrait:

Actif ID Valeur
Oui 1 aaa
Non 2 bbb
Oui 3 ccc
Oui 4 ddd

Dans cet état, si quelqu’un demande de lister tous les ids de la table, il recevrait: 1,3,4. Tout va pour le mieux, mais nous avons un fichier qui est plus gros que désiré. La majorité du temps, cela n’est pas un problème puisque d’autres rangées seront éventuellement insérées et vont prendre sa place. Par exemple, si nous insérons le ID 5, le fichier serait ensuite comme suit:

Actif ID Valeur
Oui 1 aaa
Oui 5 eee
Oui 3 ccc
Oui 4 ddd

L’espace est réutilisée et il n’y a pas de gaspillage. Le cas où cela devient un problème est lorsque le disque dur commence à être pleins, que nous savons que plusieurs rangées contiennent des données qui ne nous intéressent plus et que nous sommes prêt à les perdre (ou les sauvegarder ailleurs avant de les effacer). Si nous effaçons ces données, ensuite, nous ne voyons pas d’espace disque libéré et l’exercice devient futile. C’est pourquoi toutes les bases de données permettent de compacter ou nettoyer les tables.

Pour ce faire, il y a plusieurs algorithmes qui sont utilisées alors lisez bien la documentation et comprenez bien les limitations de chacune. Voici quelques exemples:

  • Récréer la table et effacer l’ancienne
    • + c’est un algorithme très simple à implémenter
    • – il faut beaucoup d’espace disque libre puisque cela copie toutes les bonnes données. L’espace n’est libéré qu’à la fin de la copie
    • – comme toutes les données sont copiées, c’est lent
    • – très fréquemment, c’est une opération qui bloque l’accès à la table jusqu’à la fin de cette opération
  • Remplir les trous et tronquer
    • Si nous prenons le tableau avec ID 2 d’inactif, la rangée ID 4 serait copiée par-dessus ID 2 et ensuite le fichier pourrait être tronquer après ID 3
    • + N’a pas besoin de beaucoup d’espace
    • + Pourrait être fait sans bloquer les autres opérations sur la table (à confirmer dans la documentation)
    • – l’algorithme est plus complexe et donc pourrait conduire à plus de bogues
    • – si le processus s’arrête en plein milieux, est-ce que l’état de la base de données est garantie d’être correct? (vérifier la documentation)

Le bout théorique est maintenant terminé. Voici les différentes commandes à exécuter selon votre base de données:

Base de données Concept / Commande Documentation
PostgreSQL Vacuum https://www.postgresql.org/docs/current/sql-vacuum.html
Greenplum (utilise PosgreSQL) Vacuum https://gpdb.docs.pivotal.io/6-0/ref_guide/sql_commands/VACUUM.html
MySQL/MariaDB Optimize table https://dev.mysql.com/doc/refman/5.7/en/optimize-table.html
https://mariadb.com/kb/en/library/optimize-table/
MongoDB Compact https://docs.mongodb.com/manual/reference/command/compact/
Microsoft SQL sp_clean_db_free_space https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-clean-db-free-space-transact-sql?view=sql-server-ver15
H2 Shutdown compact http://www.h2database.com/html/features.html#compacting
DB2 Reclaim https://www.ibm.com/support/pages/how-reclaim-space-after-dropping-indexes-or-rows-db2-table