pgxpool est son pool de connexions. Dans ce guide, vous allez connecter un service Go à ClickHouse Managed Postgres via une connexion TLS vérifiée, créer une table todos à l’aide d’une migration golang-migrate, puis traiter des requêtes de création, de lecture, de mise à jour et de suppression depuis un serveur net/http.
Prérequis
- Go 1.25 ou version ultérieure. Ce guide a été testé avec Go 1.27.1, pgx 5.11.0 et golang-migrate 4.20.1.
- Un compte ClickHouse Cloud
psql, pour créer la base de données. Vous pouvez également exécuter le statementCREATE DATABASEdans la console SQL.
Créer un service ClickHouse Managed Postgres
Dans la console ClickHouse Cloud, cliquez sur New service et sélectionnez Postgres. L’instance est prête en quelques minutes. Pour une procédure pas à pas, consultez le guide de démarrage rapide.Obtenir vos informations de connexion
Cliquez sur Connect dans la barre latérale gauche de votre service. Laissez Directly sélectionné et activez Use SSL. L’URL de connexion de l’onglet url utilise désormais le port5432 et se termine par sslmode=verify-full&sslrootcert=<service-name>-ca-certificate.pem. Cliquez sur Download certificat de CA. Vous pourrez également le télécharger plus tard depuis Settings → certificat de CA. Ce certificat est propre à votre instance, ce qui permet à pgx de vérifier qu’il communique bien avec votre serveur.
Dans ce guide, la connexion à Postgres se fait directement sur le port 5432, aussi bien pour les migrations que pour l’application. Un service Go est un processus de longue durée, et pgxpool y maintient déjà un pool de connexions : un second pooler est donc inutile. Si vous exécutez de nombreuses instances du service et avez besoin de plus de connexions client que Postgres n’en autorise, utilisez le PgBouncer intégré (via PgBouncer, port 6432) pour l’application ; consultez Utiliser PgBouncer, qui nécessite un paramètre de connexion supplémentaire.
Configurer le projet
Créez un module Go, ajoutez pgx, puis installez la CLImigrate avec le driver pgx :
-tags 'pgx5' compile la CLI migrate avec son driver pgx v5, qui utilise le schéma d’URL pgx5://. go install place le binaire dans $GOBIN, ou dans $(go env GOPATH)/bin si GOBIN n’est pas défini ; veillez donc à ce que ce répertoire figure dans votre PATH.
Configurer la connexion
Déplacez le certificat de CA téléchargé dans le répertoire du projet, puis renommez-le enca-certificate.pem.
Créez une base de données pour l’application. Remplacez <PASSWORD> et l’hôte par les valeurs affichées dans la fenêtre modale Connect :
guide_go et ne diffèrent que par le schéma d’URL : l’application lit DATABASE_URL, tandis que la CLI migrate utilise MIGRATE_URL :
libpq. Avec sslmode=verify-full, il charge le fichier de CA indiqué par sslrootcert et vérifie à la fois la chaîne de certificats et le nom d’hôte; vous n’avez donc besoin d’aucun code TLS. Le path sslrootcert est résolu par rapport au répertoire depuis lequel vous exécutez les commandes. Si votre mot de passe contient des caractères spéciaux tels que @, / ou #, encodez-les au format URL.
Créer le schéma à l’aide d’une migration
Créez les fichiers de migration :up :
migrations/000001_create_todos.up.sql
down, qui l’annule :
migrations/000001_create_todos.down.sql
migrate enregistre la version actuelle dans la table schema_migrations et n’applique ensuite que les migrations plus récentes. Versionnez le répertoire migrations avec votre code.
Exécutez toujours
migrate via la connexion directe (port 5432). Pendant son exécution, il détient un verrou consultatif (advisory lock) au niveau de la session, afin d’empêcher deux déploiements d’effectuer une migration en même temps. Avec PgBouncer, le verrouillage et le déverrouillage peuvent s’exécuter sur des connexions Postgres différentes : le verrou n’est alors jamais libéré, et les exécutions suivantes de migrate se bloquent ou échouent avec l’erreur timeout: can't acquire database lock.Interroger la base de données
Créezdb.go. Ce fichier crée le pool à partir de DATABASE_URL et vérifie la connexion au démarrage en demandant à Postgres quelle version de TLS est utilisée par la session :
db.go
todos.go avec les handlers HTTP. Chaque handler exécute une requête paramétrée sur le pool, puis pgx.CollectRows et pgx.CollectExactlyOneRow mappent les lignes vers la struct Todo en se basant sur le nom des colonnes :
todos.go
$1) plutôt que de les insérer dans la string SQL protège contre les injections SQL : pgx les envoie séparément du texte de la requête. Inutile de vérifier séparément l’erreur renvoyée par pool.Query : pgx.CollectRows et pgx.CollectExactlyOneRow la renvoient.
Créez main.go. Ce fichier crée un pool unique pour l’ensemble du processus, sert les routes sur le port 3114 et ferme le pool lors d’un Ctrl+C. Dans une application existante, appelez plutôt newPool une seule fois au démarrage, puis registerTodoRoutes sur votre http.ServeMux :
main.go
Exécuter et vérifier
Ajoutez les dépendances restantes depgxpool dans go.mod et go.sum, puis démarrez le serveur :
TLSv1.3 provient de pg_stat_ssl sur le serveur, ce qui confirme que la session est bien chiffrée. Si vous faites pointer sslrootcert vers tout autre certificat, le serveur ne démarre pas et inscrit dans ses logs x509: certificate signed by unknown authority, preuve que le certificat est réellement vérifié.
Dans un second terminal, créez deux tâches, marquez la première comme terminée et supprimez la seconde :
PATCH renvoie la ligne mise à jour :
http://localhost:3114/todos dans votre navigateur pour afficher la liste des tâches restantes. pgx renvoie les valeurs timestamptz dans votre fuseau horaire local. La réponse se présente ainsi :
Shutting down dans les logs et ferme le pool.
Pour afficher les données dans la console, ouvrez console SQL dans la barre latérale gauche de votre service, développez guide_go puis public, et cliquez sur la table todos. La table schema_migrations, juste à côté, contient la version de migration. La table todos contient la ligne restante :
Utiliser PgBouncer
Pour faire transiter les requêtes de l’application par le PgBouncer intégré, sélectionnez via PgBouncer dans la fenêtre modale Connect, remplacez le port deDATABASE_URL par 6432, puis ajoutez default_query_exec_mode=cache_describe. Laissez MIGRATE_URL sur le port 5432 :
default_query_exec_mode depuis l’URL et ne l’envoie pas au serveur. Aucune modification du code n’est nécessaire, et le même certificat de CA fonctionne. Le journal de démarrage affiche désormais TLS: none, car pg_stat_ssl décrit la connexion de PgBouncer lui-même à Postgres. La connexion de votre application à PgBouncer reste bien vérifiée : un certificat de CA incorrect provoque le même échec.
PgBouncer fonctionne en mode pool de connexions par transaction ; chaque transaction peut donc s’exécuter sur une connexion Postgres différente :
- Les transactions ouvertes avec
pool.Beginoupgx.BeginFuncfonctionnent normalement. - Les paramètres de session définis avec
SETne restent pas attachés à votre connexion et peuvent se propager à d’autres clients. Utilisez plutôtSET LOCALà l’intérieur d’une transaction. PgBouncer rejette égalementsearch_pathdans l’URL de connexion avec l’erreurunsupported startup parameter: search_path; préfixez plutôt les noms de tables par leur schéma. - Les commandes SQL
PREPAREetEXECUTE,LISTENainsi que les verrous consultatifs de session ne fonctionnent pas.
Étapes suivantes
- Connexion : chaînes de connexion, PgBouncer et TLS
- Paramètres : paramètres Postgres et PgBouncer, comme
max_connections - Répliques en lecture : acheminer les requêtes en lecture seule vers une réplique avec un second
pgxpool.Pool - Sécurité : listes d’accès IP et réseau privé