Zum Inhalt springen
Blog

FiveM Server und Datenbank sichern, Restore testen

mysqldump für oxmysql, Serverdateien, Verschlüsselung, Restore-Test pro Woche und wie ein Spieler sein Inventar zurückbekommt, ohne die Stadt zurückzusetzen.

Von Termi

10 Min. Lesezeit
  • Backups
  • Database
  • oxmysql
Auf dieser Seite

Um einen FiveM-Server zu sichern, ziehst du mit mysqldump --single-transaction einen Dump der MySQL- oder MariaDB-Datenbank, mit der oxmysql verbunden ist, packst server.cfg, deine Resources und txData in ein Archiv, verschlüsselst beides und kopierst es von der Maschine weg. Ein Backup zählt erst, wenn du es einmal zurückgespielt hast. Lade deshalb jede Woche eins in eine Wegwerf-Datenbank. Willst du einem einzelnen Spieler sein Inventar zurückgeben, spielst du das Backup in diese Wegwerf-Datenbank ein und kopierst nur seine Zeilen.

Diese Anleitung macht das alles von Hand mit kostenlosen Tools, unter Linux oder unter Windows mit Git Bash. Du brauchst dafür kein FiveDock. Am Ende zeigen wir dasselbe als fertige Lösung, samt Deploy Guard, das vor jedem Neustart ein Backup anlegt.

Was ein FiveM-Backup enthalten muss

  • Die Datenbank. Charaktere, Geld, Inventare, Fahrzeuge, Häuser, Handynachrichten: Alles, was ESX, QBCore, Qbox und ox_inventory speichern, liegt hier. Sie ändert sich jede Minute und braucht darum das häufigste Backup.
  • server.cfg. Deine Resource-Reihenfolge, Convars, Berechtigungen, das Datenbankpasswort und dein sv_licenseKey.
  • resources. Deine Scripts, Maps und Fahrzeuge, inklusive aller Änderungen an gekauften Scripts.
  • txData. Einstellungen, Admins und Spielerverlauf von txAdmin.

Lass cache weg: FXServer baut ihn beim nächsten Start neu auf, und oft ist er der größte Ordner auf der Platte. Logs kannst du ebenfalls weglassen.

Die Datenbank von oxmysql finden

oxmysql liest die Verbindung aus der server.cfg:

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

Das sind der Benutzer fivem, das Passwort secret, der Host 127.0.0.1 und die Datenbank fivem. Manche Server nutzen noch die ältere Form server=127.0.0.1;database=fivem;userid=fivem;password=secret, die dieselben vier Werte enthält.

Die Datenbank mit mysqldump sichern

Leg die Zugangsdaten in eine Datei, die nur du lesen kannst. So steht das Passwort weder in der Prozessliste noch in der Shell-History:

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

Dann ziehst du den Dump, während der Server weiterläuft:

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 liest alle InnoDB-Tabellen in einem konsistenten Snapshot, ohne sie zu sperren. Die Spieler spielen weiter, und das Geld in users passt zu den Items in ox_inventory.
  • --quick streamt Zeilen, statt ganze Tabellen in den Speicher zu laden. Das zählt, sobald Logs und Handy-Tabellen in die Millionen gehen.
  • --no-tablespaces vermeidet unter MySQL 8 einen Berechtigungsfehler (siehe die Fehler).
  • --default-character-set=utf8mb4 und --hex-blob halten Emojis in Charakternamen und Binärspalten heil.

Unter MariaDB heißt derselbe Befehl auch mariadb-dump, mit denselben Optionen. Nutzen deine Scripts Stored Procedures, füge --routines hinzu.

Auf MyISAM-Tabellen prüfen

Der Snapshot gilt nur für InnoDB-Tabellen. Eine MyISAM-Tabelle wird zu einem etwas anderen Zeitpunkt gelesen als der Rest. Ein Backup, das während eines Trades entsteht, kann deshalb das Geld von vorher und das Item von nachher enthalten. ALTER TABLE name ENGINE=InnoDB; stellt eine Tabelle um.

Die Serverdateien sichern

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

Zeige mit -C auf den Ordner, der server-data und txData enthält. Unter Windows ist tar ab Windows 10 und 11 dabei und nimmt dieselben Optionen.

Verschlüsseln, bevor es die Maschine verlässt

Ein Datenbank-Dump enthält die Identifier aller Spieler, und die server.cfg enthält das Datenbankpasswort und deinen Lizenzschlüssel. Wer eine Kopie bekommt, kann alles lesen oder deinen Server unter deinem Key starten. Verschlüssele mit age und einem öffentlichen Schlüssel: Der Server kann Backups verschlüsseln, aber nicht öffnen. Ein gestohlener Server verrät also nicht seine eigenen Backups.

Erzeuge das Schlüsselpaar auf deinem eigenen Rechner, nicht auf dem Server:

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

Bewahre fivem-backup.key in deinem Passwortmanager auf und gib dem Server nur den öffentlichen Schlüssel, der mit age1 beginnt:

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

