0

I've been going through PHP's source code and the mysql_pconnect function and noticed it's using some kind of HashTable persistent_list which is defined in zend_globals.

The question is, how are this globals and variables are preserved across requests when PHP is set as mod apache/fcgi. If it's a new PHP process spawned for every request those variables should not be preserved.

Alex
  • 11,479
  • 6
  • 28
  • 50
  • This only works when a process serves more than 1 request, either by reusing it, or by it having multiple threads that serve multiple requests. mod_php for apache has been the gold standard sapi for php for a long time, and apache is often configured in a way that a process serves more than 1 php request. – goat Dec 24 '12 at 16:16

2 Answers2

1

PHP-FPM reuses contexts, allowing persistent connections to work in FCGI. Something to consdier though is PHP-FPM initially creates more than one process, so you still end up with multiple connections, one for each process or context.

Something to consider is, "persistent connections do more harm than good" is a sentence said a LOT in #php.pecl. The overhead of connecting is light, and PHP lends itself to this kind of processing. In languages that are designed to run constantly the overhead of connecting might be greater ( usually because, simply connecting impacts many more objects than the one the prorgram is directly manipulating ), so a persistent or pooled connection makes sense. PHP is designed to do everything as quickly as it can and to hell with how much resources it uses doing it - everything has to run in around 250ms - connecting to mysql doesn't fire a bunch of hooks throughout the framework as it might in other languages, so the overhead is very small. Additionally, a persistent connection for each process does not amount to a pool of managed connections like it might in other languages, if the receiving machine does not have it's mysql instance configured ( with ridiculous settings ) then the connections will go stale and upon *_pconnect PHP has to first invalidate the old connection before creating a new one, which is less efficient and slower than just creating a new connection to begin with.

Joe Watkins
  • 17,032
  • 5
  • 41
  • 62
-1

The question is, how are this globals and variables are preserved across requests when PHP is set as mod apache/fcgi.

As apache module, they are shared because apache httpd itself is still running. That running process had spawned PHP and will spawn other PHPs in the future. As the child threads can relate to their parent, it can and is stored in the parents memory space.

As FCGI, this could be technically possible as long as the binary is already running, however this has not been implemented with the FPM. I would also say, it makes no real sense for FCGI, too, because it's per script and also timeouts are involved, so the life-span is much shorter as with the whole webserver.

hakre
  • 193,403
  • 52
  • 435
  • 836
  • The same documentation states that `the connection to the SQL server will not be closed when the execution of the script ends`, meaning it somehow preserves the connection between requests ( and thus instances of php processes) – Alex Dec 24 '12 at 16:12
  • +1 @Alex: Connections are not preserved across processes at all. If you are using Apache's MPM worker (which is the most common and performant setup), they are preserved across *threads*. When the script ends, the *thread* ends, but the process remains. If you are using MPM prefork instead, each script will have its own process (rather than thread) and persistent connections will not persist across scripts. hakre's answer is not detailed much, but is nonetheless correct. – netcoder Dec 25 '12 at 16:57
  • Up until apache 2 there was no `apache worker mpm` (multithreaded) only `prefork` (process per request) and `mysql_pconnect` was presented during that days already. Who had been holding the connection back then ? – Alex Dec 26 '12 at 17:25