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.Упорни врски со базата на податоци
Почист и полокален преглед на PHP референцата, со задржана структура од PHP.net и подобра читливост за примери, секции и белешки.
Упорни врски со базата на податоци
Референца за `features.persistent-connections.php` со подобрена типографија и навигација.
Упорни врски со базата на податоци
Што се постојани врски?
Постојаните врски се врски што не се затвораат кога ќе заврши извршувањето на вашиот скрипт. Кога се бара постојана врска, PHP проверува дали веќе постои идентична постојана врска (што останала отворена од претходно) - и ако постои, ја користи. Ако не постои, ја создава врската. „Идентична“ врска е врска што била отворена до истиот хост, со истото корисничко име и истата лозинка (каде што е применливо).
Не постои метод за барање специфична врска, или гарантирање дали ќе добиете постоечка врска или сосема нова (ако сите постоечки врски се во употреба, или барањето се сервисира од различен работник, кој има посебен сет на врски).
Ова значи дека не можете да ги користите постојаните врски на PHP за, на пример:
- доделување на специфична сесија на базата на податоци на специфичен веб корисник
- креирање на голема трансакција низ повеќе барања
- иницирање на прашање во едно барање и собирање на резултатите во друго
Постојаните врски не ви даваат any функционалност што не била можна со непостојани врски.
Веб барања
Постојат два начина на кои вашиот веб сервер може да го користи PHP за генерирање веб страници:
Првиот метод е да се користи PHP како „обвивка“ на CGI. Кога се извршува на овој начин, инстанца на PHP толкувачот се создава и уништува за секое барање на страница (за PHP страница) до вашиот веб сервер. Бидејќи се уништува по секое барање, сите ресурси што ги стекнува (како што е врска до сервер на SQL база на податоци) се затвораат кога ќе се уништи. Во овој случај, нема да добиете ништо од обидот да користите постојани врски - тие едноставно не опстојуваат.
Вториот, и најпопуларен, метод е да се користи PHP-FPM, или PHP како модул во мултипроцесен веб сервер, кој моментално вклучува само Apache. Овие поставки обично имаат еден процес (родителот) кој ги координира низа процеси (неговите деца) кои всушност ја вршат работата на сервисирање на веб страници. Кога доаѓа барање од клиент, тоа се предава на едно од децата што веќе не сервисира друг клиент. Ова значи дека кога истиот клиент ќе направи второ барање до серверот, тоа може да биде сервисирано од различен процес на дете отколку првиот пат. При отворање на постојана врска, секое следно барање на страници што бара SQL услуги може повторно да ја искористи истата воспоставена врска до SQL серверот.
Забелешка:
Можете да проверите кој метод го користат вашите веб барања со проверка на вредноста на „Server API“ во излезот на phpinfo() или вредноста на
PHP_SAPI, извршено од веб барање.Ако Server API е „Apache 2 Handler“ или „FPM/FastCGI“, тогаш постојаните врски ќе се користат низ барањата сервисирани од истиот работник. За било која друга вредност, постојаните врски нема да опстојат по секое барање.
Процеси од командна линија
Бидејќи PHP од командна линија користи нов процес за секој скрипт, постојаните врски не се споделуваат помеѓу скриптови од командна линија, така што нема вредност во нивното користење во привремени скриптови како што се cron задачи или команди. Сепак, тие може да бидат корисни ако, на пример, пишувате долготраен сервер за апликации што сервисира многу барања или задачи и секое може да ја има потребата од своја врска до базата на податоци.
Зошто да ги користите?
Постојаните врски се добри ако трошокот за создавање врска до вашиот SQL сервер е висок. Дали овој трошок е навистина висок зависи од многу фактори. Како, каков вид база на податоци е, дали се наоѓа на истиот компјутер на кој се наоѓа вашиот веб сервер, колку е оптоварена машината на која се наоѓа SQL серверот и така натаму. Суштината е дека ако тој трошок за поврзување е висок, постојаните врски ви помагаат значително. Тие предизвикуваат процесот да се поврзе само еднаш за целиот свој животен век, наместо секој пат кога обработува страница што бара поврзување со SQL серверот. Ова значи дека секое дете што отвори постојана врска ќе има своја отворена постојана врска со серверот. На пример, ако имавте 20 различни процеси што извршуваа скрипта што правеше постојана врска до вашиот SQL сервер, ќе имавте 20 различни врски до SQL серверот, една од секое дете.
Постојаните врски се добри ако трошоците за создавање врска до вашиот SQL сервер се високи. Дали овие трошоци се навистина високи зависи од многу фактори. Како, каков вид база на податоци е, дали се наоѓа на истиот компјутер на кој се наоѓа вашиот веб-сервер, колку е оптоварена машината на која се наоѓа SQL серверот и така натаму. Суштината е дека ако тие трошоци за поврзување се високи, постојаните врски ви помагаат значително. Тие предизвикуваат процесот да се поврзе само еднаш за целиот свој животен век, наместо секој пат кога обработува страница што бара поврзување со SQL серверот. Ова значи дека секое дете што отвори постојана врска ќе има своја отворена постојана врска со серверот. На пример, ако имавте 20 различни процеси што извршуваа скрипта што правеше постојана врска со вашиот SQL сервер, ќе имавте 20 различни врски со SQL серверот, една од секое дете.
Потенцијални недостатоци: Ограничувања на врските
Имајте предвид, сепак, дека ова може да има некои недостатоци ако користите база на податоци со ограничувања на врските што се надминати од постојаните детски врски. Ако вашата база на податоци има ограничување од 16 истовремени врски, и во текот на зафатена серверска сесија, 17 детски нишки се обидат да се поврзат, една нема да може. Ако има грешки во вашите скрипти што не дозволуваат врските да се исклучат (како што се бесконечни циклуси), базата на податоци со само 16 врски може брзо да биде преоптоварена.
Постојаните врски обично ќе го зголемат бројот на врски отворени во секое дадено време бидејќи неактивните работници сè уште ќе ги држат врските за претходните барања што ги опслужиле. Ако голем број работници се стартуваат за да се справи со наплив на барања, врските што ги отвориле ќе останат додека работникот не се убие или серверот за бази на податоци не ја затвори врската.
Уверете се дека максималниот број на врски дозволен од серверот за бази на податоци е поголем од максималниот број на работници за веб-барања (плус каква било друга употреба како што се cron задачи или административни врски).
Проверете ја документацијата на вашата база на податоци за информации за ракување со напуштени или неактивни врски (тајмаути). Долгите тајмаути може значително да го зголемат бројот на постојани врски отворени во секое дадено време.
Потенцијални недостатоци: Одржување на состојбата на врската
- Некои екстензии за бази на податоци вршат автоматско чистење кога врската се користи повторно; други ја оставаат оваа задача на дискреција на развивачот на апликацијата. Во зависност од избраната екстензија за база на податоци и дизајнот на апликацијата, можеби ќе биде потребно рачно чистење пред да заврши скриптата. Промените што може да ги остават врските во неочекувана состојба вклучуваат:
- Избрана / стандардна база на податоци
- Заклучувања на табели
- Непотврдени трансакции
- Привремени табели
Поставки или функции специфични за врската, како што е профилирање
Заклучувањата на табели и трансакциите што не се исчистени или затворени може да предизвикаат други прашања да бидат блокирани неодредено и/или да предизвикаат последователна повторна употреба на врската да предизвика неочекувани промени.
Ако е избрана погрешна база на податоци, последователната повторна употреба на врската нема да може да извршува прашања како што се очекува (или да ги извршува на погрешна база на податоци ако шемите се доволно слични).
Ако привремените табели не се исчистат, последователните барања нема да можат да ја создадат истата табела. register_shutdown_function()Можете да имплементирате чистење користејќи деструктори на класи или
. Можеби ќе сакате да размислите и за наменски прокси за групирање на врски што го вклучуваат ова како дел од нивната функционалност.
Завршни зборови
Постојаните врски се добри ако трошокот за создавање врска до вашиот SQL сервер е висок. Дали овој трошок е навистина висок зависи од многу фактори. Како, каков вид база на податоци е, дали се наоѓа на истиот компјутер на кој се наоѓа вашиот веб сервер, колку е оптоварена машината на која се наоѓа SQL серверот и така натаму. Суштината е дека ако тој трошок за поврзување е висок, постојаните врски ви помагаат значително. Тие предизвикуваат процесот едноставно да се поврзе само еднаш за целиот свој животен век, наместо секој пат кога обработува страница што бара поврзување со SQL серверот. Ова значи дека секое дете што отвори постојана врска ќе има своја отворена постојана врска со серверот. На пример, ако имавте 20 различни процеси што извршуваа скрипта што правеше постојана врска до вашиот SQL сервер, ќе имавте 20 различни врски до SQL серверот, една од секое дете.
Разгледајте алтернативни решенија како што се истражување и поправање на причините за прекумерни трошоци при креирање на конекција (на пример, оневозможување на обратни DNS пребарувања на серверот за бази на податоци), или наменски прокси за групирање на конекции.
Белешки од корисници Управување со PDO конекции
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.