Running a server without a Metin2 backup strategy is just waiting for the crash to happen. A disk failure, a careless DELETE query, or a botched table change can wipe out months of player progress in seconds. The good news: with MySQL's own tools, for free and in a few lines of shell, you can set up fully automatic, compressed and scheduled backups. In this guide I'll walk through which databases to back up and how, using mysqldump and cron on a Linux-based Metin2 server.
Which databases does Metin2 use?
In a classic Metin2 setup the game logic is usually split across several separate schemas. The exact names vary by distribution, but you'll typically see:
- account — user accounts, passwords, e-mail and ban data.
- player — characters, inventory, items, guild data, quest state. This is the most critical and most frequently changing schema.
- common — item proto, shop, mob and shared configuration tables.
- log — trade, drop and player-movement records. Usually large but losing it won't stop the game.
In practice the account and player schemas are gold; in a data loss the player reaction maps directly to them. You should back up common too, because the only copy of your manual item tweaks may live there.
Taking a one-off backup with mysqldump
First let's take a manual backup to confirm the tool works. mysqldump dumps an entire schema into a consistent SQL file without stopping the running server:
mysqldump -u root -p \
--single-transaction --quick \
--routines --triggers \
player > player.sql
The important flags:
--single-transaction: on InnoDB tables, takes a consistent snapshot without locking the tables. Critical so the game doesn't freeze while you back up the live data in the Metin2 player schema.--quick: streams large tables row by row instead of buffering them in RAM.--routines --triggers: includes stored procedures and triggers as well.
To collect several schemas into a single file, use --databases:
mysqldump -u root -p --single-transaction --quick \
--routines --triggers \
--databases account player common > metin2_full.sql
Note: if you have MyISAM tables, --single-transaction does not guarantee consistency for them; in that case you need low write traffic at backup time or --lock-tables.
Writing a backup script
For automation let's prepare a reusable shell script. We put the dated filename, compression and old-backup cleanup logic in one place. Save it as /usr/local/bin/metin2-backup.sh:
#!/bin/bash
set -euo pipefail
BACKUP_DIR="/var/backups/metin2"
DBS="account player common"
KEEP_DAYS=14
STAMP=$(date +%F_%H%M)
mkdir -p "$BACKUP_DIR"
for DB in $DBS; do
mysqldump --defaults-extra-file=/root/.my.cnf \
--single-transaction --quick \
--routines --triggers "$DB" \
| gzip > "$BACKUP_DIR/${DB}_${STAMP}.sql.gz"
done
# delete backups older than 14 days
find "$BACKUP_DIR" -name '*.sql.gz' -mtime +$KEEP_DAYS -delete
Instead of hard-coding the password in the script, we read it from a separate credentials file with --defaults-extra-file. /root/.my.cnf looks like this and must be readable only by root:
[client]
user=root
password=A_STRONG_PASSWORD
chmod 600 /root/.my.cnf
chmod 700 /usr/local/bin/metin2-backup.sh
The set -euo pipefail line makes the script safe: if any command fails the script stops, so a corrupt or half-written backup isn't produced silently.
Scheduling with cron
After running the script manually and confirming with ls -lh /var/backups/metin2 that the .sql.gz files appear, we can move to scheduling. Edit root's crontab:
crontab -e
For a full backup every night at 04:00 plus an extra one every 6 hours:
# min hr day mon dow command
0 4 * * * /usr/local/bin/metin2-backup.sh >> /var/log/metin2-backup.log 2>&1
0 */6 * * * /usr/local/bin/metin2-backup.sh >> /var/log/metin2-backup.log 2>&1
Redirecting the output to a log file (>> ... 2>&1) matters; the day a backup fails, that's where you'll see why. Put the full backup at the time when player traffic is lowest to avoid the busy server-scene hours.
Off-site copy and verification
A backup on the same machine goes down with you if the machine dies. Copy the backups to another server or to object storage. You can add a simple rsync line at the end of the script:
rsync -az "$BACKUP_DIR/" backup@backup-server:/metin2/
The most-skipped step is the restore test. A backup that has never been tested isn't a backup. Once a month, make it a habit to restore the backup into an empty test database and look inside it:
gunzip < player_2026-06-28_0400.sql.gz | mysql -u root -p player_test
If the table count, latest characters and item records are as you expect, you know the backup actually works.
Frequently Asked Questions
Do I have to shut the server down to take a backup?
For InnoDB tables, no. Because --single-transaction takes a consistent snapshot, the game can stay online. For MyISAM tables, a brief lock or a low-traffic moment is preferable for full consistency.
How often should I back up?
The player schema should be backed up at least daily, ideally every 6 hours, because loss is felt most there. Since common and account change less often, a daily backup is usually enough. Tune the interval based on how many hours of data loss you can tolerate.
Does compression hurt performance?
gzip runs during the dump and uses CPU, but since it greatly reduces disk writes the net effect is usually positive. For very large schemas you can cut the time noticeably by using the parallel pigz instead of gzip.
Want to harden your server against data loss? If you need help setting up automatic backups, monitoring and disaster recovery for your Metin2 infrastructure, get in touch with me — let me help you sleep without losing your data.