Willem
Willem

Reputation: 3253

Why does PHP occasionally hang on session_start()

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.

Upvotes: 7

Views: 5068

Answers (7)

rokdd
rokdd

Reputation: 652

I just read across different platforms because facing the same problem. I read on several pages that the process to clean up the session files is started when you call "session_start()". You can control how often and in which way the garbage cleaner (gc) cleans in the ini directives of php

Upvotes: 0

Andres SK
Andres SK

Reputation: 10974

A good practice is to install memecached for php and then just set these values:

session.save_handler = memcache
session.save_path = “tcp://127.0.0.1:11211″

Upvotes: 0

Dirigible
Dirigible

Reputation: 1948

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.

Upvotes: 2

skidadon
skidadon

Reputation: 547

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.

Upvotes: 1

Fredylg
Fredylg

Reputation: 11

I would advice to check the sessions table on magento... since it stores sessions on a mysql table you may have an issue with your db...

Upvotes: 0

Hardik Vyas
Hardik Vyas

Reputation: 500

When you have an import script that takes long to execute, the browser seem to lock up and you cannot access the website anymore. this is because a request is reading and locking the session file to prevent corruption.

you can either - use a different session handler with session_set_save_handler() - use session_write_close() in the import script as soon you don't need session anymore (best moment is just before the long during part takes place), you can session_start when ever you want and as many times you like if your import script requires session variables changed.

http://php.net/manual/en/function.session-start.php

Upvotes: 0

unixmiah
unixmiah

Reputation: 3145

On your Ajax calls I'm guessing in that file you have session_start and somewhere in your /tmp directory in your ubuntu php is saving its sessions. To solve your issue you need to run load testing against those scripts, it can also be the db that could be a factor in which you can't see with naked eye.

Try something like this: http://smartbear.com/products/qa-tools/load-testing-tool/ajax-load-testing/ as a trial maybe you can get to the bottom of the problem. You also need to dig deeper into the sessions for that matter including those individual files that uses ajax calls.

You should setup some type of performance testing against those calls to the backend that you can run when the problem occurs. The layers are PHP, PHP-FPM, Magento, Im guessing MySQL, Ubuntu, network connection and Apache?

Upvotes: -1

Related Questions