For the last week or so, FeedLounge has been vacillating between “moderately slow” and “unusable”. After an excruciating investigation into the bowels of the application, database and server, I believe I have identified the root of the issues with the slowdown of the past week - and thought I would share it with everyone.
Disclaimer: This post might come across as my complete lack of understanding as to how MySQL operates, but let me assure you that I have used MySQL for five+ years, in some heavy enterprise situations.
For the last week, I have been digging into FeedLounge anywhere and everywhere to see if I could uncover the problem. Yesterday, in watching the server using top, vmstat, and mtop (mysqltop), I found the cause.
When designing the FeedLounge database I decided to use MyISAM tables, mainly for the capability of full-text search. I did understand that the MyISAM engine performs table level locking, but this never presented itself as a problem in any of our testing.
It seems that the MyISAM engine has a special condition whereby INSERTs do not lock the table, IF the table has never had a DELETE executed on it. When we moved to our new server, everything was fine until we did some data manintenance a couple weeks ago. The clean-up we did (deleting a few rows) has sent the application in a downward spiral performance-wise.
This morning I caught 40 queries locking on 2 INSERTs, and all the queries had crossed 300 seconds of real time. Obviously, we cannot expect any FL user to wait 5+ minutes for an item from a feed to load - but that is what was happening.
We are currently testing a switch to the InnoDB engine, which does row level locking and also keeps primary keys and data in order (so most queries should speed up for us). This is somewhat counter-intuitive, but FeedLounge needs the scalibility of row-level locking more than the performance of the MyISAM engine.
If you asked me when I started this, I would have told you that a web-based feedreader is just another web application, but that just is not be the case. Because of the input and output sides of a feed reader, the application does nearly as many writes to the database as it does reads from the database. This fundamentally changes the way I tackle problems at the database level.
How did I find this problem? First, *lots* persistence in looking for the problem (since Alex and I both agreed with the users about the slowness). Second, the world’s best MySQL book, High Performance MySQL, by Jeremy Zawodny and Derek Balling. These little caveats are the types of things that the book is loaded with. If you are dealing with a database that is larger than the RAM on your machine by a few orders of magnitude, this book is “The Book” you should be reading.
If our testing shows that we indeed have identified and fixed the problem, we’ll take FeedLounge offline tonight to make the needed changes to the database (it already takes more than an hour to re-load the database, and we’re only in alpha!).
We greatly appreciate the patience our alpha testers have displayed as we work through these growing pains.