Re: sybperl occasionally causes script to 'die' when cancelling a query
[email protected] Thu, 5 Jun 2008 12:18:52 +0200
| Newsgroups | gmane.comp.lang.perl.modules.dbi.sybase |
|---|---|
| Message-ID | <OF13BCD0CA.7A62C50A-ONC125745F.00382422-C125745F.0038A7C0@jpmchase.com> |
Hi,
The problem appears to be here (in CTlib.xs)
void
ct_fetch(dbp, doAssoc=0, wantref=0)
SV * dbp
int doAssoc
int wantref
PPCODE:
{
ConInfo *info = get_ConInfo(dbp);
CS_RETCODE retcode;
CS_INT rows_read;
SV *sv;
int i, len;
#if defined(UNDEF_BUG)
int n_null = doAssoc;
#endif
if(debug_level & TRACE_FETCH)
warn("%s->ct_fetch() called in %s context", neatsvpv(dbp,
0),
wantref ? "SCALAR" : "SCALAR");
TryAgain:;
retcode = ct_fetch(info->cmd, CS_UNUSED, CS_UNUSED, CS_UNUSED,
&rows_read);
if(debug_level & TRACE_FETCH)
warn("%s->ct_fetch(%s) == %d", neatsvpv(dbp, 0),
doAssoc ? "TRUE" : "FALSE", retcode);
switch(retcode) {
<snip...>
case CS_FAIL: /* ohmygod */
/* FIXME: Should we call ct_cancel() here, or should we
let
the programmer handle it? */
if(ct_cancel(info->connection->connection, NULL,
CS_CANCEL_ALL) == CS_FAIL)
croak("ct_cancel() failed - dying");
/* FallThrough to next case! */
Where CTlib doesn't know how to recover, so just croaks.
The error trace you show appear to indicate that the connection to the
dataserver is closed at some point in the sequence ("command terminated
due to disconnect"), so you may want to check your server (ASE) error logs
to see if there are any errors there (stack traces, for example).
To handle this case without making any sybperl code changes: wrap the
ct_fetch() call in an eval {} block, and test for errors at the end of the
eval, something like
eval {
$row = $dbh->ct_fetch;
}; warn $@ if $@;
This should let you recover and avoid the exit() call.
Michael
[email protected]
Sent by: [email protected]
05.06.2008 11:55
To
[email protected]
cc
Subject
sybperl occasionally causes script to 'die' when cancelling a query
(Apologies if this appears twice - I did could not see the first send on
the list).
Hi. I have a daemon script which runs sql and sets up a timeout in case
the sql gets stuck due to a problem on the server (usually in the ct_fetch
loop). At that point the msg_cb cancels the query and the rest of the
script should carry on.
Often this works fine, however occasionally the perl script dies - which
is bad news for our daemon script - and it looks like this 'die' is called
from within sybperl. Here are the error messages received by the
msg_handler (where everything has 'Error:' or 'Info:' prepended) and the
final 'die' message (which has nothing prepended and so does not come from
our handlers):
Info: Cancelling query on dbh.
Error: Client Message: 6, Severity 5, Origin 3
Error: ct_fetch(): network packet layer: internal net library error:
Net-Library operation terminated due to disconnect
Error: Client Message: 0, Severity 0, Origin 0
Error: ct_cancel(): unable to get layer message string: unable to get
origin message string: error string not available
ct_cancel() failed - dying at /home/edgdba/bin/spid line 2433.
Looking a little deeper I can see this final message in CTlib.so:
strings CTlib.so | grep cancel
Sybase::CTlib::ct_cancel
ct_cancel() failed - dying
Tested on Perl 5.8.4/Sybperl 2.17 and Perl 5.10.0/Sybperl
2.18
Are there any plans to get rid of this 'die' call in the sybperl library?
Do you know how I can avoid it? (short of calling ct_fetch in an eval,
which - while I haven't tried it - doesn't look too pleasant or correct).
Finally here is the msg_cb code snippet dealing with the timeouts:
sub msg_cb
{
my($layer, $origin, $severity, $number, $msg, $osmsg, $dbh) = @_;
-
-
-
-
# Handle query timeout messages
if ($layer == 1 and $origin == 2 and $number == 63) {
$Total_blocked_secs = 0 unless $Total_blocked_secs;
$Total_blocked_secs += $Sql_timeout;
if (!defined($dbh) or $dbh->DBDEAD()) {
# This is a connection timeout
out("\nInfo: Connection attempt has been blocked
for the last $Total_blocked_secs seconds.\n");
if ( $Total_blocked_secs >= $Max_blocked_secs ) {
# Cancel the connection attempt
out("\nError: Connection attempt blocked
for longer than max allowed time ($Max_blocked_secs secs). Cancelling
connection attempt.\n");
return CS_FAIL;
} else {
return CS_SUCCEED; # Keep trying
}
} else {
# This is a query timeout
our ($Current_sql_section);
out("\nInfo: Spid sql query has been blocked on
the server (processing section $Current_sql_section) for the last
$Total_blocked_secs seconds.\n");
if ( $Total_blocked_secs >= $Max_blocked_secs ) {
# Cancel the query and force a reconnect
out("\nError: Query blocked on server
(processing section $Current_sql_section) for longer than max allowed time
($Max_blocked_secs secs). Cancelling query and reconnecting.\n");
# Use ATTN, not ALL since we're in a
handler
if (defined $dbh ) {
out("\nInfo: Cancelling query on
dbh.\n");
$dbh->ct_cancel(CS_CANCEL_ATTN);
} else {
# We don't always get $dbh, so try
our main connection otherwise
out("\nInfo: Cancelling query on
Con.\n"), $Con->ct_cancel(CS_CANCEL_ATTN) if defined($Con);
}
# Don't actually close the connection here
- let it complete the message and
# this script will reconnect
$Connection_dead = $true;
$Status = "TIMED_OUT";
return CS_SUCCEED;
} else {
return CS_SUCCEED; # Continue for now
}
}
}
Thanks for any help.
Andrew
This communication is for informational purposes only. It is not intended
as an offer or solicitation for the purchase or sale of any financial
instrument or as an official confirmation of any transaction. All market
prices, data and other information are not warranted as to completeness or
accuracy and are subject to change without notice. Any comments or
statements made herein do not necessarily reflect those of JPMorgan Chase
& Co., its subsidiaries and affiliates. This transmission may contain
information that is privileged, confidential, legally privileged, and/or
exempt from disclosure under applicable law. If you are not the intended
recipient, you are hereby notified that any disclosure, copying,
distribution, or use of the information contained herein (including any
reliance thereon) is STRICTLY PROHIBITED. Although this transmission and
any attachments are believed to be free of any virus or other defect that
might affect any computer system into which it is received and opened, it
is the responsibility of the recipient to ensure that it is virus free and
no responsibility is accepted by JPMorgan Chase & Co., its subsidiaries
and affiliates, as applicable, for any loss or damage arising in any way
from its use. If you received this transmission in error, please
immediately contact the sender and destroy the material in its entirety,
whether in electronic or hard copy format. Thank you. Please refer to
http://www.jpmorgan.com/pages/disclosures for disclosures relating to UK
legal entities.
-----------------------------------------
This communication is for informational purposes only. It is not
intended as an offer or solicitation for the purchase or sale of
any financial instrument or as an official confirmation of any
transaction. All market prices, data and other information are not
warranted as to completeness or accuracy and are subject to change
without notice. Any comments or statements made herein do not
necessarily reflect those of JPMorgan Chase & Co., its subsidiaries
and affiliates.
This transmission may contain information that is privileged,
confidential, legally privileged, and/or exempt from disclosure
under applicable law. If you are not the intended recipient, you
are hereby notified that any disclosure, copying, distribution, or
use of the information contained herein (including any reliance
thereon) is STRICTLY PROHIBITED. Although this transmission and any
attachments are believed to be free of any virus or other defect
that might affect any computer system into which it is received and
opened, it is the responsibility of the recipient to ensure that it
is virus free and no responsibility is accepted by JPMorgan Chase &
Co., its subsidiaries and affiliates, as applicable, for any loss
or damage arising in any way from its use. If you received this
transmission in error, please immediately contact the sender and
destroy the material in its entirety, whether in electronic or hard
copy format. Thank you.
Please refer to http://www.jpmorgan.com/pages/disclosures for
disclosures relating to UK legal entities.