Verlierst du den privaten Schlüssel, sind alle damit verschlüsselten Backups verloren. Heb zwei Kopien an zwei verschiedenen Orten auf.

Kopien außerhalb des Servers aufbewahren

Ein Backup auf derselben Platte ist weg, wenn die Platte ausfällt, wenn der Hoster den Vertrag beendet oder jemand die Maschine löscht. Kopiere jedes Backup mit rclone in einen Object Storage wie Backblaze B2, Cloudflare R2 oder S3. Gib dem Server einen Storage-Key, der Dateien hochladen, aber nicht löschen darf. Wer im Server landet, kann dann nicht auch noch deine Backups löschen.

Jede Nacht automatisch laufen lassen

Alles von oben in einem 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 ist wichtiger, als es aussieht. Ohne die Option gilt mysqldump | gzip als erfolgreich, sobald gzip durchläuft. Bei falschem Passwort bekommst du dann jede Nacht eine 20-Byte-Datei und ein Log, das behauptet, alles sei gut gegangen. Mit der Option bricht das Script beim ersten Fehler ab.

Lass es mit cron täglich um 04:00 laufen:

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

Unter Windows startest du backup.sh über die Aufgabenplanung mit Git Bash. Mach vor jedem Update eines Frameworks oder Inventory-Scripts zusätzlich ein Backup von Hand.

Restore testen, sonst hast du kein Backup

Die meisten Rollbacks scheitern in der Nacht, in der man sie braucht: Der Dump brach mittendrin ab, das Passwort wurde vor drei Monaten geändert, niemand hat den privaten Schlüssel aufgehoben. Ein wöchentlicher Test fängt alle drei Fälle ab. Mach ihn auf einer Maschine, die den privaten Schlüssel und MySQL oder MariaDB hat, etwa auf deinem eigenen Rechner oder einem Testserver:

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

Ein vollständiger Dump endet mit der Zeile -- Dump completed. Fehlt sie, wurde der Dump abgeschnitten. Ist er importiert, vergleichst du das Backup mit dem Live-Server. Unter QBCore und Qbox nimm players statt users:

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;

Gleich viele Tabellen und eine Spielerzahl nahe der heutigen heißen: Das Backup ist vollständig. Um auch die Dateien zu testen, entpackst du das Archiv neben einer Kopie von FXServer, richtest ihn auf restore_test und startest ihn.

Den ganzen Server zurücksetzen

Das brauchst du nach einem Duplication-Exploit, einer kaputten Wirtschaft oder einem Update, das die Datenbank beschädigt hat. Jeder Spieler verliert, was seit dem Backup passiert ist. Sag es ihnen also vorher.

  1. Stoppe den Server in txAdmin. Starte ihn nicht neu: Das Framework speichert jeden Online-Spieler aus dem Speicher nach seinem Timer und beim Beenden, und das würde den Restore überschreiben.
  2. Zieh ein Backup vom kaputten Zustand, falls der Restore alles schlimmer macht.
  3. Importiere das Backup von vor dem Problem.
  4. Starte den Server.
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

Der Dump löscht jede enthaltene Tabelle und legt sie neu an. Eine Tabelle, die nach dem Backup entstanden ist, bleibt unverändert.

Das Inventar eines Spielers zurückholen, ohne alle zurückzusetzen

Ein Spieler hat sein Inventar durch einen Bug verloren, oder ein Cheater hat seinen Account leergeräumt. Ein Rollback der Stadt würde alle anderen einen Spieltag kosten. Importiere stattdessen das Backup wie im Restore-Test in restore_test auf demselben Datenbankserver und kopiere nur die Zeilen dieses Spielers zurück.

Such zuerst seinen Identifier. In ESX ist das die Spalte identifier in users, und mit ox_inventory liegt sein Inventar in derselben Zeile. In QBCore und Qbox ist es citizenid in players. Kicke den Spieler danach und halte ihn vom Server fern, bis du fertig bist. Sonst schreibt das Framework bei seinem nächsten Save den aktuellen Stand über den Restore.

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 und 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 überschreibt die Zeile des Spielers mit der aus dem Backup: Geld, Inventar und Position. Die Fahrzeuge werden gelöscht und neu eingefügt, ein nach dem Backup gekauftes Auto verschwindet also auch. Hat ein Auto seit dem Backup den Besitzer gewechselt, bricht das INSERT wegen eines doppelten Schlüssels ab, und die Transaktion lässt alles, wie es war. Entscheide, wer es behält, und führe das Script dann erneut aus.

Hat der Spieler seit dem Backup getradet, bekommt er mit dem Restore zurück, was er schon weggegeben hat, und das Item existiert danach doppelt. Prüfe die Transaktionen, bevor du jemanden wiederherstellst, der behauptet, alles verloren zu haben.

Fehler, auf die du wahrscheinlich triffst

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 taucht ab MySQL 8.0.21 auf. Füge --no-tablespaces hinzu. In einer FiveM-Datenbank gibt es keine Tablespaces, die sich zu sichern lohnen.

