downloads | documentation | faq | getting help | mailing lists | licenses | wiki | reporting bugs | php.net sites | links | conferences | my php.net

search for in the

Safe Mode> <Connection handling
Last updated: Wed, 22 Jul 2009

view this page in

Persistente Database connecties

Persistente connecties zijn connecties naar SQL servers die niet gesloten worden zogauw je script beƫindigd word. Zogauw een persistente connectie wordt aangevraagd kijkt PHP of er al een identieke connectie is (dat open gebleven is nadat hij eerder geopend is) en als deze bestaat word die connectie gebruikt. Bestaat er nog geen vrij identieke connectie dan wordt er een nieuwe connectie gelegd. Een 'identieke' connectie is een connectie die geopend was naar de zelfde host, met de zelfde username en password (waar van toepassing).

Diegene die niet erg vertrouwd zijn met de manier waarop webservers werken en de manier waarop ze de aanvragen verdelen kunnen persistente connecties aanzien voor iets dat ze niet zijn. Persistente geven je niet de mogelijkheid om "user session" op deze zelfde SQL connectie te hebben, ze geven je niet de mogelijkheid om een Transaction efficienter op te bouwen en ze doen vanalles en nog wat niet. Om heel duidelijk te zijn, ze geven geen extra functionaliteit tegenover wat mogelijk is met hun niet-persistente broertjes.

Waarom ?

Dit heeft te maken met de manier waarop web servers werken. Er zijn 3 manieren waarop je web server PHP kunt gebruiken om pagina's te genereren.

De eerste manier is om PHP te gebruiken als een CGI "wrapper". Als je PHP op deze manier gebruikt word een instantie van de PHP interpreter aangemaakt en vernietigd voor iedere PHP pagina die wordt opgevraagd. Omdat het na iedere aanvraag vernietigd word, worden middelen die PHP gebruikt heeft (zoals een connectie naar een database server) vrijgegeven (gesloten). In dit geval heeft het geen zin om persistente connecties te gebruiken -- ze blijven simpelweg niet bestaan.

De tweede, en meest populaire, manier is PHP te gebruiken als een module in een multiprocess web server, op dit moment alleen Apache. Een multiprocess webserver heeft standaard 1 process (de parent) welke een partij andere process (child processen) coordineert. Deze child processen nemen zorg voor het verwerken van aanvragen. Als een aanvraag binnenkomt word deze doorgegeven aan een child process dat op dat moment niets te doen heeft. Dat betekent dat als dezelfde gebruiker een nieuwe aanvraag stuurt deze door een ander child process afgehandeld kan worden. Wat een persistente connectie voor je doet in deze context is dat een child process slechts een connectie maakt naar een SQL server bij het eerste script dat zo'n connectie vereist. Als een andere pagina daarna ook een dergelijke connectie nodig heeft dan kan de connectie die al eerder gelegd was opnieuw gebruikt worden.

De laatste methode is om PHP te gebruiken als een plug-in in een multithreaded web server. Op dit moment is dit slechts theoretisch -- PHP werkt nog niet als een plugin voor een multithreaded web server. Er wordt vooruitgang geboekt op de ontwikkeling voor support voor ISAPI, WSAPI en NSAPI (onder Windows) welke allemaal mogelijk maken dat PHP gebruikt wordt als een plug-in op multithreaded servers zoals Netscape FastTrack, Microsofts Internet Information Server (IIS) en O'Reilly's WebSite Pro. Zogauw dit compleet is zal het gedrag van PHP in deze context overeen komen met het gedrag van PHP in een multiprocess model, wat hierboven beschreven is.

Als persistente connecties geen extra functionaliteit geven, waar zijn ze dan goed voor?

Het antwoord is erg simpel -- betere performance. Persistente connecties zijn goed als de overhead om een connectie naar je SQL server te leggen groot is. Of die overhead daadwerkelijk groot is hangt af van veel factoren. Zoals, wat voor database is het, draait de server op de zelfde machine als de webserver. Hoe druk de server met de database het heeft. Uiteindelijk als deze overhead inderdaad groot is, zijn persistente connecties een goede hulp. Ze zorgen ervoor dat het child process zolang het process leeft slechts 1x een connectie naar de SQL server legt, in plaats van iedere keer dat het child process een connectie legt zogauw het een script verwerkt dat zo'n connectie vereist. Dit betekent dat ieder child process z'n eigen connectie heeft naar de SQL server. Bijvoorbeeld, als je 20 verschillende child processen hebt dat een script verwerkt dat een persistente connectie legt, dan zou je 20 verschillende connecties hebben naar de SQL server. Een van elk childprocess.

