[svn:dbd-oracle] r14813 - dbd-oracle/branches/TAF
[email protected] Mon, 4 Apr 2011 09:36:28 -0700 (PDT)
| Newsgroups | perl.dbd.oracle.changes |
|---|---|
| Message-ID | <[email protected]> |
Author: byterock
Date: Mon Apr 4 09:36:26 2011
New Revision: 14813
Modified:
dbd-oracle/branches/TAF/Oracle.pm
dbd-oracle/branches/TAF/Oracle.xs
dbd-oracle/branches/TAF/dbdimp.c
dbd-oracle/branches/TAF/dbdimp.h
dbd-oracle/branches/TAF/oci8.c
Log:
working and pod all updated ready to go back into trunk
Modified: dbd-oracle/branches/TAF/Oracle.pm
==============================================================================
--- dbd-oracle/branches/TAF/Oracle.pm (original)
+++ dbd-oracle/branches/TAF/Oracle.pm Mon Apr 4 09:36:26 2011
@@ -71,22 +71,23 @@
});
DBD::Oracle::dr::init_oci($drh) ;
$drh->STORE('ShowErrorStatement', 1);
- DBD::Oracle::db->install_method("ora_lob_read");
- DBD::Oracle::db->install_method("ora_lob_write");
- DBD::Oracle::db->install_method("ora_lob_append");
- DBD::Oracle::db->install_method("ora_lob_trim");
- DBD::Oracle::db->install_method("ora_lob_length");
- DBD::Oracle::db->install_method("ora_lob_chunk_size");
- DBD::Oracle::db->install_method("ora_lob_is_init");
- DBD::Oracle::db->install_method("ora_nls_parameters");
- DBD::Oracle::db->install_method("ora_can_unicode");
- DBD::Oracle::st->install_method("ora_fetch_scroll");
- DBD::Oracle::st->install_method("ora_scroll_position");
- DBD::Oracle::st->install_method("ora_ping");
- DBD::Oracle::st->install_method("ora_stmt_type_name");
- DBD::Oracle::st->install_method("ora_stmt_type");
- $drh;
-
+ DBD::Oracle::db->install_method("ora_lob_read");
+ DBD::Oracle::db->install_method("ora_lob_write");
+ DBD::Oracle::db->install_method("ora_lob_append");
+ DBD::Oracle::db->install_method("ora_lob_trim");
+ DBD::Oracle::db->install_method("ora_lob_length");
+ DBD::Oracle::db->install_method("ora_lob_chunk_size");
+ DBD::Oracle::db->install_method("ora_lob_is_init");
+ DBD::Oracle::db->install_method("ora_nls_parameters");
+ DBD::Oracle::db->install_method("ora_can_unicode");
+ DBD::Oracle::db->install_method("ora_can_taf");
+ DBD::Oracle::st->install_method("ora_fetch_scroll");
+ DBD::Oracle::st->install_method("ora_scroll_position");
+ DBD::Oracle::st->install_method("ora_ping");
+ DBD::Oracle::st->install_method("ora_stmt_type_name");
+ DBD::Oracle::st->install_method("ora_stmt_type");
+ $drh;
+
}
@@ -1429,6 +1430,89 @@
At this point in time this is just the first crack at DRCP and DBD::Oracle so the mechanics or its implementation are subject to change.
+=head2 TAF (Transparent Application Failover)
+Transparent Application Failover (TAF) is a longstanding default feature in OCI that allows for clients to automatically reconnect to
+an instance in the event of a failure of an instance. The reconnect happens automatically from within the OCI (Oracle Call Interface) library.
+DBD::Oracle now supports a callback function that will fire when a callback event takes place. The main use of the callback is that it
+gives the oppertunity for the program to inform the user that a failover is taking place.
+
+You will have to set up TAF on your instance before you can use this callback. You can test your instance to see if you can use TAF callback with
+
+ $dbh->ora_can_taf();
+
+If you try to set up a callback without it being enable DBD::Oracle will croak.
+
+It is outside the scope of this documents to go through all of the possiable TAF situations you might want to set up. Below is the simplest of examples;
+
+The TNS entry for the instace has had the following added to the CONNECT_DATA portion
+
+ (FAILOVER_MODE=
+ (TYPE=select)
+ (METHOD=basic)
+ (RETRIES=10)
+ (DELAY=10))
+
+You will also have to create your on perl function that will be called from the client. You can name it anything you want and it will allways return
+two values, the failover event value and the failover type value. You can also set a sleep value in case of failover error and the oci client will sleep
+for the entered seconds before it attempts another event.
+
+ use DBD::Oracle(qw(:ora_fail_over));
+ #import the ora_fail_over constancts
+
+ #set up TAF on the conection
+ my $dbh = DBI->connect('dbi:Oracle:XE','hr','hr',{ora_taf=>1,taf_sleep=>5,ora_taf_function=>'handle_taft'});
+
+ #create the perl TAF event function
+
+ sub handle_taf {
+ my ($fo_event,$fo_type) = @_;
+ if ($fo_event == OCI_FO_BEGIN){
+
+ print(" Instance Unavailable Please stand by!! \n");
+ printf(" Your TAF type is %s \n",
+ (($fo_type==OCI_FO_NONE) ? "NONE"
+ :($fo_type==OCI_FO_SESSION) ? "SESSION"
+ :($fo_type==OCI_FO_SELECT) ? "SELECT"
+ : "UNKNOWN!"));
+ }
+ elsif ($fo_event == OCI_FO_ABORT){
+ printf(" Failover aborted. Failover will not take place.\n");
+ }
+ elsif ($fo_event == OCI_FO_END){
+ printf(" Failover ended ...Resuming your %s\n",(($fo_type==OCI_FO_NONE) ? "NONE"
+ :($fo_type==OCI_FO_SESSION) ? "SESSION"
+ :($fo_type==OCI_FO_SELECT) ? "SELECT"
+ : "UNKNOWN!"));
+ }
+ elsif ($fo_event == OCI_FO_REAUTH){
+ printf(" Failed over user. Resuming services\n");
+ }
+ elsif ($fo_event == OCI_FO_ERROR){
+ printf(" Failover error Sleeping...\n");
+ }
+ else {
+ printf(" Bad Failover Event: %d.\n", $fo_event);
+
+ }
+ return 0;
+ }
+
+The TAF types are as follows
+
+ OCI_FO_SESSION which indicates the user has requested only session failover.
+ OCI_FO_SELECT which indicates the user has requested select failover.
+ OCI_FO_NONE which inicates the user has not requested a failover type.
+ OCI_FO_TXNAL which indicates the user has requested a transaction failover.
+
+The TAF events are as follows
+
+ OCI_FO_BEGIN indicates that failover has detected a lost connection and failover is starting.
+ OCI_FO_END indicates successful completion of failover.
+ OCI_FO_ABORT indicates that failover was unsuccessful, and there is no option of retrying.
+ OCI_FO_ERROR also indicates that failover was unsuccessful, but it gives the application the opportunity to handle the error and retry failover.
+ OCI_FO_REAUTH indicates that you have multiple authentication handles and failover has occurred after the original authentication. It indicates that a user handle has been re-authenticated. To find out which, the application checks the OCI_ATTR_SESSION attribute of the service context handle (which is the first parameter).
+
+
=head2 Optimizing Oracle's listener
[By Lane Sharman <[email protected]>] I spent a LOT of time optimizing
@@ -1574,7 +1658,12 @@
=item :ora_exe_modes
OCI_STMT_SCROLLABLE_READONLY
-
+
+=item :ora_fail_over
+
+ OCI_FO_END OCI_FO_ABORT OCI_FO_REAUTH OCI_FO_BEGIN OCI_FO_ERROR
+ OCI_FO_NONE OCI_FO_SESSION OCI_FO_SELECT OCI_FO_TXNAL
+
=back
=head1 Attributes
Modified: dbd-oracle/branches/TAF/Oracle.xs
==============================================================================
--- dbd-oracle/branches/TAF/Oracle.xs (original)
+++ dbd-oracle/branches/TAF/Oracle.xs Mon Apr 4 09:36:26 2011
@@ -70,6 +70,7 @@
OUTPUT:
RETVAL
+
void
ORA_OCI()
CODE:
@@ -266,6 +267,23 @@
MODULE = DBD::Oracle PACKAGE = DBD::Oracle::db
+void
+ora_can_taf(dbh)
+ SV *dbh
+ PREINIT:
+ D_imp_dbh(dbh);
+ sword status;
+ ub4 can_taf = 0;
+ CODE:
+ OCIAttrGet_log_stat(imp_dbh->srvhp, OCI_HTYPE_SERVER, &can_taf, NULL,
+ OCI_ATTR_TAF_ENABLED, imp_dbh->errhp, status);
+ if (status != OCI_SUCCESS) {
+ oci_error(dbh, imp_dbh->errhp, status, "OCIAttrGet OCI_ATTR_TAF_ENABLED");
+ XSRETURN_IV(0);
+ }
+ else {
+ XSRETURN_IV(can_taf);
+ }
void
ora_ping(dbh)
Modified: dbd-oracle/branches/TAF/dbdimp.c
==============================================================================
--- dbd-oracle/branches/TAF/dbdimp.c (original)
+++ dbd-oracle/branches/TAF/dbdimp.c Mon Apr 4 09:36:26 2011
@@ -1061,11 +1061,11 @@
if (imp_dbh->using_taf){
bool can_taf;
- OCIAttrGet_log_stat(imp_dbh->srvhp, OCI_HTYPE_SERVER, &can_taf, NULL,
+ OCIAttrGet_log_stat(imp_dbh->srvhp, OCI_HTYPE_SERVER, &can_taf, NULL,
OCI_ATTR_TAF_ENABLED, imp_dbh->errhp, status);
if (!can_taf){
- croak("You are attempting to enable TAF on a server that is not TAF Enabled \n");
+ croak("You are attempting to enable TAF on a server that is not TAF Enabled \n");
}
if (DBIS->debug >= 4 || dbd_verbose >= 4 ) {
@@ -1244,6 +1244,15 @@
goto dbd_db_destroy_out;
if (!imp_dbh->proc_handles) {
sword status;
+ if (imp_dbh->using_taf){
+ OCIFocbkStruct tafailover;
+ tafailover.fo_ctx = NULL;
+ tafailover.callback_function = NULL;
+ OCIAttrSet_log_stat(imp_dbh->srvhp, (ub4) OCI_HTYPE_SERVER,
+ (dvoid *) &tafailover, (ub4) 0,
+ (ub4) OCI_ATTR_FOCBK, imp_dbh->errhp, status);
+
+ }
#ifdef ORA_OCI_112
if (imp_dbh->using_drcp) {
OCIHandleFree_log_stat(imp_dbh->authp, OCI_HTYPE_SESSION,status);
Modified: dbd-oracle/branches/TAF/dbdimp.h
==============================================================================
--- dbd-oracle/branches/TAF/dbdimp.h (original)
+++ dbd-oracle/branches/TAF/dbdimp.h Mon Apr 4 09:36:26 2011
@@ -60,7 +60,7 @@
char *driver_name;/*driver name user defined*/
ub4 driver_namel;
#endif
-/* taf_callback_t *taf_callback;*/
+ taf_callback_t *taf_callback;
bool using_taf; /*TAF stuff*/
char *taf_function; /*User supplied TAF functiomn*/
int taf_sleep;
Modified: dbd-oracle/branches/TAF/oci8.c
==============================================================================
--- dbd-oracle/branches/TAF/oci8.c (original)
+++ dbd-oracle/branches/TAF/oci8.c Mon Apr 4 09:36:26 2011
@@ -1323,11 +1323,6 @@
XPUSHs(sv_2mortal(newSViv(fo_event)));
XPUSHs(sv_2mortal(newSViv(fo_type)));
PUTBACK;
-
- PerlIO_printf(DBILOGFP, "taf_cbk mp_drh=%p\n",cb);
-PerlIO_printf(DBILOGFP, "taf_cbk ora_taf_function=%s\n",cb->function);
-
-PerlIO_printf(DBILOGFP, " taf_sleep=%d\n",cb->sleep);
call_pv(cb->function, G_DISCARD);
switch (fo_event){
@@ -1362,24 +1357,22 @@
OCIFocbkStruct tafailover;
sword status;
taf_callback_t *cb = NULL;
+/*allocate space for the callback */
Newz(1, cb, 1, taf_callback_t);
cb->function= (char*)safemalloc(strlen(imp_dbh->taf_function));
cb->sleep = imp_dbh->taf_sleep;
strcpy((char *)cb->function,imp_dbh->taf_function);
- if (dbd_verbose >= 5 ) {
- PerlIO_printf(DBILOGFP, " In reg_taf_callback\n");
+ if (dbd_verbose >= 5 ) {
+ PerlIO_printf(DBILOGFP, " In reg_taf_callback perl callback is %s\n",imp_dbh->taf_function);
}
+ imp_dbh->taf_callback = cb;
-/* set the context up as a pointer to the handle*/
-PerlIO_printf(DBILOGFP, " sizeof(imp_dbh)=%d\n",strlen(imp_dbh->taf_function));
-
+/* set the context up as a pointer to the taf callback struct*/
tafailover.fo_ctx = cb;
-
tafailover.callback_function = &taf_cbk;
-PerlIO_printf(DBILOGFP, " reg_taf_callback=%s\n",cb->function);
-PerlIO_printf(DBILOGFP, " reg_taf_callback=%p\n",imp_dbh);
+/* register the callback */
OCIAttrSet_log_stat(imp_dbh->srvhp, (ub4) OCI_HTYPE_SERVER,
(dvoid *) &tafailover, (ub4) 0,
(ub4) OCI_ATTR_FOCBK, imp_dbh->errhp, status);