1Apache::DBI::Cache(3) User Contributed Perl DocumentationApache::DBI::Cache(3)
2
3
4

NAME

6       Apache::DBI::Cache - a DBI connection cache
7

SYNOPSIS

9         use Apache::DBI::Cache debug=>3, bdb_env=>'/tmp/tmp',
10                                plugin=>'Apache::DBI::Cache::mysql',
11                                plugin=>['DBM', sub {...}, sub {...}],
12                                ...;
13

DESCRIPTION

15       This module is an alternative to the famous Apache::DBI module. As
16       Apache::DBI it provides persistent DBI connections.
17
18       It can be used with mod_perl1, mod_perl2 and even standalone.
19
20   WHY ANOTHER MODULE FOR THE SAME?
21       Apache::DBI has a number of limitations. Firstly, it is not possible to
22       get multiple connections with the same parameters. A common scenario
23       for example is to use one connection to perform transactions and
24       another to perform simple lookups in the same database. With
25       Apache::DBI it is very likely to get the same connection if you mean to
26       use different.
27
28       With Apache::DBI all connections are reset at end of a request.
29
30       Apache::DBI does not regard database specific functions to cache
31       handles more aggressively. For example a mysql DSN can look like
32
33        dbi:mysql:test:localhost:3306
34
35       or
36
37        dbi:mysql:host=localhost;db=test
38
39       Both point to the same database but for Apache::DBI they are different.
40       Apache::DBI::Cache recognizes these two by means of a mysql plugin.
41
42       The plugin even recognizes connections to different databases on the
43       same mysql server as the same connection and issues a "USE database"
44       command before returning the actual handle to the user. Hence, with
45       Apache::DBI::Cache many the overall number of connections to a DB
46       server can be dramatically reduced.
47
48   HOW DOES IT WORK?
49       To decide whether to use Apache::DBI::Cache or not it is essential to
50       know how it works. As with Apache::DBI Apache::DBI::Cache uses a hook
51       provided by the DBI module to intercept "DBI->connect()" calls.  Also
52       do Apache::DBI::Cache maintain a cache of active handles.
53
54       When a new connection is requested and the cache is empty a new
55       connection is established and returned to the user. At this point it is
56       not cached at all. Here Apache::DBI::Cache differs from Apache::DBI.
57
58       Later either "disconnect" is called on the handle or it simply goes out
59       of scope and the garbage collector calls a "DESTROY" method if
60       provided. Both events are intercepted by Apache::DBI::Cache. Only then
61       the handle is put in the cache.
62
63       This means a handle is never really disconnected. "$dbh->{Active}" will
64       always return true no matter how often "disconnect" is called.
65       Further, you can prevent a handle from getting reused by simply not
66       forgetting it.
67
68   USAGE
69       Different to Apache::DBI Apache::DBI::Cache must be "use"ed not
70       "require"ed.  That means it's "import" function must be called.
71
72       When used with mod_perl (versions 1.x or 2.x) this is best done in a
73       "startup.pl" or in a "<Perl>" section in the "httpd.conf".  See
74       mod_perl documentation for more information.
75
76       Thereafter, "DBI->connect" is called as usual. No special treatment is
77       needed.
78
79       When Apache::Status or Apache2::Status is used Apache::DBI::Cache
80       provides an extra menu item to show statistics on handles. The loading
81       order of the Apache::Status and Apache::DBI::Cache is irrelevant.
82
83   FUNCTIONS
84       import - "use" parameter
85           Parameters to the "use" statement are given in a "key => value"
86           fashion.
87
88            use Apache::DBI::Cache debug=>3, logger=>sub {...},
89                                   plugin=>['driver', sub {}, sub {}],
90                                   plugin=>'Apache::DBI::Cache::mysql',
91                                   use_bdb=>1,
92                                   bdb_env=>'/tmp/mybdbenv',
93                                   bdb_memcache=>20*1024,
94                                   ...;
95
96plugin
97
98             loads a plugin, see also "PLUGINS" below. The plugin can be
99             specified as a 3-element array or by name. In the second case the
100             "import" simply "use"s the module. This option can be given
101             multiple times.
102
103use_bdb, bdb_env and bdb_memcache
104
105             Apache::DBI::Cache can use BerleleyDB as a shared memory
106             implementation to maintain statistics for a group of processes
107             instead of a single process.
108
109             "use_bdb" specify whether to use BerkeleyDB or not. If ommitted
110             Apache::DBI::Cache will try to load and use BerkeleyDB. If that
111             fails it silently provides per process statistics. If "use_bdb"
112             is true Apache::DBI::Cache dies if it cannot use BerkeleyDB. If
113             "use_bdb" is false per process statistics are maintained and
114             BerkeleyDB is not used.
115
116             "bdb_env" specifies a path to a directory where BerkeleyDB can
117             put it's temporary files. If omitted "/tmp/Apache::DBI::Cache" is
118             used.  The parent directory of this directory must exists and be
119             writeable.
120
121             "bdb_memcache" specifies the size of the shared memory segment
122             that is allocated by BerkeleyDB. Depending on the number of
123             handles in your configuration a few kilobytes are enough. If
124             omitted 20 kB are used.
125
126             "bdb_env" and "bdb_memcache" can also be specified by the
127             "APACHE_DBI_CACHE_ENVPATH" and "APACHE_DBI_CACHE_CACHESIZE"
128             environment variables.
129
130debug
131
132             set a debug level. Under mod_perl this is almost irrelevant, see
133             "logger" below.
134
135logger
136
137             here a logger function can be specified. It is called with the
138             message verbosity level as the first parameter. The remaining
139             parameters are concatenated to build the actual message.
140
141             Currently there are 2 verbosity levels used 1 and 2. 0 is
142             reserved for real errors. 1 mentions that the module has been
143             initialized. 2 rattle off normal processing messages.
144
145             Apache::DBI::Cache provides 2 logger functions. One is controlled
146             by the "debug" level setting (see above). A message is printed to
147             STDERR if it's level is equal or greater the current debug level.
148
149             The other logger is used when running under mod_perl. It is
150             mainly controlled by the Apache "LogLevel" setting. Messages at
151             level 0 are printed as "$log->error", level 1 as "$log->info" and
152             level 2 as "$log->debug". For level 2 messages additionally the
153             current debug level is checked to be greater or equal 2.
154
155delimiter
156
157             Here the internal key delimiter can be changed. It defaults to
158             "\1".  Changing it is necessary only when your DSN, username or
159             password contain it or to provide more readable debugging
160             messages.
161
162       statistics
163           returns a reference to the statistics hash. If BerkeleyDB is used
164           it is tied to BerkeleyDB::Btree.
165
166       statistics_as_html
167           returns a reference to an array of HTML fragments. If mod_perl and
168           Apache::Status or Apache::Status2 is used the output of this
169           function is shown under http://HOST/STATUS/URI?DBI_conn.
170
171       plugin( 'name', \&mangle, \&setup )
172           installs a new plugin, see "PLUGINS" below. If a plugin for the
173           specified database type was already installed it is returned as a
174           2-element list:
175
176            ($old_mangle, $old_setup)=
177              plugin( 'name', \&new_mangle, \&new_setup );
178
179           If called with an name only the current plugin is returned:
180
181            ($old_mangle, $old_setup)=plugin( 'name' );
182
183           To delete a plugin call
184
185            ($old_mangle, $old_setup)=plugin( 'name', undef, undef );
186
187       connect_on_init
188           call this function multiple times with parameters you would pass to
189           "DBI->connect" before calling "Apache::DBI::Cache::init", i.e.  in
190           your "startup.pl". Then "init" will establish all these
191           connections.
192
193       init
194           This function is called once per child process to initialize
195           Apache::DBI::Cache. If mod_perl is used this is done automatically
196           in a PerlChildInitHandler
197
198       finish
199           This function must be called before a process is going to
200           terminate. Under mod_perl it is automatically called in a
201           PerlChildExitHandler.
202
203           As of version 0.08 calling this function is optional.
204
205       undef_at_request_cleanup( \$dbh1, \$dbh2, ... )
206           When an application uses global variables to store handles they
207           probably won't be reused because a global variable is ..., well
208           global. This can be fixed by explicitly undefining these handles at
209           request cleanup or by using this function. It simply collects all
210           handle references passed in between 2 calls to
211           "Apache::DBI::Cache::request_cleanup". When
212           "Apache::DBI::Cache::request_cleanup" is called all these handles
213           are undefined. The first call to this function during a request
214           cycle installs "Apache::DBI::Cache::request_cleanup" as
215           PerlCleanupHandler.
216
217           With mod_perl2 this requires the PerlOption "GlobalRequest" to be
218           set:
219
220            PerlOption +GlobalRequest
221
222           in your httpd.conf.
223
224       request_cleanup
225           This is the PerlCleanupHandler. If Apache::DBI::Cache is used
226           standalone the application can call it from time to time.
227
228   EXPORT
229       Nothing.
230

