NB This is not a dupe of PHP session_start() causing HTTP requests to hang (and other similarly named questions on SO), as my hang is occasional, not permanent.
Using Ubuntu 12.04,
Magento
, PHP-FPM (5.4)
and default PHP session handler (with files on ext4).
Incidentally (once per month)
all PHP processes hang on session_start()
(according to fpm-slow.log):
[24-Sep-2014 11:03:04] [pool www] pid 24259
script_filename = /data/web/public/index.php
[0x00007f00b4ec6480] session_start() /data/web/public/includes/src/__default.php:7687
[0x00007f00b4ec6130] start() /data/web/public/includes/src/__default.php:7730
[0x00007f00b4ec5fb8] init() /data/web/public/includes/src/__default.php:8086
[0x00007f00b4ec5e30] init() /data/web/public/includes/src/__default.php:33902
[0x00007f00b4ec5bd0] __construct() /data/web/public/includes/src/__default.php:23841
[0x00007f00b4ec5ae8] getModelInstance() /data/web/public/app/Mage.php:463
[0x00007f00b4ec59c8] getModel() /data/web/public/app/Mage.php:477
[0x00007f00b4ec49a0] getSingleton() /data/web/public/includes/src/__default.php:14044
[0x00007f00b4ec4848] preDispatch() /data/web/public/includes/src/Mage_Adminhtml_Controller_Action.php:160
[0x00007f00b4ec3b00] preDispatch() /data/web/public/includes/src/__default.php:13958
[0x00007f00b4ec26e0] dispatch() /data/web/public/includes/src/__default.php:18331
[0x00007f00b4ec20c0] match() /data/web/public/includes/src/__default.php:17865
[0x00007f00b4ec1a98] dispatch() /data/web/public/includes/src/__default.php:20465
[0x00007f00b4ec1908] run() /data/web/public/app/Mage.php:684
[0x00007f00b4ec17f8] run() /data/web/public/index.php:87
Lsof says:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
php5-fpm 24259 app 10uW REG 202,1 82492 1220594 /data/web/public/var/session/sess_gr2clur9icgd7s2j9linag7ue6
php5-fpm 24262 app 10u REG 202,1 82492 1220594 /data/web/public/var/session/sess_gr2clur9icgd7s2j9linag7ue6
php5-fpm 24351 app 10u REG 202,1 82492 1220594 /data/web/public/var/session/sess_gr2clur9icgd7s2j9linag7ue6
php5-fpm 24357 app 10u REG 202,1 82492 1220594 /data/web/public/var/session/sess_gr2clur9icgd7s2j9linag7ue6
php5-fpm 24358 app 10u REG 202,1 82492 1220594 /data/web/public/var/session/sess_gr2clur9icgd7s2j9linag7ue6
php5-fpm 25563 app 10u REG 202,1 82492 1220594 /data/web/public/var/session/sess_gr2clur9icgd7s2j9linag7ue6
php5-fpm 25564 app 10u REG 202,1 82492 1220594 /data/web/public/var/session/sess_gr2clur9icgd7s2j9linag7ue6
According to strace, all these processes are waiting for flock (LOCK_EX)
, even the one who has the W flag in the lsof output above.
The CPU usage during this incident is near 0.
So why does the first session_start
hang, even though it seems to have acquired a write lock on the session file? How could I debug this further?
Here is a discussion called "race condition with ajax and php sessions". In fact, the requests that trigger the problem above, are consistenly AJAX calls. However, this article states that:
If you've used PHP's built-in, default session handling (that uses files), you'll never come across the problem.
So currently I'm at a loss where to look next.
session_start() creates a session or resumes the current one based on a session identifier passed via a GET or POST request, or passed via a cookie. When session_start() is called or when a session auto starts, PHP will call the open and read session save handlers.
It must be on every page you intend to use. The variables contained in the session—such as username and favorite color—are set with $_SESSION, a global variable. In this example, the session_start function is positioned after a non-printing comment but before any HTML.
Note: The session_start() function must be the very first thing in your document. Before any HTML tags. As for your question you can start session wherever you want, but beware that session must be started before any output. So it is considered a reasonable approach to start session at the top of a page.
session_destroy() function: It destroys the whole session rather destroying the variables. When session_start() is called, PHP sets the session cookie in browser. We need to delete the cookies also to completely destroy the session. Example: This example is used to destroying the session.
I find it best to store sessions on a local disk and not the database.
Create a directory named 'sessions' at the root directory, and then have all of your sessions write there by putting the following code at the top of scripts right before you call "session_start()"
$session_path = $_SERVER['DOCUMENT_ROOT']; //this session path assumes you are not using a subdomain
ini_set('session.save_path', $session_path.'/sessions/');
Loading from file is faster than loading from a database. And php manages it all the same, so I opt for speed.
Something unknown is blocking the first script, and it is blocking the rest.
PHP keeps the session file open for writing until after the script terminates. That means if a script gets stuck or caught up doing something slow, all other requests dependent on the session will be blocked until it finishes.
Two best practices - don't start the session until you need it, and explicitly end the session with session_write_close() when you're done changing it, especially before doing something slow or potentially buggy.
Then you'll only have 1 stuck process, instead of a locked out user.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With