Swapping on Linode 512

I have setup a LAMP server in Ubuntu 11.10 and sometimes (it looks relatively random), something takes a lot of memory and the server swaps a lot with some oomkill in /var/log/syslog as the swap becomes full. Last night oomkiller has been called 176 times.

When the madness stops, I can see "/etc/mysql/debian-start" being called in syslog, not sure if there is related or not.

It can last several minutes to nearly 2 hours.

This is what the 24-hour CPU, Bandwidth and Disk IO charts look like:

~~![](<URL url=)http://www.cnx-software.com/wp-content/ … 4_hour.jpg">http://www.cnx-software.com/wp-content/uploads/2012/02/linodeswapping24_hour.jpg" />

30 days Disk IO chart:

~~![](<URL url=)http://www.cnx-software.com/wp-content/ … 30days.jpg">http://www.cnx-software.com/wp-content/uploads/2012/02/linodeswapping30days.jpg" />

Log excerpt of what I get during oom_killer: http://pastebin.com/qeCNWnVH

There seems to be way too many apache2 processes (148), although all incoming traffic has stopped.

I've checked /etc/log/apache2/error.log, and I cannot see any specific errors during swap (There are a few segmentation fault reports).

So now, I'm a bit lost and I'm not sure what I should do from here.~~~~

7 Replies

What's your maxclients set to? Read ~~[http://library.linode.com/troubleshooting/memory-networking" target="_blank">](http://library.linode.com/troubleshooti … networking">http://library.linode.com/troubleshooting/memory-networking](

Thank you. It was set to 150. I've set it MaxClients to 24 and the other "Prefork MPM" settings used in this link and restart apache2.

I'll see how it goes.

The problem still occurs even after all optimizations for both Apache and MySQL. Should I further reduce the number of clients?

I wonder if there is some kind of memory leaks in Apache/MySQL or (more likely) a bug in my Wordpress (and plugins) installation that could create this problem.

I'm also considering to use monit to restart apache2 if the swap usage is greater than 25%, this is not ideal, but could be a workaround.

Depending on what plugins you have, MaxClients 24 might still be too high. Some plugins guzzle RAM like a Hummer guzzles gas. Even if it was only 20MB per page, 24 simultaneous page views will use up 20x24=480MB of RAM. And I've seen plugins use upwards of 100MB per page. Some scary stuff.

Try reducing MaxClients even further, like 15. Also disable KeepAlive to prevent clients from monopolizing connections (which can be a serious concern when you have low MaxClients).

That's for Apache & PHP. What about MySQL? Could you post the contents of /etc/mysql/my.cnf here?

I've just noticed I only changed MaxClients in section, but there are also sections , with this value. I'll change that as well, even though during the crash there is only 24 apache2 processes.

Here's my.cnf:

#
# The MySQL database server configuration file.
#
# You can copy this to one of:
# - "/etc/mysql/my.cnf" to set global options,
# - "~/.my.cnf" to set user-specific options.
#
# One can use all long options that the program supports.
# Run program with --help to get a list of available options and with
# --print-defaults to see which it would actually understand and use.
#
# For explanations see
# http://dev.mysql.com/doc/mysql/en/server-system-variables.html

# This will be passed to all mysql clients
# It has been reported that passwords should be enclosed with ticks/quotes
# escpecially if they contain "#" chars...
# Remember to edit /etc/mysql/debian.cnf when changing the socket location.
[client]
port            = 3306
socket          = /var/run/mysqld/mysqld.sock

# Here is entries for some specific programs
# The following values assume you have at least 32M ram

# This was formally known as [safe_mysqld]. Both versions are currently parsed.
[mysqld_safe]
socket          = /var/run/mysqld/mysqld.sock
nice            = 0

[mysqld]
#
# * Basic Settings
#

#
# * IMPORTANT
#   If you make changes to these settings and your system uses apparmor, you may
#   also need to also adjust /etc/apparmor.d/usr.sbin.mysqld.
#

user            = mysql
socket          = /var/run/mysqld/mysqld.sock
port            = 3306
basedir         = /usr
datadir         = /var/lib/mysql
tmpdir          = /tmp
skip-external-locking
skip-innodb

#
# Instead of skip-networking the default is now to listen only on
# localhost which is more compatible and is not less secure.
bind-address            = 127.0.0.1
#
# * Fine Tuning
#
key_buffer              = 16K
max_allowed_packet      = 1M
thread_stack            = 64K
thread_cache_size       = 8
# This replaces the startup script and checks MyISAM tables if needed
# the first time they are touched
myisam-recover         = BACKUP
#max_connections        = 100
table_cache            = 4
#thread_concurrency     = 10
#
# * Query Cache Configuration
#
query_cache_limit       = 1M
query_cache_size        = 16M

# Linode conf
sort_buffer = 64K
net_buffer_length = 2K
#
# * Logging and Replication
#
# Both location gets rotated by the cronjob.
# Be aware that this log type is a performance killer.
# As of 5.1 you can enable the log at runtime!
#general_log_file        = /var/log/mysql/mysql.log
#general_log             = 1

log_error                = /var/log/mysql/error.log
# Here you can see queries with especially long duration
#log_slow_queries       = /var/log/mysql/mysql-slow.log
#long_query_time = 2
#log-queries-not-using-indexes
#
# The following can be used as easy to replay backup logs or for replication.
# note: if you are setting up a replication slave, see README.Debian about
#       other settings you may need to change.
#server-id              = 1
#log_bin                        = /var/log/mysql/mysql-bin.log
expire_logs_days        = 10
max_binlog_size         = 100M
#binlog_do_db           = include_database_name
#binlog_ignore_db       = include_database_name
#
# * InnoDB
#
# InnoDB is enabled by default with a 10MB datafile in /var/lib/mysql/.
# Read the manual for more InnoDB related options. There are many!
#
# * Security Features
#
# Read the manual, too, if you want chroot!
# chroot = /var/lib/mysql/
#
# For generating SSL certificates I recommend the OpenSSL GUI "tinyca".
#
# ssl-ca=/etc/mysql/cacert.pem
# ssl-cert=/etc/mysql/server-cert.pem
# ssl-key=/etc/mysql/server-key.pem

[mysqldump]
quick
quote-names
max_allowed_packet      = 16M

[mysql]
#no-auto-rehash # faster start of mysql but no tab completition

[isamchk]
key_buffer              = 16M

#
# * IMPORTANT: Additional settings that can override those from this file!
#   The files must end with '.cnf', otherwise they'll be ignored.
#
!includedir /etc/mysql/conf.d/

Just an update to say hybinet's suggestions to set MaxClients to 15 and disable KeepAlive worked for me, as I haven't encountered this issue for 10 days.

Thanks for the help kyhwana and hybinet.

Looking at your mysql config and assuming nothing is in /etc/mysql/conf.d this seems to be the default minimal mysql configuration. I wouldn't try to tune this down any more.

If you value your data I'd enable innodb and change the engine on the tables to use innodb. Though as its a predominately readonly wordpress you could be all right.

Perhaps using a lighter web server like nginx, lighttpd, boa would help your cause too.

ps. I'm joking about boa.

Reply

Please enter an answer
Tips:

You can mention users to notify them: @username

You can use Markdown to format your question. For more examples see the Markdown Cheatsheet.

> I’m a blockquote.

I’m a blockquote.

[I'm a link] (https://www.google.com)

I'm a link

**I am bold** I am bold

*I am italicized* I am italicized

Community Code of Conduct