DBI SUBCLASSING

232       For a module like Apache::DBI::Cache it is complicated to cope with DBI
233       subclasses. There are 2 problems to solve. First, make sure that our
234       "disconnect" and "DESTROY" methods are called instead of the original.
235       Apache::DBI::Cache solves this problem by inserting its own methods
236       into the foreign class.
237
238       Hence, if a subclass provides "disconnect" and "DESTROY" methods they
239       will never be called. This is ugly but works in most cases.
240
241       To insert our methods into the subclass we need to know its name.  This
242       is the second problem. To create a subclassed DBI handle one calls
243       either
244
245        DBI->connect( $dsn, $user, $passwd, {RootClass=>SUBCLASS} );
246
247       or
248
249        SUBCLASS->connect( $dsn, $user, $passwd, {} );
250
251       The first case is simple since the attribute hash is passed to our
252       connect method. Unfortunately, the second case is not simple since
253       "SUBCLASS" is known only by "DBI::connect". This is solved by searching
254       the current call stack for the DBI::connect call. Then we use its first
255       parameter.
256
257       That works for me but is even uglier. If you encounter problems don't
258       hesitate to mail me.
259

Class::DBI and Ima::DBI

261       To make "Class::DBI" or "Ima::DBI" work with "Apache::DBI::Cache" see
262       Apache::DBI::Cache::ImaDBI.
263

