Base de données

difuzio stocke tout dans une seule base : listes, abonnés, file d'envoi, jobs entrants, sessions, compteurs de réputation, audit. Deux backends sont disponibles, et le choix se fait à la compilation, pas au démarrage : un binaire ne contient qu'un seul dialecte.

MariaDB (par défaut) SQLite ("light")
Cible service multi-hôtes, plusieurs domaines, volume soutenu installation mono-hôte, quelques listes, faible volume
Serveur à administrer oui, MariaDB >= 10.6 non, un fichier .db
Plusieurs hôtes oui (workers répartis) non (SQLite est mono-writer)
Compilation make bin make bin-sqlite

Les deux backends exécutent le même code métier et la même suite de tests d'intégration ; ils ne diffèrent que par le dialecte SQL et le jeu de migrations, tous deux embarqués dans le binaire.

Construire la bonne variante

make bin           # binaire MariaDB, produit ./difuzio
make bin-sqlite    # binaire SQLite,  produit ./difuzio-sqlite

Sans le Makefile :

go build -o difuzio ./cmd/difuzio                       # MariaDB
go build -tags sqlite -o difuzio-sqlite ./cmd/difuzio   # SQLite

Le binaire SQLite n'embarque pas le driver MySQL, et réciproquement : donner un DSN de l'autre famille à un binaire produit une erreur d'ouverture, pas un repli silencieux.

Savoir quelle variante on exécute

Le backend compilé est affiché par version et par doctor :

$ difuzio version
difuzio 1.0.0 (go1.23.5 linux/amd64, MariaDB >= 10.6)

$ difuzio doctor --config /etc/difuzio/config.yaml
database: ok (MariaDB >= 10.6, UTC)
schema: ok (version 25, clean)

Avec le binaire SQLite, les mêmes commandes affichent SQLite. Nommer le fichier déployé en conséquence (difuzio / difuzio-sqlite) évite toute ambiguïté sur un serveur.

Le DSN

Le DSN (Data Source Name) est la chaîne de connexion à la base, portée par la clé db.dsn du fichier de configuration (voir Configuration) ou par l'option --dsn des commandes d'administration. Son format dépend du backend compilé.

DSN MariaDB

difuzio:MOTDEPASSE@tcp(127.0.0.1:3306)/difuzio?parseTime=true&loc=UTC&time_zone=%27%2B00%3A00%27&clientFoundRows=true

Les quatre paramètres parseTime=true, loc=UTC, time_zone='+00:00' et clientFoundRows=true ne sont pas optionnels : l'ouverture vérifie le fuseau de session et la version du serveur, et refuse de démarrer si l'un des invariants n'est pas tenu.

DSN SQLite

/var/lib/difuzio/difuzio.db

C'est un simple chemin de fichier (ou :memory: pour un usage de test). Les paramètres de verrouillage et les pragmas sont ajoutés par difuzio lui-même : journal WAL, foreign_keys activées, busy_timeout de 5 secondes, synchronous=NORMAL, et prise du verrou d'écriture dès l'ouverture de transaction. Il n'y a donc rien à régler dans le DSN, et rien à ajouter à la main.

Le répertoire qui contient le fichier doit rester inscriptible par le compte de service : SQLite y crée les fichiers annexes -wal et -shm.

Comptes et privilèges

Sous MariaDB, deux comptes distincts sont attendus :

  • un compte applicatif à moindre privilège (SELECT, INSERT, UPDATE, DELETE), utilisé par serve-web, serve-lmtp et worker ;
  • un compte de migration doté des privilèges DDL (Data Definition Language, c'est-à-dire les instructions qui définissent le schéma : CREATE, ALTER, DROP), fourni uniquement au moment d'appliquer les migrations.

Sous SQLite, cette séparation n'existe pas : il n'y a pas de comptes, ce sont les droits POSIX sur le fichier .db qui font foi. Le donner à l'utilisateur de service en 0600.

Migrations

Les commandes sont identiques sur les deux backends (voir Référence CLI) :

difuzio migrate up     --dsn "<DSN>"
difuzio migrate status --dsn "<DSN>"

Chaque binaire embarque le jeu de migrations de son dialecte ; il n'y a pas de DDL à appliquer à la main. Sous systemd, ces commandes ne sont même pas nécessaires : difuzio-migrate.service applique les migrations en attente avant chaque démarrage de la pile (voir Installation, section 4). Elles restent utiles pour migrer à un moment choisi, ou hors systemd.

Un schéma laissé "dirty" par un échec se répare avec migrate force <version> ; tant qu'il l'est, les services refusent de démarrer.

Sauvegarde

Sous MariaDB : mariadb-dump --single-transaction nocturne (compressé), plus les binlogs pour la restauration à un instant donné.

Sous SQLite, ne jamais copier le fichier .db à chaud avec cp : le journal WAL est actif et une copie du seul .db est incohérente. Utiliser la sauvegarde en ligne de l'outil sqlite3 :

sqlite3 /var/lib/difuzio/difuzio.db ".backup /sauvegardes/difuzio-$(date +%F).db"

Dans les deux cas, sauvegarder les keyrings à part, chiffrés : sans eux, une restauration ne permet pas de revérifier les tokens VERP et one-click en circulation (voir Installation).

La base ne contient pas le corps des messages : ceux-ci vivent dans storage.blob_dir (/var/lib/difuzio/messages par défaut) et doivent être sauvegardés avec elle. Une restauration de la seule base rend des archives dont tous les corps manquent. Voir Configuration pour le détail du stockage et Exploitation pour l'ordre de sauvegarde recommandé.

Limites du backend SQLite

  • Un seul hôte. SQLite est mono-writer sur un unique système de fichiers : on ne répartit pas les workers sur plusieurs machines. C'est un choix de déploiement assumé pour les petites installations, pas un réglage à contourner.
  • Volume modéré. Au-delà de quelques listes actives et d'un trafic soutenu, la sérialisation des écritures devient le facteur limitant : la recommandation reste MariaDB.
  • Pas de bascule automatisée. difuzio ne fournit pas d'outil de conversion d'un backend vers l'autre : le choix se fait à l'installation. Une migration ultérieure suppose une reprise de données par vos soins.