After upgrading Ubuntu server from 9.10 to 10.04LTS PHP’s APC cache wasn’t functioning. Apache wouldn’t start, it hung in the process list and printed this error to /var/log/apache2/error.log
[apc-error] apc_mmap: mmap failed: Invalid argument
The apache process would show up in the process like this:
apc@hostaname# ps aux | grep apache www-data 6958 104 0.0 139044 3624 ? R 12:47 0:19 /usr/sbin/apache2 -k start
This process would then have to be killed, APC commented out, and then the web server restarted just to continue on without APC until a solution was found.
The PHP manual states this regarding MMAP support in APC:
When APC is compiled with mmap support (Memory Mapping), it will use only one memory segment, unlike when APC is built with SHM (SysV Shared Memory) support that uses multiple memory segments. MMAP does not have a maximum limit like SHM does in /proc/sys/kernel/shmmax. In general MMAP support is recommeded because it will reclaim the memory faster when the webserver is restarted and all in all reduces memory allocation impact at startup.
APC was made to run by commenting out all lines from the PHP config file except for:
extension=apc.so apc.enabled = 1
This config can exist in a number of places. In 9.10 APC had been compiled by PECL so it was in our /etc/php5/apache2/php.ini file. However, in 10.04 APC is a package so we removed the PECL version, installed the version using apt-get install php-apc and moved the configuration to /etc/php5/conf.d/apc.ini for better consistency.
pear uninstall apc apt-get install php-apc
As I began to uncomment lines one by one, it turned out the culprit was in the apc.shm_size directive. The default size is 30M, but as soon as the directive was uncommented it crashed Apache. I was unable to specify any value at all, even the same or lesser value. I even tried with quotes and removing quotes. That’s when I started thinking syntax may be a problem because it works when using the default value (shm_size commented out) but fails with an “invalid argument” error. That makes me think APC is sending an invalid argument to MMAP. In which case I find this post that confirms my suspicion.
It turns out that the “M” for Megabytes cannot be specified in the shm_size directive for APC in Ubuntu server 10.04 because it is using APC version 3.1.3p1. However, on 9.10 APC wasn’t included as a package so it was installed with PEAR PECL which installed a more recent version of APC (3.1.9) which did allow specifying the “M” in the shm_size directive.
If you wish this to work in your config file, it should read like this in older versions of APC:
apc.shm_size = 100
This would specify 100M shared memory segments, and would be equivalent to this in newer versions:
apc.shm_size = 100M
And you can also put quotees around the “100M” if you like.
After these changes I had Apache up and running again, the APC cache helping PHP along, and some of the quickest loading pages I’ve seen in a while.