Disaster: MySQL 5.5 Flushing
mysqlperformanceblog.com
mysqlperformanceblog.com
This is really terrible news for anyone trying to do high-throughput DB operations on mySQL.
The only "good" news is that the average web app isn't going to be running on hardware anywhere near as powerful as this, so you are highly likely to already be in the "slower", consistent state (e.g. anything less than 40GB of RAM).
Solid State Drives is the easiest solution to most problems requiring high I/O throughput and data persistence.
Too bad most cloud hosting vendors are way behind on offering anything like that.
EDIT: Not sure why this comment got down voted, but perhaps whoever did it might comment on why using SSD is not a solution.
SSD might be a solution, but we don't have any proof either way, and we also don't understand why is this problem happening.
=============================
What to do?
I wish I could say you should use Percona Server with XtraDB.
If we were using SSD as storage, then I would recommend it. Vanilla MySQL performs equally bad on SSD and HDD, while for SSD in Percona Server we have “innodb_adaptive_flushing_method = keep_average”.
Unfortunately on spinning disks (as in this case), Percona Server may not show significant improvement. I am going to followup with results on Percona Server.
=============================
SSD is the solution because unlike rotational disks it allows for lots of random accesses. While they are too expensive to use as "archiving" storage, SSD excels as a layer between traditional disks and RAM. Put your high I/O workload on SSD and keep your historic data on spinning disks.
If you want to see some SSD benchmarks, here is your resource: http://www.ssdperformanceblog.com/
As far as cloud storage, yes, Amazon EC2 offers 68GB RAM, however if you need hardware of that size it is not hard to justify setting up your own servers. It would be cheaper too and you'll be able to fully optimize your storage.
SSDs really help this process happen faster because they have way better random write performance than hard disks.
My macbook pro I upgraded with a gaming grade SSD gets 100-200 mb/s random write.
Just upgrading to SSDs is more viable than hacking up a database with a huge community behind it that you didn't originally create yourself.
It is hard to see the benefit of ignoring SSD to get high I/O performance vs. redesigning the software around I/O bottlenecks.
Redesigning software to work on bad hardware is definitely a challenging project, but not always the best use of resources.
Especially when it indeed is "crappy software" that will take major effort to rewrite/refactor.
Hardware is cheaper than developers, and the former doesn't fail to deliver half as often as the latter...
Also, you need to compare the cost of a single developer who fixes innodb to the cost of hardware incurred by _all_ users of innodb who would benefit from the solution.
Trying to fit high I/O workloads on spinning disks is a lot like spending your efforts to make your program run on 64K RAM. An interesting challenge, that would surely exercise your coding skills, but would not deliver the optimal performance.
If we were using SSD as storage, then I would recommend it.
Vanilla MySQL performs equally bad on SSD and HDD,
while for SSD in Percona Server we have
innodb_adaptive_flushing_method = keep_average.
Doesn't seem like a solution at all, if we believe the author.Given that Percona is fully backwards compatible with MySQL, while adding this and many other tuning options, I just cannot see a reason to use vanilla MySQL ever.
I wanted to share some of our data to help in your decision making:
A typical server in our cluster gets 5000 to 7500 TPS:
This is a 24 hour graph and as you can see there are no multi-minute lockups. We've been extremely happy with the performance our servers are delivering.
The config is 8GB of memory, RAID 1, 2X 15K RPM disks, single Intel E5410 quad core CPU.
Total DB size is around 12GB with around 15 million rows. Our TPS is higher than Vadim's but our data is smaller than the benchmark he uses which is 200 million rows in a 58 GB database.
With the following for innodb:
innodb_file_per_table = 1
innodb_flush_log_at_trx_commit = 0
innodb_buffer_pool_size = 5G
innodb_additional_mem_pool_size = 20M
innodb_log_file_size = 1024M
innodb_log_buffer_size = 16M
innodb_max_dirty_pages_pct = 90
innodb_thread_concurrency = 4
innodb_log_group_home_dir = /var/lib/mysql/
innodb_log_files_in_group = 2
So my approach to avoiding this issue will be to shard to finer granularity and avoid architectures with monolithic DB's. Keep in mind that this only affects your ability to cache greater than around 16GB, so spreading massive data across multiple servers with fast drives and moderate memory will help bring your TPS back up. I would also add that servers with memory > 32GB are very expensive - especially the memory itself. So it may not cost much more to have 5 servers with fast disk and moderate memory vs one server with massive memory.Having said all that this is obviously a very serious problem and perhaps an opportunity for a talented computer scientist to branch InnoDB and solve it if Oracle doesn't want to.
This is cheating, you've effectively disabled the 'D' in ACID; you aren't doing an fsync() at every commit.
Just depends whether or not you can deal with a small amount of lost data in the event of a crash.
>Hardware: HP ProLiant DL380 G6, with 72GB of RAM and RAID10 on 8 disks.
Playing devil's advocate - there is no proof that PostgreSQL does not have any teething problems on high capacity hardware either.
I'd personally rather buy high end SPARC64 kit which has linear performance scalability but we all know what happened to Sun, plus it doesn't run Windows anyway :( whimpers a little
I have seen throughput issues on VMWare machines (and false reporting on standard linux utilities, eg "time" output and various other issues that make me distrust it for performance-sensitive software), but don't know if this is to do with 128G machines; usually it's to do with contention on one network card handling all traffic to disks.
At Disqus we run Postgres on even larger boxes without pauses described here. We would have (had to) migrate off long ago if this were par for the course.
Not nearly as bad in magnitude, and with some shared responsibility with Linux and file system code (since PG relies of filesystem's caching). Greg Smith talked about it in some detail during PGWest 2010. One of his customers had long stalls in production and Greg worked out how to reproduce and explain them.
He had some patches he was planning for Postgres 9.1, not sure if they went in.
The mentioned spec can be had for roughly $7000 USD, depending on CPU.
http://notemagnet.blogspot.com/2008/08/linux-write-cache-mys...
When faced with this situation it seems to me you have three choices at a high level:
- throttle writes closely to your random i/o limit, eliminating your ability to accomodate brief write spikes
- throttle writes less aggressively, accommodating brief spikes but forcing stalls under sustained load as seen here
- don't throttle at all and postpone catching up until commitlog replay on restart, if necessary
None is without downside.
First, it is useless to store data in memory if you want them be committed into disk storage. The general idea here isn't about switching to some new version of mysql or SSD disks, it is about to realize that you have a data-flow inadequate for your one-server architecture.
Second - check-point intervals should be adjusted to your actual data-flow, which means they should be executed often enough. If there is situation of almost constant checkpoint - non-stop data writes, that is the sign that you need to consider sharding/multi-server solution.
The hints that there must be no other disk activity on the same hardware volume or any swapping in OS, I suppose, are obvious. People who have a /var/log and /var/db on the same volume are idiots.
There are also good idea to use one file per table storage and put a data and physical logs on a separate hardware volumes (links are your friends). One raid-X volume that fits all is a quite naive solution. Raid isn't a guaranty of reliability. Replications to a back-up servers are.
Third, when you test your configuration before put it into production, you should tune-up your servers to perform with data and log syncing, and then figure out appropriate buffer sizes and checkpoint intervals. Then, in production, when you're experiencing an increasing flow of queries, you may choice to switch into different syncing strategy and/or more often but a little bit faster checkpoints.
Configuring mysql with huge buffers and no sync means lack of understanding the basic concepts, self-delusion and misuse of software and hardware. ^_^
You got this part all wrong. He explicitly said that 'their solution' is unlikely to do any better. This is a real problem.
From the article I get the impression that this is a new problem introduced with 5.5.
Last time I checked that was a recipe for terrible performance. We normally leave the flush_method set to default and keep a couple slaves around to minimize the potential for data loss.
* You're not talking to a SAN or a virtual disk device.
* You use a filesystem that allows concurrent updates to O_DIRECT opened files, like XFS.
(For comparison, see ZFS)
> Disaster: MySQL 5.5
> MySQL
I found your problem right here.
Anither option is to use materialized views, which are not natively supported in MySQL, but can easily be simulated.