Aller au contenu
Blog

Sauvegarder un serveur FiveM et sa base, tester la restauration

mysqldump pour oxmysql, fichiers du serveur, chiffrement, test de restauration hebdo, et comment rendre son inventaire à un joueur sans rollback de la ville.

Par Termi

11 min de lecture
  • Backups
  • Database
  • oxmysql
Sur cette page

Pour sauvegarder un serveur FiveM, faites un dump de la base MySQL ou MariaDB à laquelle oxmysql se connecte avec mysqldump --single-transaction, archivez server.cfg, vos resources et txData, chiffrez les deux, puis copiez-les hors de la machine. Une sauvegarde ne compte qu’une fois restaurée : chargez-en une chaque semaine dans une base jetable. Pour rendre son inventaire à un joueur, restaurez dans cette base jetable et ne recopiez que ses lignes.

Ce guide fait tout cela à la main avec des outils gratuits, sous Linux ou sous Windows avec Git Bash. Rien ici ne demande FiveDock. À la fin, la même chose faite pour vous, avec Deploy Guard, qui sauvegarde avant chaque redémarrage.

Ce que doit contenir une sauvegarde FiveM

  • La base de données. Personnages, argent, inventaires, véhicules, maisons, messages du téléphone : tout ce que stockent ESX, QBCore, Qbox et ox_inventory s’y trouve. Elle change à chaque minute, c’est donc elle qu’il faut sauvegarder le plus souvent.
  • server.cfg. L’ordre de vos resources, les convars, les permissions, le mot de passe de la base et votre sv_licenseKey.
  • resources. Vos scripts, maps et véhicules, avec toutes les modifications faites aux scripts achetés.
  • txData. Les réglages de txAdmin, les admins et l’historique des joueurs.

Laissez de côté cache : FXServer le reconstruit au prochain démarrage, et c’est souvent le plus gros dossier du disque. Les logs peuvent aussi rester de côté.

Trouver la base qu’utilise oxmysql

oxmysql lit sa connexion dans server.cfg :

server.cfg
set mysql_connection_string "mysql://fivem:[email protected]/fivem?charset=utf8mb4"

Soit l’utilisateur fivem, le mot de passe secret, l’hôte 127.0.0.1 et la base fivem. Certains serveurs utilisent l’ancienne forme server=127.0.0.1;database=fivem;userid=fivem;password=secret, qui contient les mêmes quatre valeurs.

Dumper la base avec mysqldump

Mettez les identifiants dans un fichier que vous seul pouvez lire, pour que le mot de passe n’apparaisse ni dans la liste des processus ni dans l’historique du shell :

bash
cat > "$HOME/.fivem-backup.cnf" <<'EOF'
[client]
user=fivem
password=secret
host=127.0.0.1
EOF
chmod 600 "$HOME/.fivem-backup.cnf"

Puis dumpez la base pendant que le serveur continue de tourner :

bash
mysqldump --defaults-extra-file="$HOME/.fivem-backup.cnf" \
  --single-transaction --quick --no-tablespaces \
  --default-character-set=utf8mb4 --hex-blob \
  fivem | gzip > "fivem-$(date +%F-%H%M).sql.gz"
  • --single-transaction lit toutes les tables InnoDB dans un snapshot cohérent sans les verrouiller : les joueurs continuent de jouer, et l’argent de users correspond aux items de ox_inventory.
  • --quick envoie les lignes au fil de l’eau au lieu de charger des tables entières en mémoire, ce qui compte dès que les logs et les tables du téléphone atteignent des millions de lignes.
  • --no-tablespaces évite une erreur de privilège sur MySQL 8 (voir les erreurs).
  • --default-character-set=utf8mb4 et --hex-blob préservent les emojis dans les noms de personnages et les colonnes binaires.

Sous MariaDB, la même commande s’appelle aussi mariadb-dump, avec les mêmes options. Si vos scripts utilisent des procédures stockées, ajoutez --routines.

Vérifier les tables MyISAM

Le snapshot ne couvre que les tables InnoDB. Une table MyISAM est lue à un instant légèrement différent du reste : une sauvegarde faite pendant un échange peut contenir l’argent d’avant et l’item d’après. ALTER TABLE name ENGINE=InnoDB; convertit une table.

Sauvegarder les fichiers du serveur

bash
tar -czf "files-$(date +%F-%H%M).tar.gz" \
  --exclude='server-data/cache' \
  -C /home/fivem server-data txData

Pointez -C sur le dossier qui contient server-data et txData. Sous Windows, tar est fourni avec Windows 10 et 11 et accepte les mêmes options.

