You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl@perl.apache.org by "Dustin D." <du...@gmail.com> on 2007/07/22 17:38:19 UTC

Can't call method "prepare" on an undefined value

I'm having countless problems with mod_perl and not even sure where to
start.  I thought I had mod_perl up and running in my development
environment, so I pushed the new changes + apache configuration out to my
production environment, and immediately began tail -f on the logs.

What I noticed was, most of the time, everything was working fine.  But it
seemed like every few minutes, there would be a burst of the following
errors:

Can't call method "prepare" on an undefined value at modules//MySQLBroker.pm
line 1059.\n

What's strange is, when this error would pop up, it would flood 5-10 errors
like this in a row, all within the span of a few seconds.  Then things would
return to normal and I wouldn't get any errors for awhile.

On my site, I'm getting hits every couple of seconds, if not more
frequently.  In my startup.pl, I have something like this to initialize the
MySQL connection:

Apache::DBI->connect_on_init("DBI:mysql:mydb:127.0.0.1", "dustin", "mypass",
    {
     PrintError => 1, # warn( ) on errors
     RaiseError => 0, # don't die on error
     AutoCommit => 1, # commit executes immediately
    }
);

(NOTE: for the hostname, I was using localhost for awhile, and decided to
use a direct ip in case localhost is actually being resolved, to get rid of
one more layer of translation)

My code around line 1059 in MySQLBroker.pm looks like this:

sub _mysql_exec {
  my ($self, $dbcall) = @_;
  my @resultsArray;
  my $count=0;
  my $sth = $self->{_dbh}->prepare("$dbcall");
  $sth->execute or die "Cannot execute database command!";
  while (my @array = $sth->fetchrow) {
    push @resultsArray, \@array;
  }
  $sth->finish;
  return \@resultsArray;
}

Also, on a fairly inconsistent basis, I'm also getting "not a CODE
reference" errors.

To me, it just seems like mod_perl is very unreliable and unpredictable.
The same code that worked reliably (albeit slow) in the CGI world is now
extremely unpredictable in the mod_perl world.

FYI, I'm aware of the persistent state issues in a mod_perl world and have
gone to great lengths to debug any persistent state issues that might be
affecting things.

At this point in time, I'm extremely tempted to rewrite everything in PHP.
I really want to avoid that, but mod_perl is causing me too many headaches
to justify it, as I've already wasted a week of effort trying to migrate my
site from CGI to mod_perl.

Thanks,
Dustin

Re: Can't call method "prepare" on an undefined value

Posted by Foo JH <jh...@extracktor.com>.
Does this happen during idle period? MySQL does disconnect when the idle 
is too long.

Dustin D. wrote:
> I'm having countless problems with mod_perl and not even sure where to 
> start.  I thought I had mod_perl up and running in my development 
> environment, so I pushed the new changes + apache configuration out to 
> my production environment, and immediately began tail -f on the logs.
>
> What I noticed was, most of the time, everything was working fine.  
> But it seemed like every few minutes, there would be a burst of the 
> following errors:
>
> Can't call method "prepare" on an undefined value at 
> modules//MySQLBroker.pm line 1059.\n
>
> What's strange is, when this error would pop up, it would flood 5-10 
> errors like this in a row, all within the span of a few seconds.  Then 
> things would return to normal and I wouldn't get any errors for awhile.
>
> On my site, I'm getting hits every couple of seconds, if not more 
> frequently.  In my startup.pl, I have something like this to 
> initialize the MySQL connection:
>
> Apache::DBI->connect_on_init("DBI:mysql:mydb: 127.0.0.1 
> <http://127.0.0.1>", "dustin", "mypass",
>     {
>      PrintError => 1, # warn( ) on errors
>      RaiseError => 0, # don't die on error
>      AutoCommit => 1, # commit executes immediately
>     }
> );
>
> (NOTE: for the hostname, I was using localhost for awhile, and decided 
> to use a direct ip in case localhost is actually being resolved, to 
> get rid of one more layer of translation)
>
> My code around line 1059 in MySQLBroker.pm looks like this:
>
> sub _mysql_exec {
>   my ($self, $dbcall) = @_;
>   my @resultsArray;
>   my $count=0;
>   my $sth = $self->{_dbh}->prepare("$dbcall");
>   $sth->execute or die "Cannot execute database command!";
>   while (my @array = $sth->fetchrow) {
>     push @resultsArray, \@array;
>   }
>   $sth->finish;
>   return \@resultsArray;
> }
>
> Also, on a fairly inconsistent basis, I'm also getting "not a CODE 
> reference" errors.
>
> To me, it just seems like mod_perl is very unreliable and 
> unpredictable.  The same code that worked reliably (albeit slow) in 
> the CGI world is now extremely unpredictable in the mod_perl world.
>
> FYI, I'm aware of the persistent state issues in a mod_perl world and 
> have gone to great lengths to debug any persistent state issues that 
> might be affecting things.
>
> At this point in time, I'm extremely tempted to rewrite everything in 
> PHP.  I really want to avoid that, but mod_perl is causing me too many 
> headaches to justify it, as I've already wasted a week of effort 
> trying to migrate my site from CGI to mod_perl.
>
> Thanks,
> Dustin


