-
Notifications
You must be signed in to change notification settings - Fork 888
Expand file tree
/
Copy pathpersistent-connections.xml
More file actions
230 lines (221 loc) · 9.86 KB
/
Copy pathpersistent-connections.xml
File metadata and controls
230 lines (221 loc) · 9.86 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<chapter xml:id="features.persistent-connections" xmlns="http://docbook.org/ns/docbook">
<title>Persistent Database Connections</title>
<simplesect>
<title>What are Persistent Connections?</title>
<simpara>
Persistent connections are links that do not close when the
execution of the script ends. When a persistent connection is
requested, PHP checks whether an identical persistent
connection (that remained open from earlier) already exists; if one does,
it is reused, and if not, a new link is created. An 'identical'
connection is one opened to the same host with
the same username and password (where applicable).
</simpara>
<simpara>
There is no way to request a specific connection, or to guarantee
whether the returned connection will be an existing one or a brand new
one (if all existing connections are in use, or the request is being
served by a different worker, which has a separate pool of connections).
</simpara>
<simpara>
PHP's persistent connections therefore cannot be used to, for example:
</simpara>
<simplelist>
<member>assign a specific database session to a specific web user</member>
<member>create a large transaction across multiple requests</member>
<member>initiate a query on one request and collect the results on another</member>
</simplelist>
<simpara>
Persistent connections do not provide <emphasis>any</emphasis>
functionality that was not possible with non-persistent connections.
</simpara>
</simplesect>
<simplesect xml:id="persistent-connections.web">
<title>Web Requests</title>
<simpara>
There are two ways in which a web server can utilize PHP to generate
web pages:
</simpara>
<simpara>
The first method is to use PHP as a CGI "wrapper". When run this
way, an instance of the PHP interpreter is created and destroyed
for every page request (for a PHP page) to the web server.
Because it is destroyed after every request, any resources that it
acquires (such as a link to an SQL database server) are closed when
it is destroyed. In this case, there is nothing to be gained from
using persistent connections - they simply do not persist.
</simpara>
<simpara>
The second, and most popular, method is to run PHP-FPM, or PHP as a module
in a multiprocess web server (currently only Apache).
These setups typically have one process (the parent) which
coordinates a set of processes (its children) that actually do the
work of serving up web pages. When a request comes in from a
client, it is handed off to one of the children that is not already
serving another client. This means that when the same client makes
a second request to the server, it may be served by a different
child process than the first time. Once a persistent connection has been
opened, any subsequent page served by the same child process can reuse the
already established connection to the SQL server.
</simpara>
<note>
<para>
The method in use can be checked by looking at the value of
"Server API" in the output of <function>phpinfo</function> or the value of
<constant>PHP_SAPI</constant>, run from a web request.
</para>
<para>
If the Server API is "Apache 2 Handler" or "FPM/FastCGI", then persistent
connections will be used across requests served by the same worker. For any
other value, persistent connections will not persist after each request.
</para>
</note>
</simplesect>
<simplesect xml:id="persistent-connections.cli">
<title>Command-line Processes</title>
<simpara>
As command-line PHP uses a new process for each script, persistent
connections are not shared between command-line scripts, so there is no
value in using them in transient scripts such as crons or commands.
However, they may be useful, for example, in a long-running application
server that serves many requests or tasks, each of which may need its
own database connection.
</simpara>
</simplesect>
<simplesect xml:id="persistent-connections.why">
<title>Why Use Them?</title>
<simpara>
Persistent connections are beneficial when the overhead of creating a link
to an SQL server is high. Whether this overhead is significant depends on
many factors, such as the type of database, whether it resides on the same
machine as the web server, and how loaded that machine is. When the
connection overhead is high, persistent connections can help considerably:
each child process connects only once for its entire lifespan, rather than
every time it processes a page that requires a connection to the SQL
server. This means every child that opens a persistent connection will
maintain its own connection to the server. For example, if 20 different
child processes each run a script that makes a persistent connection to
the SQL server, there will be 20 separate connections to that server, one
from each child.
</simpara>
</simplesect>
<simplesect xml:id="persistent-connections.drawbacks.conn-limits">
<title>Potential Drawbacks: Connection Limits</title>
<simpara>
Note, however, that this can have drawbacks when using a
database with connection limits that are exceeded by persistent
child connections. If the database has a limit of 16 simultaneous
connections, and during a busy server session 17 child
processes attempt to connect, one of them will fail. If there are
bugs in the scripts that prevent connections from shutting
down (such as infinite loops), a database with only 16 connections
may be rapidly swamped.
</simpara>
<simpara>
Persistent connections will usually increase the number of connections open
at any given time, because idle workers still hold on to the connections they
opened for previous requests. If a large number of workers are spun up to
handle a spike in traffic, the connections they opened will remain until
the worker is terminated or the database server closes the connection.
</simpara>
<simpara>
Ensure that the maximum number of connections allowed by the database server
is greater than the maximum number of web request workers (plus any other
usage such as crons or administrative connections).
</simpara>
<simpara>
Check the database documentation for information on handling abandoned or
idle connections (timeouts). Long timeouts may significantly increase the
number of persistent connections open at any one time.
</simpara>
</simplesect>
<simplesect xml:id="persistent-connections.drawbacks.state">
<title>Potential Drawbacks: Maintaining Connection State</title>
<simpara>
Some database extensions perform automatic cleanup when the connection is
reused; others leave this task at the discretion of the application developer.
Depending on the chosen database extension and the application design, manual
cleanup may be needed before the script exits. Changes that may leave
connections in an unexpected state include:
</simpara>
<simplelist>
<member>Selected / default database</member>
<member>Table locks</member>
<member>Uncommitted transactions</member>
<member>Temporary tables</member>
<member>Connection specific settings or features such as profiling</member>
</simplelist>
<simpara>
Table locks and transactions that are not cleaned up or closed may cause
other queries to be blocked indefinitely and/or cause subsequent reuse of
the connection to cause unexpected changes.
</simpara>
<simpara>
Having the wrong database selected will cause subsequent reuse of the
connection to be unable to execute queries as expected (or execute them on
the wrong database if schemas are similar enough).
</simpara>
<simpara>
If temporary tables are not cleaned up, subsequent requests will not be able
to recreate the same table.
</simpara>
<simpara>
Cleanup can be implemented using class destructors or
<function>register_shutdown_function</function>. Dedicated connection
pooling proxies that include this as part of their functionality may
also be considered.
</simpara>
</simplesect>
<simplesect xml:id="persistent-connections.final-words">
<title>Final Words</title>
<simpara>
Given their behavior and potential drawbacks described above, persistent
connections should not be used without careful consideration. They should
not be used without implementing additional changes to the application and
careful configuration of the database server and web server and/or PHP-FPM.
</simpara>
<simpara>
Consider alternative solutions such as investigating and fixing the causes of
connection creation overheads (for example, disabling reverse DNS lookups on
the database server), or dedicated connection pooling proxies.
</simpara>
<simpara>
For high volume web APIs, consider using alternative runtimes or long-running
application servers.
</simpara>
</simplesect>
<simplesect role="seealso" xml:id="persistent-connections.seealso">
&reftitle.seealso;
<simplelist>
<member><function>ibase_pconnect</function></member>
<member><function>oci_pconnect</function></member>
<member><function>odbc_pconnect</function></member>
<member><function>pfsockopen</function></member>
<member><function>pg_connect</function></member>
<member><link linkend="mysqli.persistconns">MySQLi and Persistent Connections</link></member>
<member><link linkend="pdo.connections">PDO Connection Management</link></member>
</simplelist>
</simplesect>
</chapter>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->