Overview
DataServer persists character, item, guild, and event data to SQL Server
DataServer is the only component that talks to SQL Server. Every GameServer routes persistence (character load/save, inventory, warehouse, guild, chaos box, rankings, cash shop) through it. DataServer also owns the Write-Ahead Log that records critical save operations before the SQL transaction runs so interrupted saves can be detected and replayed on the next startup.
Role
Loads characters and inventories on login, saves them on logout and periodic autosave
Handles warehouse, chaos box, personal shop, and cash shop persistence
Stores guild, alliance, Castle Siege, and Gens state
Writes a Write-Ahead Log entry before character, warehouse, and chaos box saves; entries are replayed on startup when the database's
LastSaveIdshows the save was not committedRejects GameServer connections whose IP is not whitelisted
Filters character names against a bad-word list (guild names only get the baseline space-and-quote check, not the list)
File Location
DataServer/
├── DataServer.exe
├── DataServer.ini
├── AllowableIpList.txt
├── BadSyntax.txt
├── WAL/ (created on first run)
│ └── WAL_YYYYMMDD.bin
└── METRICS/ (created on first run)
└── DSMetrics_YYYYMMDD.csvAll configuration lives in the DataServer root. There is no Data/ subfolder.
Configuration Files
Database, port, logging, license
GameServer IP whitelist
Forbidden substrings in character names (creation, availability check, rename)
Startup Order
WAL init and replay
Creates the WAL folder if missing, opens today's WAL_YYYYMMDD.bin, and scans it for entries with status pending. For each pending entry, DataServer queries the target row's LastSaveId in SQL; if the DB column is still behind the WAL entry id, the save is replayed and marked complete. Already-applied entries are skipped. Incomplete saves are counted in a red log line.
If primary or pool connection fails, DataServer does not open its TCP port. GameServers will queue save requests and eventually disconnect players. Fix the database before restarting.
Dependencies
SQL Server with the
MuOnlinedatabase restored from the shipped backupODBC DSN (name configured in
DataServerODBC) registered on the DataServer hostGameServer IPs listed in
AllowableIpList.txtWritable working directory for
WAL/andMETRICS/subfolders
Write-Ahead Log
Before executing a character, warehouse, or chaos box save, DataServer appends a WAL entry with status pending to WAL/WAL_YYYYMMDD.bin and flushes it to disk. After the SQL transaction commits, the entry is updated in place to status complete. A crash between the two writes leaves the entry pending.
On startup, DataServer walks the WAL file and for each pending entry queries the target row's LastSaveId column in SQL:
If
LastSaveIdis greater than or equal to the WAL entry id, the save already committed and the entry is skippedOtherwise the save is replayed against the database,
LastSaveIdis written with the WAL entry id, and the entry is marked complete
Details:
One WAL file per calendar day; the file rolls automatically when the day of month changes
Each entry is a fixed-size header followed by the raw save payload; do not edit by hand
Entry types covered: character save, warehouse save, chaos box save. Inventory-only saves are not written separately because they are part of the character save
The log is compacted in place after many completes, keeping only still-pending entries; a
.bakcopy of the pre-compact file is left next to itWAL files accumulate across days; archive or delete old ones as disk allows
A non-zero pending count on startup is a signal to investigate the previous shutdown
Metrics
Every 10 seconds the metrics thread appends a row to METRICS/DSMetrics_YYYYMMDD.csv covering query count and timings, queue adds, overflows, queue peak depth, save counts, and derived per-second rates. The CSV header is written automatically when a new daily file is created. The DataServer window title and status bar show the live queries-per-second, queue peak, and overflow count.
Use metrics to verify the pool is keeping up. A sustained queue peak near the limit or any overflows mean either SQL Server is too slow or the pool size is undersized for the player load.
Common Issues
"Could not connect to database" - verify the ODBC DSN name, credentials, and that SQL Server is reachable
"Could not connect pool connection N" - the DSN works for 1 connection but rejects more; check SQL Server
max connectionsand the login's allowed sessions"[WAL] Found N incomplete saves from previous session" - last shutdown was not clean. Review the log for the affected characters; the data on disk is whatever was committed before the crash
GameServer connects then drops - its IP is not in
AllowableIpList.txtCharacter name creation fails for valid-looking names - a
BadSyntax.txtentry matches as a substring
Last updated