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 s'assure qu'il n'y a pas une autre connexion identique (qui serait ouverte précédemment, avec le même nom d'hôte, d'utilisateur et le même mot de passe), et si une telle connexion existe, elle est utilisée ; sinon, elle est créée. Une connexion identique est une connexion qui a ouvert le même hôte, avec le même nom 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 vous obtenez 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 que vous ne pouvez pas utiliser les connexions persistantes PHP pour, par exemple :
Les connexions persistantes ne vous donnent aucune fonctionnalité qui n'était pas possible avec des connexions non persistantes.
Il existe deux façons pour votre serveur web d'utiliser PHP pour générer des pages web :
La première est d'utiliser PHP comme un CGI (Common Interface Gateway). 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 vous ne gagnez rien à 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 client différent du premier. Les connexions persistantes vous permettent alors de ne vous connecter à une base SQL que la première fois. Lors des connexions ultérieures, les processus fils pourront réutiliser la connexion ouverte précédemment.
Note:
Vous pouvez vérifier quelle méthode vos 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 "CGI" ou "CLI", alors les connexions persistantes ne seront pas utilisées entre les requêtes. Pour toute autre valeur, les connexions persistantes persisteront 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, vous écrivez 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 votre 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. Si vous avez 20 processus fils, il suffit d'avoir 20 connexions persistantes ouvertes, une par fils.
Notez que les connexions persistantes ont quelques inconvénients si vous hébergez une base de données dont le nombre maximal de connexion risque d'être atteint par les connexions persistantes. Si votre base de données accepte jusqu'à 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.
Assurez-vous 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érifiez votre documentation de 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.
Vous pouvez implémenter le nettoyage en utilisant des destructeurs de classe ou register_shutdown_function(). Vous pouvez également 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, vous ne devez pas utiliser les connexions persistantes sans une réflexion approfondie. Elles ne doivent pas être utilisées sans mettre en œuvre des modifications supplémentaires dans votre application et une configuration soigneuse de votre serveur de base de données et de votre 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.