reference/oci8/taf.xml
f80105b4fc1196bd8d5fecb98d686b580b1ff65d
...
...
@@ -0,0 +1,373 @@
1
+
<?xml version="1.0" encoding="utf-8"?>
2
+
<!-- $Revision$ -->
3
+
<chapter xml:id="oci8.taf" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
4
+
<title>OCI8 Transparent Application Failover (TAF) Support</title>
5
+
<section>
6
+
<para>
7
+
TAF is an Oracle Database feature that provides high availability.
8
+
It enables PHP OCI8 applications to automatically reconnect to a
9
+
preconfigured database when database connectivity fails due to
10
+
instance or network failure.
11
+
</para>
12
+
<para>
13
+
In a configured Oracle Database system, TAF occurs when the PHP
14
+
application detects that the database instance is down or
15
+
unreachable. It establishes a connection to another node in an
16
+
Oracle <link xlink:href="&url.oracle.taf.rac;">RAC</link>
17
+
configuration, a hot standby database, or the same database
18
+
instance
19
+
itself. See <link xlink:href="&url.oracle.taf.ociguide;">Oracle
20
+
Call Interface Programmer's Guide</link> for more information about
21
+
OCI TAF.
22
+
</para>
23
+
<para>
24
+
An application callback can be registered
25
+
with <function>oci_register_taf_callback</function>. During
26
+
failover, normal application processing stops and the registered
27
+
callback is invoked. The callback notifies the application of the
28
+
failover events. If the failover succeeds, normal processing will
29
+
be resumed. If the failover aborts, any following database
30
+
operations in the application will fail due to no connection being
31
+
available.
32
+
</para>
33
+
<para>
34
+
When a connection fails over to another database, the callback can
35
+
reset any necessary connection state, for example replaying any
36
+
necessary ALTER SESSION commands if the database service did not have
37
+
-failover_restore enabled.
38
+
</para>
39
+
<para>
40
+
An application callback can be removed by calling <function>oci_unregister_taf_callback</function>.
41
+
</para>
42
+
</section>
43
+
<section>
44
+
<title>Configuring Transparent Application Failover</title>
45
+
<para>
46
+
TAF can be configured on the PHP OCI8 side or in the database
47
+
configuration. If both are configured, database-side settings
48
+
take precedence.
49
+
</para>
50
+
<para>
51
+
Configure TAF in PHP OCI8 (the client side) by including the
52
+
FAILOVER_MODE parameter in the CONNECT_DATA portion of a
53
+
connect descriptor. See Configuring Transparent Application
54
+
Failover in <link xlink:href="&url.oracle.taf.clientconfig;">
55
+
Oracle Database Net Services Administrator's Guide</link> for
56
+
more information about client side configuration of TAF.
57
+
</para>
58
+
<para>
59
+
An example tnsnames.ora to configure TAF reconnecting to the
60
+
same database instance:
61
+
</para>
62
+
<para>
63
+
<informalexample>
64
+
<screen>
65
+
<![CDATA[
66
+
ORCL =
67
+
(DESCRIPTION =
68
+
(ADDRESS = (PROTOCOL = TCP)(HOST = 127.0.0.1)(PORT = 1521))
69
+
(CONNECT_DATA =
70
+
(SERVICE_NAME = orclpdb1)
71
+
(FAILOVER_MODE =
72
+
(TYPE = SELECT)
73
+
(METHOD = BASIC)
74
+
(RETRIES = 20)
75
+
(DELAY = 15))))
76
+
]]>
77
+
</screen>
78
+
</informalexample>
79
+
</para>
80
+
<para>
81
+
Alternatively configure TAF on the database side by
82
+
modifying the target service with
83
+
<link xlink:href="&url.oracle.taf.srvctl;">srvctl</link>
84
+
(for RAC) or the
85
+
<link xlink:href="&url.oracle.taf.dbmsservice;">
86
+
DBMS_SERVICE.MODIFY_SERVICE</link> packaged procedure
87
+
(for single instance databases).
88
+
</para>
89
+
</section>
90
+
<section>
91
+
<title>Using TAF Callbacks in OCI8</title>
92
+
<para>
93
+
A TAF callback is an application function that can be
94
+
registered to be called during failover. It is called
95
+
several times while re-establishing the application's connection.
96
+
</para>
97
+
<para>
98
+
Callback first occurs when a loss of connection is detected.
99
+
This allows the application to act accordingly for the
100
+
upcoming delay of the failover. If the failover is successful,
101
+
the callback is invoked after connection is re-established
102
+
and usable. At this time, the application can resynchronize
103
+
session settings and take actions such as informing the user
104
+
that failover occurred. If failover is unsuccessful, a
105
+
callback occurs to inform the application that a failover did
106
+
not take place and the connection is unusable.
107
+
</para>
108
+
<para>
109
+
The interface of a TAF user-defined callback function is as
110
+
follows:
111
+
</para>
112
+
<methodsynopsis>
113
+
<type>int</type><methodname>userCallbackFn</methodname>
114
+
<methodparam><type>resource</type><parameter>connection</parameter></methodparam>
115
+
<methodparam><type>int</type><parameter>event</parameter></methodparam>
116
+
<methodparam><type>int</type><parameter>type</parameter></methodparam>
117
+
</methodsynopsis>
118
+
<para>
119
+
<variablelist>
120
+
<varlistentry>
121
+
<term><parameter>connection</parameter></term>
122
+
<listitem>
123
+
<para>
124
+
The Oracle connection on which the TAF callback was
125
+
registered via <function>oci_register_taf_callback</function>.
126
+
The connection is not valid until the
127
+
failover completes successfully.
128
+
</para>
129
+
</listitem>
130
+
</varlistentry>
131
+
<varlistentry>
132
+
<term><parameter>event</parameter></term>
133
+
<listitem>
134
+
<para>
135
+
The failover event indicates the current status of
136
+
the failover.
137
+
</para>
138
+
<para>
139
+
<itemizedlist>
140
+
<listitem>
141
+
<para>
142
+
<constant>OCI_FO_BEGIN</constant> indicates that
143
+
failover has detected a lost connection and failover
144
+
is starting.
145
+
</para>
146
+
</listitem>
147
+
<listitem>
148
+
<para>
149
+
<constant>OCI_FO_END</constant> indicates successful
150
+
completion of failover.
151
+
</para>
152
+
</listitem>
153
+
<listitem>
154
+
<para>
155
+
<constant>OCI_FO_ABORT</constant> indicates that
156
+
failover was unsuccessful, and there is no option
157
+
of retrying.
158
+
</para>
159
+
</listitem>
160
+
<listitem>
161
+
<para>
162
+
<constant>OCI_FO_ERROR</constant> also indicates
163
+
that failover was unsuccessful, but it gives the
164
+
application the opportunity to handle the error
165
+
and return OCI_FO_RETRY to retry failover.
166
+
</para>
167
+
</listitem>
168
+
<listitem>
169
+
<para>
170
+
<constant>OCI_FO_REAUTH</constant> indicates
171
+
that an Oracle user has been re-authenticated.
172
+
</para>
173
+
</listitem>
174
+
</itemizedlist>
175
+
</para>
176
+
</listitem>
177
+
</varlistentry>
178
+
<varlistentry>
179
+
<term><parameter>type</parameter></term>
180
+
<listitem>
181
+
<para>
182
+
The failover type. This lets the callback know what
183
+
type of failover the application has requested. The
184
+
usual values are as follows:
185
+
</para>
186
+
<para>
187
+
<itemizedlist>
188
+
<listitem>
189
+
<para>
190
+
<constant>OCI_FO_SESSION</constant> indicates that
191
+
the user has requested only session failover. For
192
+
example, if a user's connection is lost, then a
193
+
new session is automatically created for the user
194
+
on the backup. This type of failover does not
195
+
attempt to recover SELECTs.
196
+
</para>
197
+
</listitem>
198
+
<listitem>
199
+
<para>
200
+
<constant>OCI_FO_SELECT</constant> indicates that
201
+
the user has requested SELECT failover as well.
202
+
It allows users with open cursors to continue
203
+
fetching from them after failure.
204
+
</para>
205
+
</listitem>
206
+
</itemizedlist>
207
+
</para>
208
+
</listitem>
209
+
</varlistentry>
210
+
<varlistentry>
211
+
<term><parameter>return value</parameter></term>
212
+
<listitem>
213
+
<para>
214
+
<itemizedlist>
215
+
<listitem>
216
+
<para>
217
+
<literal>0</literal> indicates the failover
218
+
steps should continue normally.
219
+
</para>
220
+
</listitem>
221
+
<listitem>
222
+
<para>
223
+
<constant>OCI_FO_RETRY</constant> indicates that
224
+
the failover should be attempted again by Oracle.
225
+
In case of an error while failing over to a new
226
+
connection, TAF is able to retry the failover.
227
+
Typically, the application code should sleep for
228
+
a while before returning OCI_FO_RETRY.
229
+
</para>
230
+
</listitem>
231
+
</itemizedlist>
232
+
</para>
233
+
</listitem>
234
+
</varlistentry>
235
+
</variablelist>
236
+
</para>
237
+
<example>
238
+
<para>
239
+
The following example registers a TAF callback
240
+
</para>
241
+
<programlisting role="php">
242
+
<![CDATA[
243
+
<?php
244
+

245
+
// Define userspace callback
246
+
class MyClass {
247
+
public static $retry_count;
248
+
public static function TAFCallback($conn, $event, $type)
249
+
{
250
+
switch ($event) {
251
+
case OCI_FO_BEGIN:
252
+
printf(" Failing Over ... Please stand by\n");
253
+
printf(" Failover type was found to be %s \n",
254
+
(($type==OCI_FO_SESSION) ? "SESSION"
255
+
:(($type==OCI_FO_SELECT) ? "SELECT" : "UNKNOWN!")));
256
+
self::$retry_count = 0;
257
+
break;
258
+
case OCI_FO_ABORT:
259
+
// The application cannot continue using the database
260
+
printf(" Failover aborted. Failover will not take place.\n");
261
+
break;
262
+
case OCI_FO_END:
263
+
// Failover completes successfully. Inform users a failover occurs.
264
+
printf(" Failover ended ... resuming services\n");
265
+
break;
266
+
case OCI_FO_REAUTH:
267
+
printf(" Failed over user ... resuming services\n");
268
+
// Replay any ALTER SESSION commands associated with this connection
269
+
// eg. oci_parse($conn, ‘ALTER SESSION …’) ;
270
+
break;
271
+
case OCI_FO_ERROR:
272
+
// Stop retrying if we have already attempted for 20 times.
273
+
if (self::$retry_count >= 20)
274
+
return 0;
275
+
printf(" Failover error received. Sleeping...\n");
276
+
sleep(10);
277
+
self::$retry_count++;
278
+
return OCI_FO_RETRY; // retry failover
279
+
break;
280
+
default:
281
+
printf("Bad Failover Event: %d.\n", $event);
282
+
break;
283
+
}
284
+
return 0;
285
+
}
286
+
}
287
+

288
+
$fn_name = 'MyClass::TAFCallback';
289
+

290
+
$conn = oci_connect('hr', 'welcome', 'orcl');
291
+
$sysconn = oci_connect('system', 'oracle', 'orcl');
292
+

293
+
// Use a privileged connection to construct a SQL statement that will initiate failover
294
+
$sql = <<< 'END'
295
+
select unique 'alter system disconnect session '''||sid||','||serial#||''''
296
+
from v$session_connect_info
297
+
where sid = sys_context('USERENV', 'SID')
298
+
END;
299
+

300
+
$s = oci_parse($conn, $sql);
301
+
oci_execute($s);
302
+
$r = oci_fetch_array($s);
303
+
$disconnectssql = $r[0];
304
+

305
+
oci_register_taf_callback($conn, $fn_name); // Register TAFCallback to Oracle TAF
306
+

307
+
print "Parsing user query\n";
308
+
$sql = "select systimestamp from dual";
309
+
$stmt = oci_parse($conn, $sql);
310
+

311
+
// For example, if a connection loss occurs at this point, oci_execute() will
312
+
// detect the loss and failover begins. During failover, oci_execute() will
313
+
// invoke the TAF callback function several times. If the failover is successful,
314
+
// a new connection is transparently created and oci_execute() will continue as
315
+
// usual. The connection session settings can be reset in the TAF callback
316
+
// function. If the failover is aborted, oci_execute() will return an error
317
+
// because a valid connection is not available.
318
+

319
+
// Disconnect the user, which initiates failover
320
+
print "Disconnecting the user\n";
321
+
$discsql = oci_parse($sysconn, $disconnectssql);
322
+
oci_execute($discsql);
323
+

324
+
print "Executing user query\n";
325
+
$e = oci_execute($stmt);
326
+
if (!$e) {
327
+
$m = oci_error($stmt);
328
+
trigger_error("Could not execute statement: ". $m['message'], E_USER_ERROR);
329
+
}
330
+
$row = oci_fetch_array($stmt);
331
+
print $row[0] . "\n";
332
+

333
+
// do other SQL statements with the new connection, if it is valid
334
+
// $stmt = oci_parse($conn, . . .);
335
+

336
+
?>
337
+
]]>
338
+
</programlisting>
339
+
</example>
340
+
</section>
341
+

342
+
<section>
343
+
&reftitle.seealso;
344
+
<simplelist>
345
+
<member><function>oci_register_taf_callback</function></member>
346
+
<member><function>oci_unregister_taf_callback</function></member>
347
+
</simplelist>
348
+
</section>
349
+

350
+

351
+
</chapter>
352
+

353
+
<!-- Keep this comment at the end of the file
354
+
Local variables:
355
+
mode: sgml
356
+
sgml-omittag:t
357
+
sgml-shorttag:t
358
+
sgml-minimize-attributes:nil
359
+
sgml-always-quote-attributes:t
360
+
sgml-indent-step:1
361
+
sgml-indent-data:t
362
+
indent-tabs-mode:nil
363
+
sgml-parent-document:nil
364
+
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
365
+
sgml-exposed-tags:nil
366
+
sgml-local-catalogs:nil
367
+
sgml-local-ecat-files:nil
368
+
End:
369
+
vim600: syn=xml fen fdm=syntax fdl=2 si
370
+
vim: et tw=78 syn=sgml
371
+
vi: ts=1 sw=1
372
+
-->
373
+

0
374