Memcache und PHP7, auch gestolpert? Eine kleine Odyssee später gab es auch eine Lösung!
Die Aufgabe war, PHP-Applikationen auf einen neuen Server umziehen zu lassen, aber die Apps stürzten dauern ab. In den Server-Logs fand ich dann folgendes.
[Fri Jan 27 10:56:48.863150 2017] [core:notice] [pid 29007] AH00052: child pid 7363 exit signal Aborted (6)
*** buffer overflow detected ***: /usr/sbin/apache2 terminated
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x777e5)[0x7f059bafe7e5]
..
/lib/x86_64-linux-gnu/libc.so.6(+0x1184b7)[0x7f059bb9f4b7]
/usr/lib/php/20151012/memcache.so(mmc_pool_select+0x4a1)[0x7f058a25e161]
/usr/lib/php/20151012/memcache.so(mmc_pool_run+0x68)[0x7f058a25e988]
/usr/lib/php/20151012/memcache.so(zif_memcache_get+0x180)[0x7f058a259400]
/usr/lib/apache2/modules/libphp7.0.so(dtrace_execute_internal+0x2a)[0x7f05989bc53a]
/usr/lib/apache2/modules/libphp7.0.so(+0x2d6570)[0x7f0598a51570]
...
/usr/sbin/apache2(ap_run_handler+0x40)[0x562806ef35a0]
/usr/sbin/apache2(ap_invoke_handler+0xb6)[0x562806ef3b26]
/usr/sbin/apache2(ap_process_async_request+0x372)[0x562806f0afc2]
/usr/sbin/apache2(ap_process_request+0x10)[0x562806f0b170]
/usr/sbin/apache2(+0x6923e)[0x562806f0723e]
/usr/sbin/apache2(ap_run_process_connection+0x40)[0x562806efd510]
/usr/lib/apache2/modules/mod_mpm_prefork.so(+0x37e9)[0x7f0598fb67e9]
/usr/lib/apache2/modules/mod_mpm_prefork.so(+0x3a74)[0x7f0598fb6a74]
/usr/lib/apache2/modules/mod_mpm_prefork.so(+0x48c5)[0x7f0598fb78c5]
/usr/sbin/apache2(ap_run_mpm+0x4e)[0x562806ed7abe]
/usr/sbin/apache2(main+0x9b0)[0x562806ed1160]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0)[0x7f059baa7830]
/usr/sbin/apache2(_start+0x29)[0x562806ed1259]
======= Memory map: ========
562806e9e000-562806f35000 r-xp 00000000 09:02 59251002 /usr/sbin/apache2
...
Ich habe also gegoogelt, ohne echten Erfolg. Ich schaute mir das Log also nochmals an, begab mich in die Tiefen des Quellcodes der Anwendung, und konnte die Auslöser ein wenig einkreisen. Es schien das php-memcache Modul zu sein, denn die Crashs fanden jedesmal statt, wenn darauf zugegriffen wurde, und im Log wurde Memcache auch erwähnt. Wie auch immer, ich nutze Memcache sehr oft, und nicht alle Seiten mit Zugriff auf Memcache crashten. Nur die mit extrem vielen Zugriffen auf Memcache waren betroffen. Der Daemon selber lief klaglos, der war wohl nicht schuld. Also habe ich mir mal die Unterschiede zwischen php-memcache und php-memcached angeschaut. Durch umstellen auf php-memcached konnte ich die Fehler komplett beseitigen.
Es gibt eine Menge Posts im Web zum Thema Inkompatibilitäten zwischen php7 und php-memcache. Scheinbar haben die alle recht.
Mein Quellcode sah vorher ungefähr so aus:
$memcache = new Memcache;
$memcache->connect("localhost", 11211);
$somestuff = $memcache->get("someobjects");
...do something
$memcache->set("someobjects", $somestuff, 0, 60);
Ich war faul und habe nur zwei kleine Änderungen gemacht:
$memcache = new Memcached;
$memcache->addServers(array("127.0.0.1"));
$somestuff = $memcache->get("someobjects");
...do something
$memcache->set("someobjects", $somestuff, 0, 60);
Fertig. Nur die fetten Zeilen waren betroffen.
Übrigens, die Server-Installation war ein jungfräuliches Ubuntu 16.04 LTS mit Apache 2.4.18 and PHP 7.0.13. Falls das php-memcached Module nicht installiert ist, einfach apt install php-memcached && service apache2 restart und alles wird gut…