MySQL tuning for MU Online servers: the complete performance guide
Tune MySQL parameters to support high concurrency on MU Online servers: buffer pool, indexes, connection pool, slow query log, and maintenance routines.
The database is the most underestimated bottleneck on MU Online servers with many concurrent players: every login, item trade, position update, and event log generates queries to MySQL, and an out-of-the-box configuration simply wasn't built for this volume of small, frequent operations. This tutori
The database is the most underestimated bottleneck on MU Online servers with many concurrent players: every login, item trade, position update, and event log generates queries to MySQL, and an out-of-the-box configuration simply wasn't built for this volume of small, frequent operations. This tutorial covers complete MySQL/MariaDB tuning for MU Online, from memory parameters to indexing strategy and ongoing maintenance, aimed at those who already have a server running and are feeling slowness at peak hours.
Diagnosing the problem before tuning
Before changing any parameter, confirm the bottleneck really is the database. Enable the slow query log temporarily and observe which queries exceed an acceptable time threshold:
[mysqld]
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 1
log_queries_not_using_indexes = 1
After a few hours during peak time, analyze the log file (or use mysqldumpslow/pt-query-digest) to identify the slowest and most frequent queries. This directs your tuning effort at the real problem, instead of adjusting parameters generically.
Essential InnoDB parameters
InnoDB is the default and recommended storage engine for character, inventory, and account tables in virtually every MU emulator. The parameters with the biggest impact:
| Parameter | Function | Recommendation for MU |
|---|---|---|
innodb_buffer_pool_size | In-memory cache for data and indexes | 60-70% of RAM on a dedicated database server |
innodb_log_file_size | Transaction log size | 256M-1G, depending on write volume |
innodb_flush_log_at_trx_commit | Durability vs. write performance | 2 (good balance) instead of the default 1 (safer, slower) |
innodb_flush_method | OS I/O method | O_DIRECT on Linux, to avoid double buffering |
innodb_file_per_table | One data file per table | 1 (eases maintenance and space recovery) |
Connection and thread configuration
MU servers with multiple processes (GameServer, ConnectServer, JoinServer, DataServer/web panel) open many simultaneous connections to the database. Adjust:
[mysqld]
max_connections = 300
thread_cache_size = 64
table_open_cache = 4000
A common mistake is leaving max_connections at its low default (usually 151), which causes "too many connections" errors right at peak hours, when more players are logging in and generating connection spikes.
Essential indexes on MU tables
Most emulators already ship with basic indexes on the main tables (Character, AccountCharacter, Warehouse), but as the server grows it's common to need additional indexes for custom queries (rankings, donation systems, audit logs). Before creating indexes, identify repeated slow queries in the slow log and check the execution plan:
EXPLAIN SELECT * FROM Character WHERE AccountID = 'exemplo' AND Ctl1 = 0;
If EXPLAIN shows type: ALL (full table scan) on a large table, that's a sign of a missing index on the column used in the filter. Add it carefully in production, preferably during low-traffic hours, since creating an index on a large table can temporarily lock writes.
Optimizing log and ranking tables
Log tables (login, GM command, item transaction) grow indefinitely and are rarely optimized by admins. Two recommended practices:
- Date partitioning on very large log tables, so recent queries (the most common ones) don't have to scan the entire history.
- Periodic archiving: move records older than X months to a separate history table, or export and truncate, keeping the active table lean.
Ranking tables (top level, top guild, top reset) often run in heavy cron jobs — if the script recalculates everything from scratch on every run, consider optimizing for incremental updates or running it during low-traffic hours.
Connection pooling in the application (emulator)
Besides tuning MySQL itself, check whether the emulator is using a connection pool efficiently or opening/closing new connections on every operation — the latter generates unnecessary handshake overhead. .NET-based emulators generally use a connection string with pooling enabled by default; confirm the Min Pool Size and Max Pool Size parameters in the GameServer's and web panel's connection strings, adjusting them for the expected number of concurrent players.
Query cache configuration (where applicable)
Older MySQL versions (up to 5.7) support query_cache, useful for identical repetitive queries, but with concurrency limitations under high write loads. In versions 8.0+ the feature was removed — in that case, consider caching at the application layer instead (e.g., caching rankings in the web panel) rather than relying on the database for this kind of optimization.
Ongoing monitoring
Lightweight monitoring tools (Percona Monitoring and Management, or simply scheduled SHOW STATUS/SHOW ENGINE INNODB STATUS scripts) help catch trends before they become incidents. Pay special attention to:
| Metric | What it indicates |
|---|---|
Threads_connected close to max_connections | Imminent risk of connection errors |
High Innodb_buffer_pool_wait_free | Undersized buffer pool |
Growing Slow_queries | Need to review indexes/queries |
High Innodb_row_lock_waits | Lock contention, possibly a long-running transaction |
Maintenance and backup routine
Schedule periodic OPTIMIZE TABLE on tables with a high update/delete rate (inventory, characters), since InnoDB accumulates fragmentation over time. For backups, prefer hot backup tools (like mariabackup/xtrabackup) for large databases, avoiding the table locking a traditional mysqldump can cause in production. Always run backups during low-traffic hours and periodically validate that the backup is restorable — a backup that's never been tested is just an assumption.
Common errors and fixes
| Symptom | Likely cause | Fix |
|---|---|---|
| "Too many connections" at peak times | max_connections at the low default | Increase it based on the number of processes and concurrent players |
| General slowness logging in/buying/selling | Buffer pool too small for the data volume | Increase innodb_buffer_pool_size based on available RAM |
| Ranking query periodically freezes the server | Full recalculation with no incremental optimization | Rewrite for incremental updates or run it off-peak |
| Backup makes the server slow during execution | mysqldump locking tables in production | Migrate to hot backup or schedule it during low-traffic hours |
| Very large log tables slow down queries | No partitioning/archiving | Implement periodic archiving and date partitioning |
MySQL tuning checklist for MU Online
- Slow query log enabled and analyzed before any adjustments.
- InnoDB parameters (buffer pool, log file, flush method) adjusted to available RAM.
max_connectionsandthread_cache_sizecalibrated for the server's number of processes.- Indexes reviewed with
EXPLAINon the identified slowest queries. - Archiving/partitioning routine applied to log tables.
- Emulator connection pooling validated (Min/Max Pool Size).
- Ongoing monitoring of key metrics configured.
- Hot backup tested and validated as restorable.
With the database tuned to support your real player volume, the next step is reviewing the overall game server configuration that depends on this foundation: see the MU Online server setup tutorial to understand how GameServer, ConnectServer, and the database work together in the complete architecture.
Frequently asked questions
What's the difference in tuning between MySQL and MariaDB for MU Online?
Most tuning parameters (buffer pool, indexes, connection pool) are compatible between the two, since MariaDB is a fork of MySQL. Differences show up in specific query optimization features and the default storage engine in some versions — always confirm the exact version before applying configs copied from forums.
How much RAM should I dedicate to the InnoDB buffer pool?
A common benchmark is 60-70% of the available RAM on a dedicated database server, leaving the rest for the OS and other processes. On shared servers (database and game on the same machine), reduce that ratio so you don't starve the GameServer.
Is it worth using an SSD for the MU Online database?
Yes, it's one of the highest-value upgrades you can make. MU's database access pattern (many small, frequent reads/writes for characters, inventory, logs) benefits far more from high SSD IOPS than from raw HDD capacity.
How do I know if my server needs database tuning?
Clear signs include noticeable slowness logging in, lag opening inventory/shop, and timeout messages at peak hours. The slow query log is the most direct tool to confirm it: if it's accumulating queries over 1-2 seconds frequently, tuning is needed.
Does automatic backup affect production performance?
It can, if poorly configured. A full dump (mysqldump) locks tables or generates heavy I/O load during execution. Prefer running backups during low-traffic hours and consider incremental/hot backup tools for large databases.