PLUGINS

265       Plugins are used to modify the caching for certain database types. They
266       can change the caching key, issue database commands just before a
267       handle is returned to the user or prevent handle caching entirely for a
268       database type.
269
270       There can only be one plugin per database type at a time.
271
272       A plugin registers itself by calling "Apache::DBI::Cache::plugin"
273       passing 3 parameters. The first parameter is simply the name of the
274       database type.  It matches the DBI driver name. Thus, a MySQL plugin
275       passes the string "mysql" since the corresponding DBI driver is named
276       "DBD::mysql".  Whereas a PostgreSQL plugin passes either "Pg" or "PgPP"
277       depending on the driver actually used.
278
279       The 2nd and 3rd parameters are CODE references that are called just
280       before a connection is chosen from the cache or newly established and
281       after the connection is made just before it is returned to the caller.
282       The first function can mangle the connection parameters the second
283       perform additional setup steps. Further, I will call them mangle and
284       setup.
285
286       Thus, a plugin is registered this way:
287
288        Apache::DBI::Cache::plugin('Name', \&mangle, \&setup);
289
290       Normally, it is implemented as a separate module according to the
291       following template, see Apache::DBI::Cache::mysql for example:
292
293        package Apache::DBI::Cache::DRIVER;
294
295        use strict;
296
297        BEGIN {
298          die "Please load Apache::DBI::Cache before"
299            unless defined &Apache::DBI::Cache::plugin;
300
301          ...
302
303          Apache::DBI::Cache::plugin
304              (
305               'DRIVER',
306               sub {},
307               sub {}
308              );
309        }
310
311        1;
312
313   Calling Conventions
314mangle
315
316          ($dsn, $user, $passwd, $attr, $ctx, $nocache)=
317             mangle($dsn, $user, $passwd, $attr);
318
319         mangle is called with almost the same parameters as the original call
320         to "DBI->connect". The "dbi:DRIVER:" prefix is stripped from the DSN.
321         It is expected to return similar values plus an arbitrary context
322         that is later passed to setup and an optional "nocache" flag.
323
324         If $nocache is true or mangle returns an empty list a new connection
325         is made and the handle is directly passed to the caller without
326         further processing. Also setup will not be called. Such a handle will
327         not be cached on "disconnect" or "DESTROY".
328
329         mangle can change all parameters. The MySQL plugin for example
330         deletes the actual database name from the DSN, reformats it according
331         to a standard format and adds the standard port if it is omitted. The
332         database is put in the context.
333
334setup
335
336          $rc=setup($dbh, $dsn, $user, $passwd, $attr, $ctx);
337
338         The setup function performs additional setup steps on $dbh. The MySQL
339         plugin for example issues a "USE database" command using the database
340         from the context.
341
342         A connection is considered dead if setup returns false.
343

TODO

345       •   periodically ping all cached handles
346
347       •   correct statistics when a process is finishes without calling
348           "finish()"
349
350       •   redirect BerkeleyDB errors to logger
351

SEE ALSO

353       Apache::DBI::Cache::mysql
354       Apache::DBI
355

AUTHOR

357       Torsten Foertsch, <torsten.foertsch@gmx.net>
358
359       With suggestions from
360
361           Andreas Nolte < andreas dot nolte at bertelsmann dot de >
362
363           Dietmar Hanisch < dietmar dot hanisch at bertelsmann dot de > and
364
365           Ewald Hinrichs < ewald dot hinrichs at bertelsmann dot de >
366

SPONSORING

368       Sincere thanks to Arvato Direct Services (http://www.arvato.com/) for
369       sponsoring this module and providing a test platform with several
370       thousand DBI connections.
371
373       Copyright (C) 2005-2006 by Torsten Foertsch
374
375       This library is free software; you can redistribute it and/or modify it
376       under the same terms as Perl itself.
377
378
379
380perl v5.36.0                      2022-07-22             Apache::DBI::Cache(3)
Impressum