Access denied when using LOCK TABLES

mysqldump: Got error: 1044: Access denied for user 'fivem'@'localhost' to database 'fivem' when using LOCK TABLES heißt: Der Dump lief ohne --single-transaction und wollte jede Tabelle sperren. Füge die Option hinzu. Damit friert der Dump den Server auch nicht mehr ein.

Unknown collation utf8mb4_0900_ai_ci

ERROR 1273 (HY000) at line 25: Unknown collation: 'utf8mb4_0900_ai_ci' heißt: Ein MySQL-8-Dump wird in MariaDB eingespielt, und MariaDB kennt diese Collation nicht. Ersetze sie vor dem Import:

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

Dasselbe, erledigt von FiveDock

Alles oben macht die Time Machine von FiveDock direkt in deinem Server, über denselben Agent, der auch den Rest von FiveDock ausführt. Du pflegst kein Script und vergisst keinen Cronjob.

  • Mit deinem Schlüssel verschlüsselt. Der Agent verschlüsselt jedes Backup auf deiner Maschine mit einem Schlüssel, der für diesen Server erzeugt und dir einmal angezeigt wird. Wir können deine Backups nicht lesen, auch nicht die Dateinamen, und eine geleakte server.cfg öffnet nur die Backups dieses einen Servers.
  • Konsistent und inkrementell. Jede Tabelle wird in einem konsistenten Snapshot gelesen, und das Backup sagt dir, welche Tabellen MyISAM sind. Hochgeladen wird nur, was sich geändert hat, und ein gelöschtes Backup bleibt 30 Tage gesperrt, damit niemand deine Historie löschen kann.
  • Jede Woche getestet. FiveDock spielt ein Backup in eine Wegwerf-Datenbank auf deinem eigenen Server ein und markiert es als testweise wiederhergestellt. So findest du ein kaputtes Backup Wochen, bevor du es brauchst.
  • Genau das zurückspulen, was kaputt ist. Den ganzen Server, die Datenbank, eine Tabelle, eine Resource, eine Datei oder einen Spieler, mit einer Anzahl der Änderungen vor der Bestätigung und vorher einem Sicherheits-Backup. Einen noch verbundenen Spieler stellt es nicht wieder her, und einen Datenbank-Restore lehnt es ab, solange ESX, QBCore oder Qbox läuft.
  • Deploy Guard. Ein Backup vor jedem Neustart, zehn Minuten danach ein Urteil, das die Resource nennt, die Ärger gemacht hat, und ein Klick zurück zum Stand vor dem Neustart.
  • Ein Backup, wenn die Wirtschaft kippt. Schlägt ein Wirtschafts-Alarm an, entsteht in derselben Sekunde ein Backup, bevor sich der Schaden ausbreitet.

Jeder Plan macht ein tägliches Backup. Einzelne Tabellen oder Spieler wiederherstellen, wöchentliche Test-Restores, stündliche Backups und Deploy Guard gehören zu Metro. Die ganze Liste steht unter Preise, und Funktionen zeigt den Rest der Time Machine.

FAQ

Wie oft sollte ich einen FiveM-Server sichern?

Sichere die Datenbank mindestens einmal am Tag und zusätzlich von Hand vor jedem Update von Framework oder Inventar. Ist die Wirtschaft stark belebt, sichere stündlich: Wird ein Duplication-Exploit um 22:00 entdeckt und das letzte Backup ist von 04:00, kostet das jeden Spieler 18 Stunden.

Kann ich die Datenbank sichern, während der Server läuft?

Ja. mysqldump --single-transaction liest InnoDB-Tabellen in einem konsistenten Snapshot ohne Sperren, die Spieler merken nichts. Nur MyISAM-Tabellen liegen außerhalb des Snapshots.

Sichert txAdmin meine Datenbank?

Nein. txAdmin startet, restartet und überwacht den Server, zieht aber keinen Dump deiner MySQL- oder MariaDB-Datenbank. Nutze mysqldump nach Zeitplan oder ein Tool, das es für dich übernimmt.

Wie setze ich einen FiveM-Server nach einem Dupe-Exploit zurück?

Stoppe den Server in txAdmin, zieh ein Backup vom aktuellen Stand, importiere das letzte Backup von vor dem Exploit und starte den Server wieder. Haben nur wenige Spieler profitiert, stelle deren Zeilen wieder her oder bereinige sie, statt alle zurückzusetzen.

Wie hole ich das Inventar eines einzelnen Spielers zurück?

Importiere das Backup in eine separate Datenbank auf demselben Server, halte den Spieler offline und kopiere seine Zeilen aus users (ESX) oder players (QBCore und Qbox) samt Fahrzeugen in einer Transaktion in die Live-Datenbank.

Wo ist die Datenbank, die oxmysql nutzt?

In der server.cfg, in der Zeile set mysql_connection_string. Sie enthält Benutzer, Passwort, Host und Datenbanknamen, die mysqldump braucht.

Alle Artikel