On Tue, 18 Mar 2003, Tim Bunce wrote:

> > 2. When you get a chance, could you send me your column info patch, so
> > that I can apply it before mucking too with the perl code?
> 
> Attached.
> 
Can you resend? I did not seem to get the attachment?

> > Also looking at the auto reconenct, I think I can see why it defaults to
> > on, but for the life of me, I don't understand why this 'fix' was put into
> > the driver instead of telling people to fix their code. Grrr.
> 
> I can. It's a very useful feature for some environments like mod_perl.
> If the database server has been bounced you don't want the next few
> requests (one for each child httpd) to fail.

I try to make my code robust against such things; I ping the db and
reconnect if needed.


> > Anyway, I
> > have a patch to add the mysql_auto_reconnect Attrubite. I left it
> > defaulting to on, however, because of the existing code that depnds on the
> > feature
> 
> Fine. A way to get a count of how many auto reconnects have been
> made would be handy, but not important for me as I'll probably just
> disable it.
> 

I am doing the counts, but as for reporting the stats I was thinking more
something like

%stats = %{$dbh->{mysql_STATS}};

$recn = $stats->{auto_reconnects};

So we don't end up polluting the attributes with statistics if the number
grows.  Thoughts?


> 
> It certainly needs to be made very clear that any use of LOCK TABLE
> or GET_LOCK with DBD::mysql is currently unsafe as the locks can
> be lost without notice.
> 

Well it looks like you will also get the magic reconnect with AutoCommit
off too.  mysql_real_connect() sets mysql.reconnect = 1, so the mysql
libraries will automatically reconnect to the database on execute if
needed??  Since mysql_real_execute() would always work, the DBD::mysql
auto reconnect code was not being exercised (at least against
4.0.11-gamma.)


Rudy

ps. I have attached a first draft ofn the auto_reconnect patch (I want to
do some more testing before I check it into CVS). The patch also fixes a
problem where srings were not being quoted if they had been used in
numeric context before passed to execute().
--- dbdimp.c.brl        Sun Mar 16 16:24:51 2003
+++ dbdimp.c    Wed Mar 19 00:12:11 2003
@@ -155,7 +155,7 @@
            alen += 3;  /* Erase '?', insert 'NULL' */
        } else {
            if (!ph->type) {
-               ph->type = SvNIOK(ph->value) ? SQL_INTEGER : SQL_VARCHAR;
+                   ph->type= SQL_VARCHAR;
            }
            valbuf = SvPV(ph->value, vallen);
            alen += 2*vallen+1; /* Erase '?', insert (possibly quoted)
@@ -621,6 +621,10 @@
     if (imp_dbh) {
       SV* sv = DBIc_IMP_DATA(imp_dbh);
       imp_dbh->has_transactions = TRUE;
+      imp_dbh->auto_reconnect = TRUE; /* Default to TRUE for backwards compat */
+      imp_dbh->stats.auto_reconnects = 0;
+      imp_dbh->stats.failed_auto_reconnects = 0;
+
       DBIc_set(imp_dbh, DBIcf_AutoCommit, &sv_yes);
       if (sv  &&  SvROK(sv)) {
        HV* hv = (HV*) SvRV(sv);
@@ -733,6 +737,11 @@
                                portNr, unixSocket, client_flag);
     if (dbis->debug >= 2)
       PerlIO_printf(DBILOGFP, "imp_dbh->mysql_dr_connect: <-");
+
+    /* we turn off Mysql's auto reconnect and handle re-connecting ourselves
+     * so that we can keep track of when this happens.
+     */
+    sock->reconnect=0;
     return result;
   }
 }
@@ -1047,11 +1056,11 @@
     char *key = SvPV(keysv, kl);
     SV *cachesv = Nullsv;
     int cacheit = FALSE;
+    bool newval = SvTRUE(valuesv);
 
     if (kl==10 && strEQ(key, "AutoCommit")){
       if (imp_dbh->has_transactions) {
         int oldval = DBIc_has(imp_dbh,DBIcf_AutoCommit);
-       int newval = SvTRUE(valuesv);
 
        /* if setting AutoCommit on ... */
        if (newval) {
@@ -1091,6 +1100,12 @@
            croak("Transactions not supported by database");
        }
       }
+    } else if (strlen("mysql_auto_reconnect") 
+                   == kl && strEQ(key,"mysql_auto_reconnect") ) 
+    {
+        /*XXX: Does DBI handle the magic ? */
+       imp_dbh->auto_reconnect = newval;
+       /* imp_dbh->mysql.reconnect=0; */
     } else {
         return FALSE;
     }
@@ -1157,6 +1172,10 @@
   }
 
   switch(*key) {
+   case 'a':
+      if (kl == strlen("auto_reconnect") && strEQ(key, "auto_reconnect"))
+               result = sv_2mortal(newSViv(imp_dbh->auto_reconnect));
+      break;
     case 'e':
       if (strEQ(key, "errno")) {
        result = sv_2mortal(newSViv((IV)mysql_errno(&imp_dbh->mysql)));
@@ -2025,7 +2044,7 @@
     return FALSE;
   }
 
-  if (!DBIc_has(imp_dbh, DBIcf_AutoCommit)) {
+  if (!DBIc_has(imp_dbh, DBIcf_AutoCommit) || !imp_dbh->auto_reconnect) {
     /* We never reconnect if AutoCommit is turned off.
      * Otherwise we might get an inconsistent transaction
      * state.
@@ -2035,7 +2054,10 @@
 
   if (!_MyLogin(imp_dbh)) {
     do_error(h, mysql_errno(&imp_dbh->mysql), mysql_error(&imp_dbh->mysql));
+    ++imp_dbh->stats.failed_auto_reconnects;
     return FALSE;
+  } else {
+    ++imp_dbh->stats.auto_reconnects;
   }
   return TRUE;
 }
--- dbdimp.h.brl        Sun Mar 16 16:55:23 2003
+++ dbdimp.h    Mon Mar 17 00:36:39 2003
@@ -57,7 +57,8 @@
     JW_ERR_SEQUENCE,
     TX_ERR_AUTOCOMMIT,
     TX_ERR_COMMIT,
-    TX_ERR_ROLLBACK
+    TX_ERR_ROLLBACK,
+    JW_ERR_BAD_AUTOCOMMIT_VAL
 };
 
 

Reply via email to