oddmedley has asked for the wisdom of the Perl Monks concerning the following question:

Hello!

my first post :) The challange I have is getting recv (in IO::Socket) to not hang.

I send a query (a SELECT) to mysql (5.0.22) through the NET::MySql module and it hangs where the table is empty. Specifically it hangs on the 2nd call to recv on the line

${*$sock}{'io_socket_peername'} = recv($sock, $_[1]='', $len, $flags);

I can't get the debuger to step into this line, it just hangs. I've tried different timeouts and specifying non-blocking. With a non-blocking socket, whatever the timeout, server authentication always fails immediately, claiming a timeout. (I've checked the socket timeout value in debuging mode and it is as I set it) With blocking, the call to recv always hangs on the 2nd call for a select from an empty table. The result of the 1st call to recv seems reasonable, looking pretty similar to what is returned on the 1st call for a query on a non-empty table, so I don't know what is causing the problem and it's driving me up the wall and I really need to fix it :)

I'd be very grateful if anyone could point me in the right direction to solving this!

Replies are listed 'Best First'.
Re: sockets mysql and recv
by grep (Monsignor) on Dec 02, 2006 at 19:42 UTC
    This is a Known Bug with Net::MySQL.

    But the bigger question is why you are not using DBI and DBD::mysql? Those are time-tested, solid, and often recommended modules for MySQL work.

    grep
    XP matters not. Look at me. Judge me by my XP, do you?

      Indeed. Not using DBD::mysql because it doesn't compile on my system. If I can't fix it, I may resort to installing mysql from source and then trying DBD::mysql again...
        What problems do you have compiling DBD::mysql? I'm quite sure one of us can help you resolve them.

        grep
        XP matters not. Look at me. Judge me by my XP, do you?

Re: sockets mysql and recv
by oddmedley (Novice) on Dec 04, 2006 at 02:50 UTC
    Right... My earlier (in hindsight rather foolish) 'fix' for NET::MySQL didn't work :) A better solution would be to check whether the size of the packet is less than BUFFER_LENGTH (rather than the arbitrary 512 bytes as before) and if so not call recv again (in _get_record_by_serve). However I don't know if the buffer is always garanteed to be full where more data is yet to come. Another fix which I'm using at the moment is, since the last five bytes of the packet always seem to be "\xfe\0\0\x02\x00" for SELECT queries on empty tables, to change the funtion 'sub _has_next_packet' in MySQL.pm to this:

    sub _has_next_packet { my $self = shift; return substr($_[0], -5) !~ qr/(\xfe\0\0\x22\x00|\xfe\0\0\x02\x00) +/; }


    My worry with this fix is that "\xfe\0\0\x02\x00" might on very rare occations be valid table data at the end of the packet... It would be nice to find a mysql doc with what all the end codes actually mean, so I can be 100% sure this is a safe fix..., but I've tried the above on my database and it works beautifully (for now) :)