Incremental vs. full backup for MU Online servers: which to choose
Understand the differences between full, incremental, and differential backups for MU Online servers, with script examples, retention rotation, and a testable disaster recovery plan.
Losing the database of a MU Online server — accounts, characters, items, guilds, ranking history — is the kind of incident that can end a project overnight, especially if the community has already invested time and money in it. The question "incremental or full backup" doesn't have a single answer:
Losing the database of a MU Online server — accounts, characters, items, guilds, ranking history — is the kind of incident that can end a project overnight, especially if the community has already invested time and money in it. The question "incremental or full backup" doesn't have a single answer: the right choice depends on database size, how frequently the data changes, and the acceptable recovery time in case of disaster. This tutorial explains the technical differences between backup types, shows how to combine them in practice for a MU server, and presents a testable recovery plan — because a backup that's never been restored is just an assumption.
The three types of backup
Before deciding on a strategy, you need to understand exactly what each type does:
| Type | What it copies | Generation speed | Restore speed | Disk space |
|---|---|---|---|---|
| Full | The entire database/files, from scratch | Slow | Fast (single file) | High |
| Incremental | Only what changed since the last backup of any type | Very fast | Slow (depends on the whole chain) | Low |
| Differential | Only what changed since the last full backup | Fast (grows over time) | Medium (full + 1 differential) | Medium |
The choice between incremental and differential is the most commonly confused point: incremental is lighter to generate, but riskier to restore, because the whole chain (full + incremental 1 + incremental 2 + ... + incremental N) needs to be intact. If an intermediate file gets corrupted, everything after it becomes useless.
What needs to go into a MU server backup
Many admins back up only the database and forget files essential for a full recovery:
| Component | Why it's critical | Recommended frequency |
|---|---|---|
| Database (accounts, characters, items, guilds) | Loss = total loss of player progress | Daily full + incremental/log every 15-30 min |
| Server configuration files (GameServer, ConnectServer, JoinServer) | Recreating from scratch can take hours if undocumented | On every change + weekly |
| Transaction/audit logs (trades, GM commands) | Needed to investigate disputes and fraud after an incident | Together with the database backup |
| Client and custom files (items, maps, custom wings) | Loss requires rebuilding all customization work | Weekly or per release |
| Automation scripts (cron, deploy, anti-cheat) | Without them, restoring the server doesn't recover full operation | On every change |
Recommended strategy by server size
There's no single strategy — database size and active player volume change the cost-benefit calculation.
| Server size | Recommended strategy | Retention |
|---|---|---|
| Small (up to 200 online) | Daily full backup, no incremental (small enough database) | 14 days |
| Medium (200 to 1000 online) | Weekly full + daily incremental | 30 days full, 14 days incremental |
| Large (1000+ online) | Daily full + incremental/log every 15-30 min | 30 days full, 7 days of transaction log |
Full backup script example (MySQL/MariaDB)
Most MU emulators (MuEmu, IGCN) use MySQL or MariaDB. A basic full backup script, scheduled via cron:
#!/bin/bash
DATA=$(date +%Y%m%d_%H%M%S)
DESTINO="/backup/mu/completo"
BANCO="mu_online"
mysqldump --single-transaction --routines --triggers \
-u backup_user -p"SENHA_AQUI" "$BANCO" | gzip > "$DESTINO/full_${BANCO}_${DATA}.sql.gz"
# Remove full backups older than 30 days
find "$DESTINO" -name "full_${BANCO}_*.sql.gz" -mtime +30 -delete
The --single-transaction parameter is essential on InnoDB databases — it guarantees a consistent database snapshot without locking tables during the dump, avoiding noticeable impact for online players during the backup.
Incremental backup example via binlog (MySQL)
For true incremental backups (not just a "small full backup"), enable MySQL's binary log and back it up periodically:
# my.cnf — enable binlog
[mysqld]
log-bin = /var/log/mysql/mu-bin
binlog_expire_logs_seconds = 604800
server-id = 1
#!/bin/bash
# Copies the binlogs generated since the last full backup
DESTINO="/backup/mu/incremental"
mysqladmin -u backup_user -p"SENHA_AQUI" flush-logs
cp /var/log/mysql/mu-bin.* "$DESTINO/"
Restoring with binlogs requires applying the most recent full backup and then "replaying" the binlogs in exact order — so always document the chronological order of the files in their names or in a separate index.
Rotation and retention policy (3-2-1)
The classic 3-2-1 backup rule applies well to MU servers: 3 copies of the data, on 2 different media, with 1 copy off-site from the server's physical location (another city, another cloud provider). A VPS hosting the backup on the same machine as the production server isn't a real backup — it's just a copy that dies together in the same incident (disk failure, breach, provider account ban).
| Copy | Suggested location | Purpose |
|---|---|---|
| 1st copy | Separate disk on the same server | Fast recovery from an operational error (bad query, accidental deletion) |
| 2nd copy | Another server/VPS, same region | Recovery if the primary disk fails physically |
| 3rd copy | Cloud storage (S3, Backblaze, Google Cloud Storage) in another region | Total disaster recovery (breach, account ban, datacenter fire) |
Backup encryption and security
A backup containing player account data (even with hashed passwords) is a sensitive asset — if leaked, it exposes emails, login IPs, and store purchase history. Encrypt the file before sending it to the cloud:
gpg --symmetric --cipher-algo AES256 --output "full_mu_online_${DATA}.sql.gz.gpg" "full_mu_online_${DATA}.sql.gz"
Store the encryption password in a password vault separate from the server infrastructure — if the server is compromised, the encrypted backup stays protected even if the attacker has access to the machine.
Testing the restore (the step everyone skips)
A restore-testing schedule should exist regardless of how "reliable" the process seems:
- Reserve an isolated environment (test VPS or container) with no access to the production network.
- Restore the most recent full backup from scratch.
- Apply the incrementals/binlogs in the correct order, if applicable.
- Bring up the GameServer pointing to that restored database and validate login, character, and inventory for a known test account.
- Document the total time spent — that number is your real RTO (recovery time objective), not a theoretical estimate.
Backup failure monitoring and alerts
A backup that fails silently is worse than having no backup at all, because it creates a false sense of security. Set up automatic alerts (Discord webhook, email) when the backup script finishes with an error or when the generated file's size is abnormally small compared to its history:
TAMANHO=$(stat -c%s "$DESTINO/full_${BANCO}_${DATA}.sql.gz")
if [ "$TAMANHO" -lt 1000000 ]; then
curl -H "Content-Type: application/json" -d '{"content":"⚠️ MU backup produced a suspiciously small file!"}' "$WEBHOOK_DISCORD"
fi
Common errors and fixes
| Symptom | Likely cause | Fix |
|---|---|---|
| Restore fails due to a missing incremental file | A binlog in the chain was deleted by automatic rotation | Adjust binlog_expire_logs_seconds and sync it with the full backup's retention |
| Full backup locks up the game while generating | Missing --single-transaction in mysqldump | Add the parameter for a consistent dump without table locking |
| A never-tested backup fails during a real recovery | No restore-testing routine | Schedule a monthly test in an isolated environment |
| All backup copies live on the same server | No 3-2-1 policy | Send at least one copy to another region/provider |
| Failure alert never arrives | Script has no success/file-size check | Add exit code and size checks with webhook notification |
Backup strategy checklist
- Full backup scheduled at a frequency suited to the server's size.
- Incremental or differential configured if change volume justifies it.
- 3-2-1 rule applied (off-site copy from the production server).
- Files encrypted before any upload to the cloud.
- Automatic backup failure alert configured.
- Full restore test performed in an isolated environment within the last month.
- Restore order documentation (full + incrementals) up to date.
With the backup strategy validated and tested, the natural next step is to review the server's overall infrastructure — from provisioning to security configuration — described in more detail in the MU Online server creation tutorial.
Frequently asked questions
Is incremental backup always faster than full?
Yes, at generation time — it only copies what changed since the last backup. But restoring is slower and riskier, because it depends on the entire chain of previous incrementals being intact.
Can I use only incremental backups and never do a full one again?
Not recommended. The incremental chain grows indefinitely, and any corrupted file in the middle invalidates the restore of everything after it. Redo a full backup periodically (weekly is common) to 'reset' the chain.
What's the difference between incremental and differential?
Incremental copies only what changed since the last backup (of any type). Differential copies everything that changed since the last full backup. Differential uses more space than incremental, but restores faster, because it only depends on the full backup plus the last differential.
How often should I back up the database of an active MU server?
For servers with active players, a daily full database backup (outside peak hours) plus incremental transaction log backups every 15-30 minutes is a common practice, minimizing progress loss in case of failure.
Is testing the backup really necessary if it has 'always worked'?
Yes, mandatory. A backup that has never been restored is an assumption, not a guarantee. Reserve a monthly test environment to restore the most recent backup from scratch and validate that the server comes up correctly with that data.