Chiffrer avant que ça ne quitte la machine

Un dump de base contient les identifiants de tous les joueurs, et server.cfg contient le mot de passe de la base et votre clé de licence. Quiconque obtient une copie peut tout lire, ou lancer un serveur avec votre clé. Chiffrez avec age et une clé publique : le serveur peut chiffrer les sauvegardes mais pas les ouvrir, donc un serveur volé ne livre pas ses propres sauvegardes.

Générez la paire de clés sur votre propre ordinateur, pas sur le serveur :

bash
age-keygen -o fivem-backup.key
# Public key: age1q9x...

Gardez fivem-backup.key dans votre gestionnaire de mots de passe et ne donnez au serveur que la clé publique, celle qui commence par age1 :

bash
age -r age1q9x... -o fivem-2026-10-15-0400.sql.gz.age fivem-2026-10-15-0400.sql.gz

Si vous perdez la clé privée, toutes les sauvegardes qu’elle a chiffrées sont perdues avec elle. Gardez-en deux copies, à deux endroits différents.

Garder des copies hors du serveur

Une sauvegarde sur le même disque disparaît avec lui, que le disque lâche, que l’hébergeur résilie votre contrat ou que quelqu’un efface la machine. Copiez chaque sauvegarde vers un stockage objet comme Backblaze B2, Cloudflare R2 ou S3 avec rclone. Donnez au serveur une clé de stockage qui peut envoyer des fichiers mais pas les supprimer : celui qui entre sur le serveur ne pourra pas non plus effacer vos sauvegardes.

Le lancer toutes les nuits

Tout ce qui précède dans un seul script :

backup.sh
#!/usr/bin/env bash
set -euo pipefail

STAMP=$(date +%F-%H%M)
OUT=/var/backups/fivem
RECIPIENT=age1q9x...
mkdir -p "$OUT"

mysqldump --defaults-extra-file="$HOME/.fivem-backup.cnf" \
  --single-transaction --quick --no-tablespaces \
  --default-character-set=utf8mb4 --hex-blob \
  fivem | gzip | age -r "$RECIPIENT" > "$OUT/db-$STAMP.sql.gz.age"

tar -czf - --exclude='server-data/cache' -C /home/fivem server-data txData \
  | age -r "$RECIPIENT" > "$OUT/files-$STAMP.tar.gz.age"

rclone copy "$OUT" b2:my-city-backups --include '*.age'
find "$OUT" -name '*.age' -mtime +14 -delete

set -o pipefail compte plus qu’il n’y paraît. Sans lui, mysqldump | gzip réussit dès que gzip réussit : avec un mauvais mot de passe, vous obtenez chaque nuit un fichier de 20 octets et un log qui dit que tout s’est bien passé. Avec lui, le script s’arrête à la première erreur.

Lancez-le tous les jours à 04:00 avec cron :

crontab -e
0 4 * * * /home/fivem/backup.sh >> /var/log/fivem-backup.log 2>&1

Sous Windows, lancez backup.sh avec Git Bash depuis le Planificateur de tâches. Faites une sauvegarde de plus à la main avant chaque mise à jour d’un framework ou d’un script d’inventaire.

Tester la restauration, sinon vous n’avez pas de sauvegarde

La plupart des rollbacks échouent la nuit où on en a besoin : le dump s’est arrêté à mi-chemin, le mot de passe a changé il y a trois mois, personne n’a gardé la clé privée. Un test hebdomadaire attrape les trois cas. Faites-le sur une machine qui a la clé privée et MySQL ou MariaDB, comme votre ordinateur ou un serveur de test :

bash
age -d -i fivem-backup.key db-2026-10-15-0400.sql.gz.age | gunzip > restore.sql
tail -n 1 restore.sql
# -- Dump completed on 2026-10-15  4:00:03

mysql -e 'DROP DATABASE IF EXISTS restore_test; CREATE DATABASE restore_test'
mysql restore_test < restore.sql

Un dump complet se termine par la ligne -- Dump completed. Si elle manque, le dump a été coupé. Une fois importé, comparez la sauvegarde au serveur en production. Utilisez players à la place de users sur QBCore et Qbox :

SQL
SELECT table_schema, COUNT(*) AS tables
FROM information_schema.tables
WHERE table_schema IN ('fivem', 'restore_test')
GROUP BY table_schema;

SELECT
  (SELECT COUNT(*) FROM fivem.users)        AS players_now,
  (SELECT COUNT(*) FROM restore_test.users) AS players_in_backup;

