The settings I tweaked for the database server? They were only part of the problem. They were just the beginning.
My VPS has only 128 megabytes of dedicated memory. No, that's not a lot of memory, but for a simple web server, it's sufficient. At least, it's sufficient IF some settings are right.
Unless you want to learn WAY more than you ever wanted to about memory management on Linux systems, you'd probably better stop reading now. This is going to get WAY beyond geeky here.
No. Seriously. If you're not interested in minute technical details, you'd better stop reading or your head just might explode.
One of the nice things about a Virtual Private Server that you don't get with most shared hosts is a command prompt with root access. With this type of command prompt, you have the ability to troubleshoot things like memory issues.
The first thing that I checked was /var/log/messages. I found regular messages in this log that said things like:
Out of memory: Killed process 7716 (mysqld)
Out of memory: Killed process 7725 (httpd)
This made it pretty clear that it really WAS a memory issue and that the programs suffering most from lack of memory were my database server (MySql) and my web server (Apache). Since these two things are, to say the least, critical for web sites (they're the core of most web sites, especially sites with blogs), I needed to figure out how to keep these servers from being killed. These servers were asking for more memory than existed, so they were being stopped by the machine.
My next step was to look at the memory usage on the machine. I saw that the total memory available was barely higher than the amount of memory in use. That worried me at first until I did some research and found that this situation is very normal with Linux systems that have limited memory. The next thing I looked at was the memory buffers used. This shows how much memory is actually being used by applications. The absolute maximum amount of memory available is the amount of physical memory plus the amount of "swap space" (which I'll explain in a moment). The disturbing thing about the memory buffers was that it appeared dangerously close to the absolute maximum amount of memory available.
So... How to fix this? I needed to find out which applications were hogging memory and I needed to figure out how to make them stop being such bloated pigs.
I found out that there is a way to display what percentage of total memory was used by each process. From that, I found out that the worst offender was the Apache Web Server and another big problem child was Spam Assassin. Apache will create multiple servers (to serve up multiple simultaneous requests), each of which can consume 15% of the server's memory. Apache alone was eating up about 60% of the memory available and Spam Assassin had multiple copies running, each of which was using about 7% of the memory. Add to that a MySql database server that was using about 15% of the available memory, and guess what. I was OUT of memory.
So what does the system do when it runs out of memory? It uses swap space.
Swap space is simply disk space that is used as memory by the system. When running a program a computer will first check and see if the needed part of the program is already in memory. If it is, it will use the program in memory. If not, it then checks to see if it's in the "swap space" on disk. If it's there, it has to copy it from the disk to memory. If there's not enough free memory to copy it into memory, it first has to copy something from memory into the swap space. Thus, it swaps different applications back and forth between system memory and disk. Why is this a problem? Memory access = usually very very fast. Disk access = usually very, very, very slow in comparison. Access to memory is measured in nanoseconds, or BILLIONTHS of seconds. Access to disk is measured in milliseconds, or THOUSANDTHS of seconds. So realistically, memory access is a million times faster. If memory could run the hundred yard dash in 10 seconds, a disk could run it in just under 116 days.
The other problem is that the swapping of memory blocks from memory to disk takes time and processing power. So as more swapping takes place, the entire system slows down.
So I checked to find out how much swapping was taking place.
The Swap In and Swap Out numbers were in the mid-hundreds. This meant that my server was doing way way WAY too much swapping. Good numbers would be close to zero. The less swapping, the more that memory is being accessed instead of disks and the faster the system will run.
So I needed to find out how to make the memory-hogging programs not hog as much memory. A little research later and I found out that I needed to:
- Limit the amount of memory that MySQL was using by adding 3 or 4 lines to a configuration file.
- Limit the number of web servers by changing about 3 lines in a configuration file.
- Limit the number of spam assassin servers by changing a line in a couple of configuration files.
So by making a few small changes, I could solve this problem. I made the changes and the results are great! Apache is using about half of the memory it used to. Spam assassin is using less than a third of the memory it used to. MySql is using less than half of the memory it used to. These three changes dropped my swap in/swap out numbers from the mid hundreds each to 1 and 2 (at this moment) respectively.
The bottom line: You probably didn't have to wait forever to read this long, way-too-technical, very boring post. I learned a lot. I'll be able to fix problems like this in the future. And I didn't have to pay more to add memory to my server. All of those things are GOOD things!