Onthoudt wel dat dit z'n nadelen kan hebben als je een database server gebruikt met een limiet op het aantal connecties. Als je database een limiet van 16 gelijke connecties heeft, en in laten we zeggen dat we een drukke server hebben, 17 child processes proberen een connectie te leggen, zal er een hierin falen. Als je scripts bugs hebben welke niet de connectie sluiten kan een database met slechts 32 connecties snel "verdrinken". Zoek door de database documentatie naar informatie over het sluiten van verlaten of niet-gebruikte connecties.

Een belangrijke samenvatting. Persistente connectie zijn ontwikkeld om in principe het zelfde te werken als standaard connecties. Dat betekent dat je altijd de mogelijk hebt om persistente connecties te vervangen met niet-persistente connecties, zonder dat het gedrag van je script wijzigt. Het kan (en zal waarschijnlijk) de effectiviteit van je script verbeteren, maar het zal nooit het gedrag veranderen.



Safe Mode> <Connection handling
Last updated: Wed, 22 Jul 2009
 
add a note add a note User Contributed Notes
Persistente Database connecties
ynzhang from lakeheadu canada
09-Mar-2009 07:49
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.
christopher dot jones at oracle dot com
26-Jun-2007 07:46
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.
andy at paradigm-reborn dot com
20-Feb-2007 05:13
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.
whatspaz at g NO dot SPAM mail dot c o m
26-Nov-2006 12:02
in response to web at nick, have you tried FLUSH PRIVILEGES. this should reload those privileges.
RQuadling at GMail dot com
06-Mar-2006 12:43
If you have multiple databases on the same server AND you are using persistent connections, you MUST prefix all the table names with the specific database name.

Changing the database using the xxx_select_db functions alters the database for the connection for all users who are sharing that connection (assuming PHP is running shared and not CGI/CLI).

If you have 2 databases (live and archive) and your script is talking to both, you cannot use 2 persistent connections and change the database for each one.

Internally, persistent connections are used even if you do not specify that you want to use persistent connections. This is why new_link was added to mysql_connect/mssql_connect (PHPV4.2.0+).
fabio
12-Jan-2006 12:54
You can in fact provide a port for the connection, take a look at http://de2.php.net/manual/en/function.mysql-pconnect.php#AEN101879

Just use "hostname:port" for the server address.
aaryal at foresightint dot com
16-Jan-2004 12:21
this one bit quite a bit of chunk out of my you-know-what. seems like if you're running multiple database servers on the same host (for eg. MySQL on a number of ports) you can't use pconnect since the port number isn't part of the key for database connections. especially if you have the same username and password to connect to all the database servers running on different ports. but then it might be php-MySQL specific. you might get a connection for an entirely different port than the one you asked for.
web at nickSPAMrabinowitz dot com
02-Dec-2003 11:41
This may only pertain to Apache/MySQL:

After several hours of wrestling with MySQL "Access denied" messages, I determined that persistent database connections don't necessarily reflect subsequent privilege changes.

I loaded a PHP script attempting a LOAD DATA statement, and got an "Access denied" error. I granted FILE privileges to the MySQL user, and was able to run LOAD DATA statements from the terminal, but still got "Access denied" from my PHP pages.  When I switched from mysql_pconnect() to mysql_connect(), the problem went away; eventually I restarted apache to kill the persistent connection and switched back to mysql_pconnect(), and now everything works fine.
jean_christian at myrealbox dot com
15-Aug-2002 12:13
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."
sebastian at flothow dot de
18-Apr-2000 04:28
Yes, with nonpersistent connections database connections last only while a database-related request is processed, thus reducing the load on the database server.
However, latency will be somewhat higher since a database connection must be opened before a request can be handeled.

Safe Mode> <Connection handling
Last updated: Wed, 22 Jul 2009
 
 
show source | credits | stats | sitemap | contact | advertising | mirror sites