There's a third case for PHP: run on a fastCGI interface. In this case, PHP processes are NOT destroyed after each request, and so persistent connections do persist. Set PHP_FCGI_CHILDREN << mysql's max_connections and you'll be fine.Les connexions persistantes aux bases de donnĂ©es SQL sont des connexions qui ne se referment pas Ă la fin du script. Lorsqu'une connexion persistante est demandĂ©e, PHP vĂ©rifie s'il existe dĂ©jĂ une connexion persistante identique (qui aurait Ă©tĂ© ouverte prĂ©cĂ©demment) et, si tel est le cas, la rĂ©utilise ; sinon, il en crĂ©e une nouvelle. Une connexion identique est une connexion ouverte sur le mĂȘme hĂŽte, avec le mĂȘme nom d'utilisateur et le mĂȘme mot de passe (s'ils sont nĂ©cessaires).
Il n'y a pas de mĂ©thode pour demander une connexion spĂ©cifique, ou garantir que l'on obtient une connexion existante ou une toute nouvelle (si toutes les connexions sont utilisĂ©es, ou si la requĂȘte est servie par un autre processus, qui a un ensemble de connexions sĂ©parĂ©).
Cela signifie qu'il n'est pas possible d'utiliser les connexions persistantes PHP pour, par exemple :
Les connexions persistantes ne donnent aucune fonctionnalité qui n'était pas possible avec des connexions non persistantes.
Il existe deux façons pour le serveur web d'utiliser PHP pour générer des pages web :
La premiĂšre est d'utiliser PHP comme un CGI (Common Gateway Interface). Lorsque PHP fonctionne de cette maniĂšre, une instance de l'interprĂ©teur PHP est créée puis dĂ©truite pour chaque page demandĂ©e. Ătant donnĂ© que cet interprĂ©teur est dĂ©truit aprĂšs chaque requĂȘte, toutes les ressources acquises (comme une connexion Ă une base SQL), sont purement et simplement dĂ©truites. Dans ce cas, il n'y a rien Ă gagner Ă utiliser des connexions persistantes - elles ne persistent tout simplement pas.
La deuxiĂšme mĂ©thode, de loin la plus prisĂ©e, est d'exĂ©cuter PHP-FPM, ou PHP sous la forme d'un module sur un serveur multiprocessus, ce qui revient Ă dire : Apache. Ces configurations ont gĂ©nĂ©ralement un processus (le parent) qui coordonne un ensemble de processus fils, qui servent les fichiers. Lorsque les requĂȘtes parviennent depuis un client, elles sont transmises Ă un fils disponible. Cela signifie que si un client fait une deuxiĂšme requĂȘte, il peut ĂȘtre servi par un processus fils diffĂ©rent du premier. Une fois qu'une connexion persistante est ouverte, toute requĂȘte ultĂ©rieure servie par le mĂȘme processus fils peut rĂ©utiliser la connexion dĂ©jĂ Ă©tablie vers le serveur SQL.
Note:
Il est possible de vĂ©rifier quelle mĂ©thode les requĂȘtes web utilisent en vĂ©rifiant la valeur de "Server API" dans la sortie de phpinfo() ou la valeur de
PHP_SAPI, exĂ©cutĂ©e depuis une requĂȘte web.Si la valeur de Server API est "Apache 2 Handler" ou "FPM/FastCGI", alors les connexions persistantes seront utilisĂ©es entre les requĂȘtes servies par le mĂȘme worker. Pour toute autre valeur, les connexions persistantes ne persisteront pas aprĂšs chaque requĂȘte.
Comme PHP en ligne de commande utilise un nouveau processus pour chaque script, les connexions persistantes ne sont pas partagĂ©es entre les scripts en ligne de commande, donc il n'y a aucun intĂ©rĂȘt Ă les utiliser dans des scripts transitoires tels que les crons ou les commandes. Cependant, elles peuvent ĂȘtre utiles si, par exemple, l'on Ă©crit un serveur d'applications de longue durĂ©e qui sert de nombreuses requĂȘtes ou tĂąches et que chacune peut avoir besoin de sa propre connexion Ă la base de donnĂ©es.
Les connexions persistantes sont utiles si le coĂ»t de crĂ©ation d'une liaison vers le serveur SQL est Ă©levĂ©. Que ce coĂ»t soit rĂ©ellement Ă©levĂ© ou pas ceci dĂ©pend de nombreux facteurs : le type de base de donnĂ©es, cette base est-elle sur le mĂȘme serveur ou pas, quelle est la charge du serveur de base de donnĂ©es, etc. Si le temps de connexion est long, les connexions persistantes seront bien utiles, car une fois ouverte par un processus fils, la connexion est rĂ©utilisable sans avoir Ă se reconnecter. Avec 20 processus fils, il suffit d'avoir 20 connexions persistantes ouvertes, une par fils.
Il est Ă noter que les connexions persistantes ont quelques inconvĂ©nients lors de l'hĂ©bergement d'une base de donnĂ©es dont le nombre maximal de connexion risque d'ĂȘtre atteint par les connexions persistantes. Si la base de donnĂ©es a une limite de 16 connexions simultanĂ©es, et que lors d'une session serveur chargĂ©e, 17 processus fils tentent de se connecter, l'un d'entre eux ne pourra pas. S'il y a des bogues dans les scripts qui empĂȘchent les connexions de se fermer (comme des boucles infinies), la base de donnĂ©es avec seulement 16 connexions peut ĂȘtre rapidement submergĂ©e.
Les connexions persistantes augmenteront gĂ©nĂ©ralement le nombre de connexions ouvertes Ă un moment donnĂ© parce que les travailleurs inactifs conserveront les connexions pour les requĂȘtes prĂ©cĂ©dentes qu'ils ont servies. Si un grand nombre de travailleurs est lancĂ© pour gĂ©rer un afflux de requĂȘtes, les connexions qu'ils ont ouvertes resteront jusqu'Ă ce que le travailleur soit tuĂ© ou que le serveur de base de donnĂ©es ferme la connexion.
Il faut s'assurer que le nombre maximal de connexions autorisĂ©es par le serveur de base de donnĂ©es est supĂ©rieur au nombre maximal de travailleurs de requĂȘtes web (plus toute autre utilisation telle que les crons ou les connexions administratives).
Vérifier la documentation de la base de données pour des informations sur la gestion des connexions abandonnées ou inactives (timeouts). Des timeouts longs peuvent augmenter considérablement le nombre de connexions persistantes ouvertes à un moment donné.
Certaines extensions de base de donnĂ©es effectuent un nettoyage automatique lorsque la connexion est rĂ©utilisĂ©e ; d'autres laissent cette tĂąche Ă la discrĂ©tion du dĂ©veloppeur d'application. En fonction de l'extension de base de donnĂ©es choisie et de la conception de l'application, un nettoyage manuel peut ĂȘtre nĂ©cessaire avant la fin du script. Les modifications qui peuvent laisser les connexions dans un Ă©tat inattendu incluent :
Les verrous de table et les transactions qui ne sont pas nettoyĂ©s ou fermĂ©s peuvent entraĂźner le blocage indĂ©fini d'autres requĂȘtes et/ou provoquer des modifications inattendues lors de la rĂ©utilisation ultĂ©rieure de la connexion.
Avoir la mauvaise base de donnĂ©es sĂ©lectionnĂ©e entraĂźnera la rĂ©utilisation de la connexion incapable d'exĂ©cuter les requĂȘtes suivantes comme prĂ©vu (ou de les exĂ©cuter sur la mauvaise base de donnĂ©es si les schĂ©mas sont suffisamment similaires).
Si les tables temporaires ne sont pas nettoyĂ©es, les requĂȘtes suivantes ne pourront pas recrĂ©er la mĂȘme table.
Il est possible d'implémenter le nettoyage en utilisant des destructeurs de classe ou register_shutdown_function(). Il est également possible d'envisager des proxies de mise en pool de connexions dédiés qui incluent cela dans leur fonctionnalité.
Ătant donnĂ© leur comportement et les inconvĂ©nients potentiels dĂ©crits ci-dessus, il est recommandĂ© de ne pas utiliser les connexions persistantes sans une rĂ©flexion approfondie. Elles ne devraient pas ĂȘtre utilisĂ©es sans mettre en Ćuvre des modifications supplĂ©mentaires dans l'application et une configuration soigneuse du serveur de base de donnĂ©es et du serveur web et/ou PHP-FPM.
Considérez des solutions alternatives telles que l'investigation et la correction des causes des surcoûts de création de connexion (par exemple, la désactivation des recherches DNS inverses sur le serveur de base de données), ou des proxies de mise en pool de connexions dédiés.
Pour les API web à fort volume, envisagez d'utiliser des runtimes alternatifs ou des serveurs d'applications de longue durée.
There's a third case for PHP: run on a fastCGI interface. In this case, PHP processes are NOT destroyed after each request, and so persistent connections do persist. Set PHP_FCGI_CHILDREN << mysql's max_connections and you'll be fine.In IBM_DB2 extension v1.9.0 or later performs a transaction rollback on persistent connections at the end of a request, thus ending the transaction. This prevents the transaction block from carrying over to the next request which uses that connection if script execution ends before the transaction block does.One additional not regarding odbc_pconnect and possibly other variations of pconnect:
If the connection encounters an error (bad SQL, incorrect request, etc), that error will return with be present in odbc_errormsg for every subsequent action on that connection, even if subsequent actions don't cause another error.
For example:
A script connects with odbc_pconnect.
The connection is created on it's first use.
The script calls a query "Select * FROM Table1".
Table1 doesn't exist and odbc_errormsg contains that error.
Later(days, perhaps), a different script is called using the same parameters to odbc_pconnect.
The connection already exists, to it is reused.
The script calls a query "Select * FROM Table0".
The query runs fine, but odbc_errormsg still returns the error about Table1 not existing.
I'm not seeing a way to clear that error using odbc_ functions, so keep your eyes open for this gotcha or use odbc_connect instead.For the oci8 extension it is not true that " [...] when using transactions, a transaction block will also carry over to the next script which uses that connection if script execution ends before the transaction block does.". The oci8 extension does a rollback at the end scripts using persistent connections, thus ending the transaction. The rollback also releases locks. However any ALTER SESSION command (e.g. changing the date format) on a persistent connection will be retained over to the next script.It seems that using pg_pconnect() will not persist the temporary views/tables. So if you are trying to create temporary views/tables with the query results and then access them with the next script of the same session, you are out of luck. Those temporary view/tables are gone after each PHP script ended. One way to get around this problem is to create real view/table with session ID as part of the name and record the name&creation time in a common table. Have a garbage collection script to drop the view/table who's session is expired.If anyone ever wonders why the number of idle db process (open connections) seems to grow even though you are using persistent connections, here's why:
"You are probably using a multi-process web server such as Apache. Since
database connections cannot be shared among different processes a new
one is created if the request happen to come to a different web server
child process."To those using MySQL and finding a lot of leftover sleeping processes, take a look at MySQL's wait_timeout directive. By default it is set to 8 hours, but almost any decent production server will have been lowered to the 60 second range. Even on my testing server, I was having problems with too many connections from leftover persistent connections.