in reply to mysql, locked databases, Apache::DBI and mod_perl

Debuggers are nice, but they aren't always the solution. What usually works for me is to take stuff out until the bug goes away. Then you know where it is and you can make a tiny example and post it here.

Locking can be very dangerous with Apache::DBI. If you lock tables, make sure you add cleanup handlers that unlock them. Otherwise, your code could die in the middle and leave a table locked.

Something that often helps with "random" bugs is to run in -X mode so that you hit the same process each time. Also, as I mentioned in your other post, try using TCP instead of local sockets. I know it's voodoo, but more people run it that way so it has been better debugged.

  • Comment on Re: mysql, locked databases, Apache::DBI and mod_perl

Replies are listed 'Best First'.
Re: Re: mysql, locked databases, Apache::DBI and mod_perl
by Flame (Deacon) on May 19, 2003 at 05:10 UTC
    Hmm, I'll try -X and see if it helps. As for the locked tables, that code was commented out and the system was restarted so the locks should no longer be affecting the situation, however while on the subject, if I have one database handle for my database in my program, if I try to create a new one under Apache::DBI to the same database, will I have two handles to the same connection, or two connections?



    My code doesn't have bugs, it just develops random features.

    Flame ~ Lead Programmer: GMS (DOWN) | GMS (DOWN)

      Assuming the connection parameters are identical, you will just get the exact same handle back.
        Under mod_perl then, if I were to lock a table and have another process running at the same time, both using Apache::DBI and the same parameters, wouldn't it think of both processes as identical and thus complain when one tries to use tables that weren't locked by the other, and when one locks tables, wouldn't it undo the previous locks? I'm beginning to question the practicality of Apache::DBI in this context... perhaps I should do file locking on files named after the tables.



        My code doesn't have bugs, it just develops random features.

        Flame ~ Lead Programmer: GMS (DOWN) | GMS (DOWN)

Re: Re: mysql, locked databases, Apache::DBI and mod_perl
by Flame (Deacon) on May 20, 2003 at 03:39 UTC
    Ok, I've managed to narrow it down using a series of warn() statements represented by &pdebugger; in the following code, in combination with -X. From the top of the file, to where the problem occurs, and a little more:
    #!/usr/bin/perl use DBI; use Date::Calc qw(Days_in_Month Day_of_Week Today Decode_Day_of_Week T +his_Year check_date Day_of_Year Delta_Days Month_to_Text); use CGI::Util qw(escape); use HTML::Entities qw(encode_entities); use Data::Dumper; use Digest::MD5 'md5_base64'; use Data::Page; #To simplify paging logic use HTML::CalendarMonthSimple; use Apache::Request; use Apache::Cookie; use Tie::IxHash; use Apache::Session::MySQL; #use Date::Format; use Parse::RecDescent; #use IO::File; use strict; #This can be declared here because it never changes our %months; tie(%months,'Tie::IxHash'); %months = qw(9 September 10 October 11 November 12 December 1 January +2 February 3 March 4 April 5 May 6 June); #Filters for fields used in each mode TO BE REDONE our @newfields = ('type','title',qr/^new\d+(?:day|month)$/,qr/^[se]t\d ++(?:-\d+)?$/,qr/^newtype\d+(?:-\d+)?$/,'newspec',qr/^keepday\d+$/,qr/ +^desc\d+(?:-\d+)?$/,'expire',qr/^apm[se]\d+(?:-\d+)?$/,qr/codeblock\d ++/,'cmd','fields',qr/^newexp(?:day|month$)/); our @browsefields = ('cid'); our $timeparse = qr/^0?([12]?\d):(\d+):00$/; #Initialize the state, this will be passed to all subs my $state = {}; &pdebugger; #Scope all processing that sets variables { #Get the Apache::Request object my $r = new Apache::Request(shift); my $cookie = new Apache::Cookie($r, -name => 'MY_SESSION_ID', -path => '/', ); my %cookies = $cookie->parse; my $DBH = DBI->connect('dbi:mysql:schedule;host=localhost','root',' +',{RaiseError => 1}); &pdebugger; { #Used to demonstrate that mysql itself can still communicate my $sth = $DBH->prepare("SELECT * from users"); $sth->execute; warn(Dumper($sth->fetchall_arrayref)); } #Session code adapted from: # Apache::Session docs # HTML::Mason samples # code available at http://www.masonhq.com/user/adpacifico/Apache +SessionMason.html my %session; &pdebugger; eval { tie %session, 'Apache::Session::MySQL', ($cookies{'MY_SESSION_ID'} ? $cookies{'MY_SESSION_ID'}->value +() : undef), { Handle => $DBH, LockHandle => $DBH }; }; &pdebugger; # If we could not re-establish an existing, $@ should contain # 'Object does not exist in the data store'. If the eval # failed for a different reason, that might be important if ($@) { if ($@ =~ m#^Object does not exist in the data store#) { #this will create a new session entry tie %session, 'Apache::Session::MySQL', undef, { Handle => $DBH, LockHandle => $DBH }; undef $cookies{'MY_SESSION_ID'}; } else { #place message in server log warn $@; } } &pdebugger; $cookie->value( $session{'_session_id'} ); $cookie->bake; #Add to header queue &pdebugger; $r->send_http_header('text/html'); &pdebugger; # Timestamp the session hash to ensure Apache::Session writes # out the data store The reason for this is that # Apache::Session only does a shallow check for changes in # %session. If %session contains references to objects whose # attributes have changed, those changes won't be recorded. So # adding a 'timestamp' key with a value that changes every # request ensures that all data structures are stored to disk. $session{'timestamp'}=localtime; #End session establishing code #End localization block, place everything needed into the state #Prepare to release tables later #$state->{'ulock'} = $DBH->prepare('UNLOCK TABLES'); $state->{'r'} = $r; $state->{'session'} = \%session; $state->{'DBH'} = $DBH; } &pdebugger;

    The first time through, everything runs fine, however, on the second attempt, things go wrong. I've traced it down to the first session declarations, repeated here:

    #Session code adapted from: # Apache::Session docs # HTML::Mason samples # code available at http://www.masonhq.com/user/adpacifico/Apache +SessionMason.html my %session; &pdebugger; eval { tie %session, 'Apache::Session::MySQL', ($cookies{'MY_SESSION_ID'} ? $cookies{'MY_SESSION_ID'}->value +() : undef), { Handle => $DBH, LockHandle => $DBH }; }; &pdebugger;

    The first &pdebugger; in this section is on line 64, the last one to print on the second run (reliably gets this far and no farther). I've concluded the problem must lie in Apache::Session somewhere, but I am at a loss to even guess where aside from the unique id generating methods or their locking mechanism. I'm not quite sure what I should attempt at this point, should I edit the actual files and see if I can find the problem, or is the problem in my use of Apache::Session? Well... at least I'm gaining some ground.



    My code doesn't have bugs, it just develops random features.

    Flame ~ Lead Programmer: GMS (DOWN) | GMS (DOWN)

      Can you give more explanation of "things go wrong"? What happens, exactly? Does it hang? Do you get error messages?
        As I said before, it just stops, like it got itself stuck in a loop.



        My code doesn't have bugs, it just develops random features.

        Flame ~ Lead Programmer: GMS (DOWN) | GMS (DOWN)