PEPPLER.ORG
Michael Peppler
Sybase Consulting
Menu
Home
Sybase on Linux
Install Guide for Sybase on Linux
General Sybase Resources
General Perl Resources
Freeware
Sybperl
Sybase::Simple
DBD::Sybase
BCP Tool
Bug Tracker
Mailing List Archive
Downloads Directory
FAQs
Sybase on Linux FAQ
Sybperl FAQ
Personal
Michael Peppler's resume

sybperl-l Archive

Up    Prev    Next    

From: michael dot x dot peppler at jpmchase dot com
Subject: Re: sybperl occasionally causes script to 'die' when cancelling a query
Date: Jun 5 2008 10:18AM

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) {



      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




andrew.x.dear@jpmchase.com 
Sent by: owner-sybperl-l@peppler.org
05.06.2008 11:55

To
sybperl-l@peppler.org
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.