- PostgreSQL 18 peut cloner une base de données presque instantanément en combinant la stratégie de copie de fichiers (FILE_COPY) avec les fonctionnalités de clonage du système de fichiers
- Avec le nouveau paramètre
file_copy_method = clone, il est possible d’exploiter les capacités de clonage des systèmes de fichiers modernes (FICLONE) comme XFS, ZFS et APFS - Selon les benchmarks, pour le clonage d’une base de données de 6 Go, la méthode existante WAL_LOG prend environ 67 secondes, tandis que la méthode par clonage descend à environ 0,2 seconde
- Les bases clonées partagent au départ les mêmes blocs physiques, puis se séparent via le mécanisme copy-on-write lors des écritures
- En revanche, le clonage n’est possible qu’en l’absence de connexions actives et ne fonctionne qu’au sein d’un même système de fichiers
Structure de clonage basée sur les templates dans PostgreSQL
- Dans PostgreSQL, la commande
CREATE DATABASE dbnamecrée en interne une nouvelle base en clonant la basetemplate1- Cela correspond au même comportement que
CREATE DATABASE dbname TEMPLATE template1
- Cela correspond au même comportement que
- Il est possible d’indiquer une autre base à la place de
template1, ce qui permet le clonage via des templates personnalisés - Dans PostgreSQL 18, ce système de templates a été étendu vers une architecture permettant un clonage instantané
CREATE DATABASE ... STRATEGY
- Depuis PostgreSQL 15, le paramètre
CREATE DATABASE ... STRATEGYpermet de choisir la méthode de clonage- La valeur par défaut est
WAL_LOG, qui effectue une réplication bloc par bloc via le Write-Ahead Log - Cette méthode réduit la charge I/O et améliore la prise en charge de la concurrence, mais elle reste lente pour les gros clonages
- La valeur par défaut est
- En spécifiant
STRATEGY=FILE_COPY, il est possible de revenir à la méthode traditionnelle de copie de fichiers ; PostgreSQL 18 y ajoute une nouvelle option de clonage
FILE_COPY et file_copy_method
- Le paramètre
file_copy_methodde PostgreSQL 18 contrôle la méthode de clonage de fichiers au niveau du système d’exploitation- La valeur par défaut est
copy, qui lit tous les octets et les réécrit à un nouvel emplacement - En passant à
clone, PostgreSQL utilise la fonctionnalité de clonage du système de fichiers (FICLONE) pour réaliser un clonage instantané sans consommation d’espace supplémentaire
- La valeur par défaut est
- Systèmes de fichiers pris en charge : XFS, ZFS, APFS, FreeBSD ZFS
- Procédure de configuration
- Déployer le cluster PostgreSQL sur l’un de ces systèmes de fichiers
- Définir
file_copy_method = clone, puis recharger la configuration
Résultats des benchmarks
- Après la création d’une base de test d’environ 6 Go (
source_db), deux méthodes ont été comparées- Méthode
WAL_LOG: 67 000 ms (environ 67 secondes) - Méthode
FILE_COPY+clone: 212 ms
- Méthode
- À volume de données identique, on observe un gain de performance supérieur à 300x
- La base clonée (
fast_clone) n’utilise quasiment pas d’espace disque supplémentaire
Principe de fonctionnement des données clonées
- Avec
file_copy_method = clone, seules les métadonnées du système de fichiers sont dupliquées, ce qui fait que les deux bases partagent les mêmes blocs physiques - La taille de base remontée par PostgreSQL reste la même taille logique (environ 6 Go)
- Lorsqu’une écriture survient, le mécanisme copy-on-write (COW) s’active et sépare les pages concernées
- La page contenant les lignes modifiées
- La page où de nouveaux tuples sont écrits
- Les pages d’index ainsi que les pages FSM et visibility map, entre autres
- L’exécution de
VACUUMprovoque également des séparations de pages supplémentaires
Vérification des blocs partagés sur XFS
- La commande
filefrag -vpermet de vérifier si deux bases partagent les mêmes blocs physiques- À l’état initial, toutes les extents sont marquées
shared - Après mise à jour de quelques lignes, les 40 premiers blocs (environ 160 Ko) sont séparés et passent à des adresses physiques différentes
- Les autres extents restent partagées
- À l’état initial, toutes les extents sont marquées
Points d’attention et limites
- Aucune connexion active ne doit exister sur la base source au moment du clonage
- Il s’agit d’une contrainte de PostgreSQL, et non d’un problème du système de fichiers
- En production, il est courant d’utiliser une base template dédiée
- Le clonage n’est possible qu’au sein d’un seul système de fichiers
- Si plusieurs tablespaces sont répartis sur différents points de montage, PostgreSQL revient à une copie classique
- Dans les services cloud managés (AWS RDS, Google Cloud SQL, etc.), l’accès au système de fichiers n’est pas possible, donc cette fonctionnalité ne peut pas être utilisée
- En revanche, dans un environnement VM autogéré ou bare metal, un contrôle complet reste possible
Conclusion
- La fonctionnalité
file_copy_method = clonede PostgreSQL 18 exploite directement les capacités de clonage au niveau du système d’exploitation pour
réduire de façon spectaculaire le temps de clonage de bases de données volumineuses - Elle permet de mettre en place des workflows de bases de données clonables et réinitialisables instantanément pour les environnements de test, de développement et d’apprentissage
- Il reste toutefois nécessaire de concevoir l’exploitation en tenant compte de la contrainte sur les connexions actives et de la limitation à un système de fichiers unique
1 commentaires
Commentaires sur Hacker News
Pour ceux qui ne peuvent pas attendre ou qui ont besoin d’une isolation complète des instances avec PG18, j’ai créé Velo, un outil de branching instantané basé sur des snapshots ZFS
Ça fonctionne avec n’importe quelle version de PostgreSQL, et chaque branche a son propre conteneur et son propre port
Il faut environ 2 à 5 secondes pour créer une base de 100 Go
La différence avec l’approche de PG18, c’est que ça ne partage pas une seule instance et fournit une isolation complète du serveur
Lien GitHub
Dans le passé, quand mon entreprise migrait vers RDS, on avait construit en interne un système similaire
Des problèmes survenaient souvent pendant les migrations de production, donc pour les éviter, on avait automatisé les étapes suivantes
Grâce à ce processus, on a pu détecter beaucoup de bugs spécifiques à la production qui n’apparaissaient ni en local ni en CI
On a ensuite automatisé ça avec un simple script Ruby, et j’ai entendu dire qu’ils utilisent toujours ce script
Je découvre seulement maintenant que la stratégie de template cloning est configurable
J’ai utilisé Neon pour créer des environnements d’intégration en temps réel, et dans mon projet Golang pgtestdb, je crée pour chaque test une base Postgres complète avec toutes les migrations de schéma déjà appliquées
J’avais déjà vu dans une startup la création instantanée de bases de staging avec btrfs, et c’est intéressant de voir cette idée réapparaître régulièrement
Ce type de clonage rapide et de test est un énorme avantage de Postgres et de Sqlite, et j’aimerais que ce soit aussi possible avec Clickhouse ou MySQL
On dirait qu’aujourd’hui PostgreSQL est devenu la base de données passe-partout qui couvre presque tous les usages SQL
En plus, c’est gratuit
Je me demande s’il y a encore vraiment une raison d’utiliser une autre base SQL
Clickhouse est bien plus rapide pour l’analytique, et des bases comme Cassandra sont avantagées pour les workloads centrés sur l’écriture
Autrement dit, chaque base garde encore ses points forts
Quand le volume de données augmente, on rencontre des dégradations de performances ou des problèmes de migration
Dans mon cas, les performances du partitionnement natif étaient insuffisantes, donc j’ai dû implémenter moi-même un partitionnement personnalisé
Ce choix a plusieurs effets négatifs quand la charge augmente
C’est aussi un sujet abordé dans le billet de blog d’Uber
Malgré ça, dans le cloud, c’est toujours à Postgres que je fais le plus confiance
C’est pourquoi, pour les déploiements OLTP à grande échelle, c’est encore surtout MySQL qui est utilisé (par ex. YouTube, Uber)
En utilisant des structures de données immuables (HAMT), on peut créer une base de données capable de clonage instantané quel que soit le système de fichiers
J’ai dit que c’était théorique, mais je l’ai réellement implémenté
Je ne comprends pas pourquoi il n’existe pas davantage de bases fondées sur HAMT
Lien vers la documentation
Je ne savais pas que, dans Postgres v15, WAL_LOG était devenu la valeur par défaut
Dans un environnement de tests CI parallèles, il est plus logique de revenir à la stratégie FILE_COPY
J’avais ouvert une issue à ce sujet dans mon ancien projet integresql
J’ai déjà créé un simple outil GUI pgtt pour tester en local des applications basées sur Postgres
Ça simplifie énormément la configuration de l’environnement de développement
Ça pourrait aider pour les tâches répétitives de migrations SQL
J’ai aussi lu d’autres billets du blog, et dans l’ensemble c’est excellent
J’y ai notamment découvert pour la première fois les types range de Postgres
Je me demande si MariaDB a aussi ce genre de fonctionnalité
Remettre la base à l’état initial à chaque test est trop lent, donc je cherche une solution
On utilise MariaDB en production, donc changer de base serait compliqué
Cela dit, la solution côté Postgres a l’air meilleure
Cette méthode est assez efficace
AWS propose aussi une fonctionnalité similaire
Documentation sur les clones Aurora
C’est irréaliste pour des tests d’intégration