Le même nombre de tables et un nombre de joueurs proche de celui d’aujourd’hui, c’est une sauvegarde entière. Pour tester aussi les fichiers, décompressez l’archive à côté d’une copie de FXServer, pointez-le sur restore_test et démarrez-le.

Revenir en arrière sur tout le serveur

À utiliser après un exploit de duplication, une économie cassée ou une mise à jour qui a abîmé la base. Chaque joueur perd ce qui s’est passé depuis la sauvegarde : prévenez-les d’abord.

  1. Arrêtez le serveur dans txAdmin. Ne le redémarrez pas : le framework sauvegarde chaque joueur en ligne depuis la mémoire sur son timer et à la fermeture, ce qui écraserait la restauration.
  2. Faites une sauvegarde de l’état cassé, au cas où la restauration aggraverait les choses.
  3. Importez la sauvegarde d’avant le début du problème.
  4. Démarrez le serveur.
bash
mysqldump --defaults-extra-file="$HOME/.fivem-backup.cnf" \
  --single-transaction --quick --no-tablespaces \
  --default-character-set=utf8mb4 --hex-blob \
  fivem | gzip > before-rollback.sql.gz

age -d -i fivem-backup.key db-2026-10-15-0400.sql.gz.age | gunzip | mysql fivem

Le dump supprime et recrée chaque table qu’il contient. Une table créée après la sauvegarde reste telle quelle.

Restaurer l’inventaire d’un joueur sans revenir en arrière pour tous

Un joueur a perdu son inventaire à cause d’un bug, ou un tricheur a vidé son compte. Un rollback de la ville ferait perdre une journée de jeu à tous les autres. Importez plutôt la sauvegarde dans restore_test sur le même serveur de base de données, comme dans le test de restauration, et recopiez uniquement les lignes de ce joueur.

Trouvez d’abord son identifiant. Sous ESX, c’est la colonne identifier de users, et avec ox_inventory son inventaire est stocké dans la même ligne. Sous QBCore et Qbox, c’est citizenid dans players. Ensuite, expulsez le joueur et gardez-le hors du serveur jusqu’à la fin, sinon le framework réécrit son état actuel par-dessus la restauration à sa prochaine sauvegarde.

ESX

SQL
SET FOREIGN_KEY_CHECKS = 0;
START TRANSACTION;

REPLACE INTO fivem.users
  SELECT * FROM restore_test.users WHERE identifier = 'char1:3f2a9c...';

DELETE FROM fivem.owned_vehicles WHERE owner = 'char1:3f2a9c...';
INSERT INTO fivem.owned_vehicles
  SELECT * FROM restore_test.owned_vehicles WHERE owner = 'char1:3f2a9c...';

COMMIT;
SET FOREIGN_KEY_CHECKS = 1;

QBCore et Qbox

SQL
SET FOREIGN_KEY_CHECKS = 0;
START TRANSACTION;

REPLACE INTO fivem.players
  SELECT * FROM restore_test.players WHERE citizenid = 'KX81F2QD';

DELETE FROM fivem.player_vehicles WHERE citizenid = 'KX81F2QD';
INSERT INTO fivem.player_vehicles
  SELECT * FROM restore_test.player_vehicles WHERE citizenid = 'KX81F2QD';

COMMIT;
SET FOREIGN_KEY_CHECKS = 1;

REPLACE écrase la ligne du joueur par celle de la sauvegarde : argent, inventaire et position. Les véhicules sont supprimés puis réinsérés, donc une voiture achetée après la sauvegarde disparaît aussi. Si une voiture a changé de main depuis, le INSERT s’arrête sur une clé en double et la transaction laisse tout en l’état. Décidez qui la garde, puis relancez.

Si le joueur a fait un échange depuis la sauvegarde, la restauration lui rend ce qu’il a déjà donné, et l’item existe alors en double. Vérifiez ses transactions avant de restaurer quelqu’un qui prétend avoir tout perdu.

Les erreurs que vous allez sans doute rencontrer

Access denied; you need the PROCESS privilege

mysqldump: Error: 'Access denied; you need (at least one of) the PROCESS privilege(s) for this operation' when trying to dump tablespaces apparaît sur MySQL 8.0.21 et les versions suivantes. Ajoutez --no-tablespaces. Une base FiveM n’a aucun tablespace qui vaille la peine d’être dumpé.

Access denied when using LOCK TABLES

mysqldump: Got error: 1044: Access denied for user 'fivem'@'localhost' to database 'fivem' when using LOCK TABLES veut dire que le dump a tourné sans --single-transaction et a tenté de verrouiller toutes les tables. Ajoutez l’option. C’est aussi ce qui évite que le dump gèle le serveur.

