MySQL Performance Tuning: Stop The I/O Bleeding in High-Load Web Apps
Let’s be honest. If your web application is sluggish, 90% of the time it’s not your PHP code loop—it’s your database gasping for air. I’ve spent the last week auditing a client's Magento deployment here in Oslo. They were ready to rewrite their entire frontend because of "latency issues." A quick look at top showed the CPU was 95% idle, but the iowait was screaming at 40%. Their database wasn't computing; it was waiting for a spinning rust hard drive to seek.
In the world of high-performance hosting, latency is the silent killer. If you are serving customers in Norway, you worry about two things: the milliseconds it takes to route through NIX (Norwegian Internet Exchange) and the milliseconds it takes your disk to find data. You can't fix the speed of light, but you can definitely fix your my.cnf.
The Hardware Reality: Spindles vs. Silicon
Before we touch a single configuration file, we need to address the elephant in the server room. If you are running a high-write database on a standard shared VPS with 7.2k RPM SATA drives, no amount of tuning will save you. The IOPS (Input/Output Operations Per Second) ceiling is simply too low.
In 2012, the biggest leap you can make is moving from HDD to SSD (Solid State Drive) storage. The random read/write speeds on SSDs are orders of magnitude faster than mechanical disks. At CoolVDS, we've benchmarked this extensively. A complex JOIN query that takes 1.2 seconds on a SAS RAID-10 array often completes in under 0.05 seconds on our SSD-backed KVM instances.
Pro Tip: If you cannot afford full SSD storage, ensure your hosting provider places the database partition on a high-performance tier or uses Flash caching technologies like Flashcache. But for serious workloads, pure SSD is the only future-proof path.
The Engine War: MyISAM is Dead, Long Live InnoDB
If you are still using MyISAM for your production tables, stop reading and migrate them now. MyISAM employs table-level locking. If one user writes to the table, everyone else waits. InnoDB uses row-level locking, which is essential for concurrency.
With MySQL 5.5 becoming the standard in repositories like EPEL for CentOS 6, InnoDB is the default engine. Ensure your architecture respects this.
Key InnoDB Configurations
The default MySQL configuration shipped with most Linux distributions (Debian Squeeze, CentOS 6) is criminally small, often assuming you are running on 512MB of RAM. Here is how we tune the [mysqld] section of /etc/my.cnf for a server with 8GB RAM dedicated to the database.
[mysqld]
# The most important setting. Set to 70-80% of TOTAL RAM for a dedicated DB server.
innodb_buffer_pool_size = 6G
# Only if you have a high write load and fast disks (SSD)
innodb_write_io_threads = 8
innodb_read_io_threads = 8
# The size of the redo logs. Larger means better performance but longer recovery time.
innodb_log_file_size = 256M
# Do not cache results. The query cache is often a bottleneck due to lock contention.
query_cache_type = 0
query_cache_size = 0
# Per-thread buffers. Be careful not to set these too high or you'll OOM.
sort_buffer_size = 2M
read_buffer_size = 2M
read_rnd_buffer_size = 8M
join_buffer_size = 8M
# Networking
max_allowed_packet = 64M
max_connections = 300
The ACID Trade-off
There is a setting called innodb_flush_log_at_trx_commit. By default, it is set to 1, meaning MySQL flushes data to the disk after every transaction. This is ACID compliance. It is safe. It is also slow.
If you can tolerate losing 1 second of data in the event of a total power failure (which is rare in our Oslo data centers equipped with UPS and diesel generators), change this setting:
innodb_flush_log_at_trx_commit = 2
This writes to the OS cache and flushes to disk once per second. In write-heavy applications, I have seen this single change improve throughput by 500%.
Operating System Tuning
MySQL lives on top of the Linux kernel. If the kernel manages the disk poorly, MySQL suffers. For database servers, the I/O scheduler is critical. The default cfq (Completely Fair Queuing) scheduler is designed for desktop responsiveness, not database throughput.
For virtualized environments, especially KVM, you want the deadline or noop scheduler. This allows the hypervisor to handle the ordering more efficiently.
Check your current scheduler:
cat /sys/block/sda/queue/scheduler
[cfq] deadline noop
Change it on the fly:
echo deadline > /sys/block/sda/queue/scheduler
To make it permanent, edit /boot/grub/menu.lst (or grub.conf on CentOS) and add elevator=deadline to your kernel line.
Swappiness
The Linux kernel loves to swap out memory to disk to keep the file cache large. For a database server, swapping is death. If MySQL's buffer pool gets swapped to disk, your performance falls off a cliff.
Check your swappiness (default is usually 60):
cat /proc/sys/vm/swappiness
Add this to /etc/sysctl.conf to tell the kernel "don't swap unless absolutely necessary":
vm.swappiness = 0
Why Virtualization Technology Matters
This brings us to a critical point about the Norwegian hosting market. Many providers use container-based virtualization like OpenVZ to oversell RAM. They tell you that you have 4GB of RAM, but it's "burst" RAM. When your neighbor's blog gets hit by Reddit, your MySQL performance tanks because that RAM is pulled out from under you.
At CoolVDS, we exclusively use KVM (Kernel-based Virtual Machine). With KVM, RAM is hard-allocated. If you configure your innodb_buffer_pool_size to 6GB, that memory is yours, guaranteed. The kernel won't steal it back. This stability is mandatory for consistent database performance.
Benchmarking Your Changes
Don't just guess. Measure. One of the best tools currently available is the Percona Toolkit (formerly Maatkit). Use pt-query-digest to analyze your slow query logs.
Enable the slow query log in my.cnf first:
slow_query_log = 1
slow_query_log_file = /var/log/mysql/mysql-slow.log
long_query_time = 1
Then run the analysis:
pt-query-digest /var/log/mysql/mysql-slow.log
This will give you a breakdown of the queries consuming the most resources, allowing you to add indexes or refactor code where it matters most.
Conclusion: Keep Data Local, Keep it Fast
Performance isn't just about raw speed; it's about reliability and compliance. With the Personopplysningsloven (Personal Data Act) strictly regulating how we handle user data in Norway, hosting locally in Oslo isn't just a latency play—it's a compliance strategy. But your users don't care about compliance; they care that the checkout page loads instantly.
By combining KVM isolation, SSD storage, and proper InnoDB tuning, you can turn a sluggish application into a market leader.
Ready to see the difference pure silicon makes? Deploy a high-performance CentOS 6 instance on CoolVDS today and get the I/O throughput your database deserves.