Re: PHP Connections - Mailing list pgsql-php
From | scott.marlowe |
---|---|
Subject | Re: PHP Connections |
Date | |
Msg-id | Pine.LNX.4.33.0308051251310.13758-100000@css120.ihs.com Whole thread Raw |
In response to | Re: PHP Connections (Lynna Landstreet <lynna@gallery44.org>) |
Responses |
Re: PHP Connections
|
List | pgsql-php |
On Tue, 5 Aug 2003, Lynna Landstreet wrote: > On my site I have one global include file with the db connection in it, and > just call it in the head section of each page. The code just references the > $db handle where it needs it, rather than connecting again. Even with that, > I keep wondering if it might be better to use a persistent connection that > would last from page to page rather than each page connecting over again. > But the problem there is that I don't necessarily know which page visitors > are going to come in on, so I need to make sure they always get a > connection, and connecting once per page seems like a reasonable compromise. > > But hey, come to think of it, maybe I could turn the pg_connect into a > pg_pconnect and just have it check to see if $db already exists before > connecting - that way there'd be only one connection per site visit! Cool, > your question gave me a new idea... :-) Be VERY wary of persistant connections. They are fraught with danger and can cause your server to present the "too many connections" error message after being up for a while. The reason is the dirt simple persistant connection technology in PHP/Apache. Each persistant connection stays open until the child process dies or the connection errors or times out. Since Postgresql, by default, doesn't time out idle connections, and apache, by default doesn't kill it's children every so often, only if there's too many, and postgresql, by experience never seems to crash (backend or especially postmaster for me) this means that each persistant connection functioanlly lasts forever. So, if apache is configured for 150 children (the default) and postgresql is configured for 32 children (again, the default) then after the server's been up and under load, it is quite possible for all the connections to postgresql to get exhausted and for the 33rd connection to get a too many connection errors. Easy fix, just crank up max backends, right? Well, sorta. The rule of TANSTAAFL (there ain't no such thing as a free lunch.) If Postgresql has 150+ connections sitting open and idle, it's likely not gonna run as fast as if it had only 3 or 4 children open. So, it's generally better to turn down the number of apache children to control this problem. But that brings up apache's keep alive mechanism, a standard part of the http/1.1 protocol, which basically means that whichever request came from ip w.x.y.z last time will likely get serviced by the same child, which will stay assigned to that client as long as he clicks every X seconds (usually 15 or so). If apache has 30 keep alive connects going, and a max children setting of 150, when a new request from a new client comes along, it will NOT reuse one of the pre-existing children unless its keep alive has timed out. So, if you've got 100 distinct users clicking every 7 to 15 seconds, you may find apache spawning LOTS of children if you haven't turned it down. Now, if the max children are set to 30, and apache has 30 keep alive connections going, it will reuse one of the pre-existing child processes. That means that whatever page cache was being kept for that client likely is lost (but still probably in kernel buffers, so no huge loss.) Now, things get real ugly when you start connecting to different databases. Say I have 64 databases, and my scripts have equal chances of using any one of them depending on which customer site whatever they are hitting. Now we look at pgsql.max_persistent. this setting is PER CHILD. Not for the whole apache/php server. If you have this set to unlimited, and your child processes are hopping all over due to keep alive timeout/out of children mentioned above, then you could theoretically have 64 persistant connections open, per child. That's 1920 connections. ugh. It's important to understand that php persistant connects are NOT connection pooling in the classic java sense, and if not configured properly, can bring an apache/php/postgresql server to it's knees under fairly light load. Put another way, whereas non-persistant connections have a slow degrade under increasing of load, persistant connections, if improperly configured, fail catastrophically under increasing load. Configured properly: pgsql.max_persistent set to 1 to 4 apache max_children set to 30 to 100 max_connections set to the two numbers above multiplied by each other, plus an extra dozen or so for fudge factor they can work quite well and help a busy web site. But they aren't always a gain, since having too many connections open at once can cause a performance issue too.