Unknown collation utf8mb4_0900_ai_ci

ERROR 1273 (HY000) at line 25: Unknown collation: 'utf8mb4_0900_ai_ci' veut dire qu’un dump MySQL 8 est importé dans MariaDB, qui ne connaît pas cette collation. Remplacez-la avant l’import :

bash
sed -i 's/utf8mb4_0900_ai_ci/utf8mb4_unicode_ci/g' restore.sql

La même chose, faite par FiveDock

Tout ce qui précède, c’est ce que fait Time Machine de FiveDock depuis l’intérieur de votre serveur, par le même agent qui fait tourner le reste de FiveDock. Pas de script à maintenir, pas de tâche cron à oublier.

  • Chiffré avec votre clé. L’agent chiffre chaque sauvegarde sur votre machine avec une clé créée pour ce serveur et affichée une seule fois. Nous ne pouvons pas lire vos sauvegardes, noms de fichiers compris, et un server.cfg qui fuite n’ouvre que celles de ce serveur.
  • Cohérent et incrémental. Chaque table est lue dans un snapshot cohérent, et la sauvegarde vous indique quelles tables sont en MyISAM. Seules les parties modifiées sont envoyées, et une sauvegarde supprimée reste verrouillée 30 jours pour que personne ne puisse effacer votre historique.
  • Testé chaque semaine. FiveDock restaure une sauvegarde dans une base jetable sur votre propre serveur et la marque comme restauration testée : vous trouvez une sauvegarde cassée des semaines avant d’en avoir besoin.
  • Revenir exactement sur ce qui a cassé. Le serveur entier, la base, une table, une resource, un fichier ou un joueur, avec le nombre d’éléments qui vont changer avant que vous confirmiez, et une sauvegarde de sécurité d’abord. Il refuse de restaurer un joueur encore connecté, et refuse une restauration de base tant qu’ESX, QBCore ou Qbox tourne.
  • Deploy Guard. Une sauvegarde avant chaque redémarrage, un verdict dix minutes après qui nomme la resource fautive, et un clic pour revenir à l’état d’avant le redémarrage.
  • Une sauvegarde quand l’économie déraille. Quand une alerte économie se déclenche, une sauvegarde est faite à la seconde même, avant que les dégâts ne s’étendent.

Chaque offre fait une sauvegarde quotidienne. La restauration d’une table ou d’un joueur, les tests de restauration hebdomadaires, les sauvegardes toutes les heures et Deploy Guard sont inclus avec Metro. La liste complète est sur Tarifs, et Fonctionnalités montre le reste de Time Machine.

FAQ

À quelle fréquence sauvegarder un serveur FiveM ?

Sauvegardez la base au moins une fois par jour, et une fois de plus à la main avant chaque mise à jour du framework ou de l’inventaire. Si votre économie est active, sauvegardez toutes les heures : un exploit de duplication découvert à 22:00 avec une sauvegarde de 04:00 coûte 18 heures à chaque joueur.

Puis-je sauvegarder la base pendant que le serveur tourne ?

Oui. mysqldump --single-transaction lit les tables InnoDB dans un snapshot cohérent sans les verrouiller, les joueurs ne remarquent rien. Seules les tables MyISAM sont hors du snapshot.

txAdmin sauvegarde-t-il ma base de données ?

Non. txAdmin démarre, redémarre et surveille le serveur, mais ne dumpe pas votre base MySQL ou MariaDB. Utilisez mysqldump avec une planification, ou un outil qui le fait pour vous.

Comment revenir en arrière sur un serveur FiveM après un exploit de dupe ?

Arrêtez le serveur dans txAdmin, faites une sauvegarde de l’état actuel, importez la dernière sauvegarde d’avant l’exploit et redémarrez le serveur. Si seuls quelques joueurs en ont profité, restaurez ou nettoyez leurs lignes au lieu de faire revenir tout le monde en arrière.

Comment restaurer l’inventaire d’un seul joueur ?

Importez la sauvegarde dans une base séparée sur le même serveur, gardez le joueur hors ligne, et recopiez ses lignes de users (ESX) ou players (QBCore et Qbox), plus ses véhicules, dans la base en production en une seule transaction.

Où se trouve la base qu’utilise oxmysql ?

Dans server.cfg, sur la ligne set mysql_connection_string. Elle contient l’utilisateur, le mot de passe, l’hôte et le nom de la base dont mysqldump a besoin.

Tous les articles