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
};