Re: Can't call method "prepare" on an undefined value

Posted by Dondi Stroma <ds...@verizon.net>.
Where is your DBI "connect" method? Do you have error checking in place in 
case the connect fails?  If the connect fails, your database handle will be 
undef.

Try adding

or die DBI->errstr;

to your connect method as well as the prepare on line 1059.

----- Original Message ----- 
From: Dustin D.
To: modperl@perl.apache.org
Sent: Sunday, July 22, 2007 11:38 AM
Subject: Can't call method "prepare" on an undefined value


I'm having countless problems with mod_perl and not even sure where to 
start.  I thought I had mod_perl up and running in my development 
environment, so I pushed the new changes + apache configuration out to my 
production environment, and immediately began tail -f on the logs.

What I noticed was, most of the time, everything was working fine.  But it 
seemed like every few minutes, there would be a burst of the following 
errors:

Can't call method "prepare" on an undefined value at modules//MySQLBroker.pm 
line 1059.\n


Re: Can't call method "prepare" on an undefined value

Posted by Kevin Field <ke...@brantaero.com>.
> > My code around line 1059 in MySQLBroker.pm looks like this:
> >
> > sub _mysql_exec {
> >   my ($self, $dbcall) = @_;
> >   my @resultsArray;
> >   my $count=0;
> >   my $sth = $self->{_dbh}->prepare("$dbcall");
> 
> You shouldn't store a $dbh in your objects like this.  Apache::DBI
> will check that your connection is still good when you try to use it,
> but only if you call connect().  If you don't, your connection can go
> stale and get dropped.

Aside from that, a general trick that seems to help sometimes is 
changing "my" to "local our".  But I believe Perrin is right, you 
should have your scripts call connect() at their beginnings, and 
Apache::DBI will do the caching for you.

Kev

Re: Can't call method "prepare" on an undefined value

Posted by Perrin Harkins <pe...@elem.com>.
On 7/22/07, Dustin D. <du...@gmail.com> wrote:
> I thought I had mod_perl up and running in my development
> environment, so I pushed the new changes + apache configuration out to my
> production environment, and immediately began tail -f on the logs.
>
> What I noticed was, most of the time, everything was working fine.  But it
> seemed like every few minutes, there would be a burst of the following
> errors:
>
> Can't call method "prepare" on an undefined value at modules//MySQLBroker.pm
> line 1059.\n

Did you see these in your development environment?  How did you make
the code live?  Did you restart the server or did you use something
like Apache::Reload?

> What's strange is, when this error would pop up, it would flood 5-10 errors
> like this in a row, all within the span of a few seconds.  Then things would
> return to normal and I wouldn't get any errors for awhile.

It sounds like your MySQL server is dropping the connections, or else
you have multiple processes sharing a connection.  Do you do anything
during the startup (in httpd.conf or called from httpd.conf) that
opens database connections?

> (NOTE: for the hostname, I was using localhost for awhile, and decided to
> use a direct ip in case localhost is actually being resolved, to get rid of
> one more layer of translation)

Ironically, you actually made it slower there.  If you specify
'localhost' or empty string for the server, it will connect using Unix
domain sockets instead of TCP.  This is a significant performance
improvement for simple queries.  See the DBD::mysql dcos for more
info.

> My code around line 1059 in MySQLBroker.pm looks like this:
>
> sub _mysql_exec {
>   my ($self, $dbcall) = @_;
>   my @resultsArray;
>   my $count=0;
>   my $sth = $self->{_dbh}->prepare("$dbcall");

You shouldn't store a $dbh in your objects like this.  Apache::DBI
will check that your connection is still good when you try to use it,
but only if you call connect().  If you don't, your connection can go
stale and get dropped.

> Also, on a fairly inconsistent basis, I'm also getting "not a CODE
> reference" errors.

Which part of the code gives you that?

> To me, it just seems like mod_perl is very unreliable and unpredictable.
> The same code that worked reliably (albeit slow) in the CGI world is now
> extremely unpredictable in the mod_perl world.

It's 100% predictable.  You just don't understand how your code works
in a persistent environment yet.  Give yourself a little time before
you throw in the towel.  And ask more questions if you're confused.
No need to wait a week and get frustrated before asking for help.

- Perrin