Kopia zapasowa serwera FiveM i bazy danych, z testem
mysqldump dla oxmysql, pliki serwera, szyfrowanie, cotygodniowy test przywracania i jak oddać graczowi ekwipunek bez cofania całego miasta.
Autor: Termi
- Backups
- Database
- oxmysql
Na tej stronie
- Co musi trafić do kopii serwera FiveM
- Znajdź bazę, której używa oxmysql
- Zrzuć bazę przez mysqldump
- Zrób kopię plików serwera
- Zaszyfruj, zanim opuści maszynę
- Trzymaj kopie poza serwerem
- Uruchamiaj to co noc
- Przetestuj przywracanie, inaczej nie masz kopii
- Cofnij cały serwer
- Przywróć ekwipunek jednego gracza bez cofania wszystkich
- ESX
- QBCore i Qbox
- Błędy, na które pewnie trafisz
- Access denied; brak uprawnienia PROCESS
- Access denied przy LOCK TABLES
- Nieznane porównanie utf8mb4_0900_ai_ci
- To samo, zrobione przez FiveDocka
- FAQ
- Jak często robić kopię serwera FiveM?
- Czy mogę robić kopię bazy, gdy serwer działa?
- Czy txAdmin robi kopię mojej bazy?
- Jak cofnąć serwer FiveM po exploicie na duplikację?
- Jak przywrócić ekwipunek jednego gracza?
- Gdzie jest baza, której używa oxmysql?
Żeby zrobić kopię serwera FiveM, zrzuć bazę MySQL albo MariaDB, z którą łączy się oxmysql, poleceniem mysqldump --single-transaction, spakuj server.cfg, zasoby i txData, zaszyfruj jedno i drugie i skopiuj poza maszynę. Kopia liczy się dopiero wtedy, gdy ją przywrócisz, więc co tydzień wczytuj jedną do bazy testowej. Żeby oddać jednemu graczowi ekwipunek, przywróć kopię do tej bazy testowej i przenieś tylko jego wiersze.
Ten poradnik robi to wszystko ręcznie, darmowymi narzędziami, na Linuksie albo na Windowsie z Git Bash. Nic w nim nie wymaga FiveDocka. Na końcu to samo zrobione za ciebie, razem z Deploy Guard, który robi kopię przed każdym restartem.
Co musi trafić do kopii serwera FiveM
Pomiń cache: FXServer odbuduje go przy następnym starcie, a często to największy folder na dysku. Logi też możesz pominąć.
Znajdź bazę, której używa oxmysql
oxmysql czyta połączenie z server.cfg:
set mysql_connection_string "mysql://fivem:[email protected]/fivem?charset=utf8mb4"To użytkownik fivem, hasło secret, host 127.0.0.1 i baza fivem. Niektóre serwery używają starszej formy server=127.0.0.1;database=fivem;userid=fivem;password=secret, która zawiera te same cztery wartości.
Zrzuć bazę przez mysqldump
Zapisz dane logowania w pliku, który możesz czytać tylko ty, żeby hasło nie było widać na liście procesów ani w historii powłoki:
cat > "$HOME/.fivem-backup.cnf" <<'EOF'
[client]
user=fivem
password=secret
host=127.0.0.1
EOF
chmod 600 "$HOME/.fivem-backup.cnf"Potem zrzuć bazę, podczas gdy serwer dalej działa:
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"Na MariaDB to samo polecenie nazywa się też mariadb-dump i ma te same opcje. Jeśli twoje skrypty używają procedur składowanych, dodaj --routines.
Sprawdź, czy masz tabele MyISAM
Snapshot obejmuje tylko tabele InnoDB. Tabela MyISAM jest czytana w trochę innym momencie niż reszta, więc kopia zrobiona w trakcie wymiany może mieć pieniądze sprzed niej i przedmiot po niej. ALTER TABLE nazwa ENGINE=InnoDB; przerabia jedną.
Zrób kopię plików serwera
tar -czf "files-$(date +%F-%H%M).tar.gz" \
--exclude='server-data/cache' \
-C /home/fivem server-data txDataUstaw -C na folder, w którym leżą server-data i txData. Na Windowsie tar jest w systemie od Windows 10 i przyjmuje te same opcje.
Zaszyfruj, zanim opuści maszynę
Zrzut bazy zawiera identyfikatory każdego gracza, a server.cfg hasło do bazy i twój klucz licencji. Każdy, kto dostanie kopię, przeczyta to wszystko albo uruchomi serwer na twoim kluczu. Szyfruj przez age kluczem publicznym: serwer może szyfrować kopie, ale nie może ich otworzyć, więc przejęty serwer nie oddaje własnych kopii.
Wygeneruj parę kluczy na swoim komputerze, nie na serwerze:
age-keygen -o fivem-backup.key
# Public key: age1q9x...Trzymaj fivem-backup.key w menedżerze haseł, a serwerowi daj tylko klucz publiczny, który zaczyna się od age1:
age -r age1q9x... -o fivem-2026-10-15-0400.sql.gz.age fivem-2026-10-15-0400.sql.gzJeśli zgubisz klucz prywatny, przepadają z nim wszystkie kopie, które zaszyfrował. Trzymaj dwie kopie klucza, w dwóch różnych miejscach.
Trzymaj kopie poza serwerem
Kopia na tym samym dysku znika, gdy dysk padnie, gdy hosting zakończy umowę albo gdy ktoś wyczyści maszynę. Kopiuj każdą kopię do magazynu obiektów, np. Backblaze B2, Cloudflare R2 albo S3, przez rclone. Daj serwerowi klucz, który może wgrywać pliki, ale nie może ich usuwać, żeby ten, kto dostanie się na serwer, nie skasował też kopii.
Uruchamiaj to co noc
Wszystko powyżej w jednym skrypcie:
#!/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 -deleteset -o pipefail ma większe znaczenie, niż się wydaje. Bez niego mysqldump | gzip kończy się sukcesem, kiedy tylko gzip się uda, więc złe hasło zostawia co noc plik 20-bajtowy i log, w którym wszystko działało. Z nim skrypt zatrzymuje się na pierwszym błędzie.
Uruchamiaj go codziennie o 04:00 przez crona:
0 4 * * * /home/fivem/backup.sh >> /var/log/fivem-backup.log 2>&1Na Windowsie uruchamiaj backup.sh przez Git Bash z Harmonogramu zadań. Przed każdą aktualizacją frameworka albo skryptu ekwipunku zrób dodatkową kopię ręcznie.
Przetestuj przywracanie, inaczej nie masz kopii
Większość rollbacków zawodzi w noc, w którą są potrzebne: zrzut urwał się w połowie, hasło zmieniło się trzy miesiące temu, nikt nie zachował klucza prywatnego. Cotygodniowy test wyłapie wszystkie trzy. Rób go na maszynie, która ma klucz prywatny i MySQL albo MariaDB, np. na swoim komputerze albo serwerze testowym:
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.sqlPełny zrzut kończy się linijką -- Dump completed. Jeśli jej brakuje, zrzut się urwał. Po imporcie porównaj kopię z serwerem na żywo. Na QBCore i Qbox użyj players zamiast users:
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;Ta sama liczba tabel i liczba graczy bliska dzisiejszej oznacza, że kopia jest cała. Żeby przetestować też pliki, rozpakuj archiwum obok kopii FXServera, skieruj go na restore_test i uruchom.
Cofnij cały serwer
Użyj tego po exploicie na duplikację, zepsutej ekonomii albo aktualizacji, która uszkodziła bazę. Każdy gracz straci to, co wydarzyło się od kopii, więc najpierw ich uprzedź.
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 fivemZrzut usuwa i tworzy na nowo każdą tabelę, którą zawiera. Tabela utworzona po kopii zostaje bez zmian.
Przywróć ekwipunek jednego gracza bez cofania wszystkich
Gracz stracił ekwipunek przez błąd albo cheater wyczyścił mu konto. Cofnięcie miasta kosztowałoby wszystkich innych dzień gry. Zamiast tego zaimportuj kopię do restore_test na tym samym serwerze bazy, jak w teście przywracania, i skopiuj z powrotem tylko wiersze tego gracza.
Najpierw znajdź jego identyfikator. W ESX to kolumna identifier w users, a z ox_inventory jego ekwipunek siedzi w tym samym wierszu. W QBCore i Qbox to citizenid w players. Potem wyrzuć gracza i nie wpuszczaj go, dopóki nie skończysz, bo framework przy następnym zapisie nadpisze przywrócone dane jego obecnym stanem.
ESX
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 i Qbox
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 nadpisuje wiersz gracza wierszem z kopii: pieniądze, ekwipunek i pozycję. Pojazdy są usuwane i wstawiane od nowa, więc auto kupione po kopii też znika. Jeśli auto zmieniło właściciela od czasu kopii, INSERT zatrzyma się na zduplikowanym kluczu, a transakcja zostawi wszystko bez zmian. Zdecyduj, kto je zatrzymuje, i uruchom ponownie.
Jeśli gracz handlował od czasu kopii, przywrócenie odda mu to, co już komuś przekazał, i przedmiot będzie istniał dwa razy. Sprawdź jego transakcje, zanim przywrócisz kogoś, kto twierdzi, że stracił wszystko.
Błędy, na które pewnie trafisz
Access denied; brak uprawnienia PROCESS
mysqldump: Error: 'Access denied; you need (at least one of) the PROCESS privilege(s) for this operation' when trying to dump tablespaces pojawia się na MySQL 8.0.21 i nowszych. Dodaj --no-tablespaces. Baza FiveM nie ma tablespace’ów, które warto zrzucać.
Access denied przy LOCK TABLES
mysqldump: Got error: 1044: Access denied for user 'fivem'@'localhost' to database 'fivem' when using LOCK TABLES znaczy, że zrzut poszedł bez --single-transaction i próbował zablokować każdą tabelę. Dodaj tę opcję. To też dzięki niej zrzut nie zamraża serwera.
Nieznane porównanie utf8mb4_0900_ai_ci
ERROR 1273 (HY000) at line 25: Unknown collation: 'utf8mb4_0900_ai_ci' znaczy, że zrzut z MySQL 8 trafia do MariaDB, która nie zna tego porównania. Podmień je przed importem:
sed -i 's/utf8mb4_0900_ai_ci/utf8mb4_unicode_ci/g' restore.sqlTo samo, zrobione przez FiveDocka
Wszystko powyżej robi Time Machine FiveDocka z wnętrza twojego serwera, przez tego samego agenta, który obsługuje resztę FiveDocka. Nie ma skryptu do utrzymania ani crona, o którym można zapomnieć.
Każdy plan robi codzienną kopię. Przywracanie jednej tabeli albo jednego gracza, cotygodniowe testy, kopie co godzinę i Deploy Guard są w planie Metro. Cennik ma pełną listę, a funkcje pokazują resztę Time Machine.
FAQ
Jak często robić kopię serwera FiveM?
Kopię bazy rób co najmniej raz dziennie i dodatkowo ręcznie przed każdą aktualizacją frameworka albo ekwipunku. Jeśli ekonomia jest ruchliwa, rób ją co godzinę: exploit na duplikację znaleziony o 22:00 przy kopii z 04:00 kosztuje każdego gracza 18 godzin.
Czy mogę robić kopię bazy, gdy serwer działa?
Tak. mysqldump --single-transaction czyta tabele InnoDB w jednym spójnym snapshocie bez blokowania, więc gracze niczego nie zauważą. Poza snapshotem zostają tylko tabele MyISAM.
Czy txAdmin robi kopię mojej bazy?
Nie. txAdmin uruchamia, restartuje i pilnuje serwera, ale nie zrzuca twojej bazy MySQL ani MariaDB. Użyj mysqldump według harmonogramu albo narzędzia, które zrobi to za ciebie.
Jak cofnąć serwer FiveM po exploicie na duplikację?
Zatrzymaj serwer w txAdminie, zrób kopię obecnego stanu, zaimportuj ostatnią kopię sprzed exploita i uruchom serwer. Jeśli skorzystało tylko kilku graczy, przywróć albo wyczyść ich wiersze, zamiast cofać wszystkich.
Jak przywrócić ekwipunek jednego gracza?
Zaimportuj kopię do osobnej bazy na tym samym serwerze, trzymaj gracza offline i skopiuj jego wiersze z users (ESX) albo players (QBCore i Qbox), razem z jego pojazdami, do bazy na żywo w jednej transakcji.
Gdzie jest baza, której używa oxmysql?
W server.cfg, w linijce set mysql_connection_string. Są w niej użytkownik, hasło, host i nazwa bazy, których potrzebuje mysqldump.