You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl@perl.apache.org by Jonathan Vanasco <mo...@2xlp.com> on 2006/03/19 21:13:25 UTC
DBD:Pg (Postgres) + Apache::DBI
I'm finishing up my migration to Postgres, and i noticed some odd
behavior
I was hoping that someone could point me in the right direction:
a - i often lose a connection to the server for an apache child. i
can't seem to trace when where or why this happens
i just get this in the log "DBD::Pg::st execute failed: no
connection to the server"
the other children are unaffected. i'm wondering if this is a ping
error, postgres shutting things down from too many invalid queries
(i'm still on my dev box) , or something else
b- several times a handle seems to have been corrupted. usually it
seems to happen with a failed sequence operation ( adding a new
record or retreiving a value )
when this happens, the handle seems to not be reset by the cleanup
handler ( ie - the automagic Apache::DBI issued rollback ). i have
to restart the server to clean the handle
has this happened to anyone else?
c- i was getting a bunch of "message type 0x49 arrived from server
while idle" -> "message type 0x53 arrived from server while idle"
looking on the net, i wasn't able to find much about it. a lot of
people had the issue on the perl DB lists, the Postgres lists, but
there was no mention of what caused it.
Then I finally came across somethig from the bricolage changelog:
http://bricolage.sourceforge.net/docs/Bric/Changes.html
Removed queries added in 1.7.2 that were running at Bricolage
startup time. They could cause DBI to cache a database handle and
return it after Apache forks, leading to strange errors such as
``message type 0x49 arrived from server while idle'', and
occaisionally a frozen server. [David]
It turns out that I had a handle that was cached by accident ( i
hadn't made a config only user yet, and the config handle was
connecting with the same params as my writing handle). Chances are ,
thats probably the issue. But does anyone know if there is a
definitive cause for this?
Thanks.
Jonathan
Re: DBD:Pg (Postgres) + Apache::DBI
Posted by Jonathan Vanasco <jo...@2xlp.com>.
On Mar 20, 2006, at 5:48 PM, Perrin Harkins wrote:
> Here's my guess -- are you calling you DBI->connect() on every
> request?
yep.
> If this is all making you annoyed with Apache::DBI, just make your own
> cleanup handler that does a rollback. It's easy to do, as long as you
> have a simple way to get the database handle.
well, i already have a cleanup handler that does some stuff with my
db handle , so i'll just stuck a rollback in there. problem solved.
and in solving it, I also found the issue. and ( of course ) it was
entirely my fault .
i connect as AutoCommit = 0 so I get the rollback
then i have a db abstraction level that flips AutoCommit to 1 (shown
below) and replaces the begin_work / rollback / commit -- because I
need to explicitly declare those commands
i *think* a bad error trap missed the rollback, which would have
flipped my autocommit.
anyways, thanks a ton. this was killing me. i've been porting 160+
tables of a mysql-centric db layout to postgres, and having to redo a
significant amount of sql statements to standard sql language. so my
db handles were corrupting nonstop.
eval
{
$db->{'dbh'}->do($SQL) or die "Can not insert";
};
if ( $@ )
{
$self->set_error( "Error: $@" )
$db-> _dbwriter_endwork_rollback();
}
sub _dbwriter_beginwork
{
eval
{
$_[0]->{'DBH'}{AutoCommit} = 1;
$_[0]->{'DBH'}->begin_work;
};
if ( $@ )
{
return 0;
}
return 1;
}
sub _dbwriter_endwork_rollback
{
$_[0]->{'DBH'}->rollback;
$_[0]->{'DBH'}{AutoCommit} = 0;
}
sub _dbwriter_endwork_commit
{
$_[0]->{'DBH'}->commit;
$_[0]->{'DBH'}{AutoCommit} = 0;
}
Re: DBD:Pg (Postgres) + Apache::DBI
Posted by Perrin Harkins <pe...@elem.com>.
On Mon, 2006-03-20 at 17:29 -0500, Jonathan Vanasco wrote:
> I'm not even seeing an explicit rollback on the good handle, which
> makes me think something odd happened on my config
Here's my guess -- are you calling you DBI->connect() on every request?
If you don't, Apache::DBI won't work. I've seen people put their $dbh
in a global or closure, not realizing that they have to call
DBI->connect at least once at the beginning of the request to trigger
Apache::DBI.
If this is all making you annoyed with Apache::DBI, just make your own
cleanup handler that does a rollback. It's easy to do, as long as you
have a simple way to get the database handle.
- Perrin
Re: DBD:Pg (Postgres) + Apache::DBI
Posted by Jonathan Vanasco <jo...@2xlp.com>.
On Mar 20, 2006, at 3:50 PM, Perrin Harkins wrote:
> It only does that if you connect with AutoCommit off.
my connect args are
{ RaiseError => 0, AutoCommit => 0 , TraceLevel => 1 }
> Can you give an example of an invalid SQL command, and what was "bad"
> about the cached handle on the next page?
Something like:
SELECT id_field AS validated FROM id_table WHERE id_field = ''; #
where id_field is a int column
Gives me this
DBD::Pg::db do failed: ERROR: invalid input syntax for integer: ""
DBD::Pg::st execute failed: ERROR: current transaction is aborted,
commands ignored until end of transaction block
which makes sense. but all pages that child requests in the future
are met with this:
DBD::Pg::st execute failed: ERROR: current transaction is aborted,
commands ignored until end of transaction block
I'm pretty sure its because I'm catching the error before I issue a
rollback (my fault).
But I was counting on the DBI rollback
Other invalid sql commands that trigger this are " SELECT
column__does_not_exist FROM table__does_not_exist "
> Also, set $Apache::DBI::DEBUG = 2 and it will tell you if it ran a
Thanks. I just tried that.
On a good handle, I get
24572 Apache::DBI need ping: yes
<- ping= 1 at DBI.pm line 135
24572 Apache::DBI already connected to
'dbname=DBNAMEdbuserDBPASSAutoCommit=0PrintError=1RaiseError=0TraceLevel
=1Username=DBUSER'
<- STORE('RaiseError' 0)= 1 at DBI.pm line 664
<- STORE('PrintError' 1)= 1 at DBI.pm line 664
<- STORE('AutoCommit' 0)= 1 at DBI.pm line 664
<- STORE('TraceLevel' 1)= 1 at DBI.pm line 667
<> FETCH('TraceLevel')= 1 ('TraceLevel' from cache) at DBI.pm
line 667
<- STORE('Username' 'DBUSER')= 1 at DBI.pm line 667
<> FETCH('Username')= 'DBUSER' ('Username' from cache) at DBI.pm
line 667
Once a handle is corrupted, I see
24572 Apache::DBI disconnect (overloaded)
I'm not even seeing an explicit rollback on the good handle, which
makes me think something odd happened on my config ( i remember with
mysql, it would send an "AutoCommit = 1 ; AutoCommit = 0;" to handle
the rollback
Re: DBD:Pg (Postgres) + Apache::DBI
Posted by Perrin Harkins <pe...@elem.com>.
On Mon, 2006-03-20 at 15:22 -0500, Jonathan Vanasco wrote:
> I did a bunch of tracing this morning it seems that apache::dbi isn't
> always issuing the rollback at cleanup
It only does that if you connect with AutoCommit off.
> if there's an invalid sql command executed in my transaction though,
> ==============CLEANUP
>
> is all i get. no cleanup is issued (rollback/closure/etc) on the
> dbi, and i'm still using a bad cached handle on subsequent page
> views , necessitating a page start.
Can you give an example of an invalid SQL command, and what was "bad"
about the cached handle on the next page?
Also, set $Apache::DBI::DEBUG = 2 and it will tell you if it ran a
cleanup or not.
- Perrin
Re: DBD:Pg (Postgres) + Apache::DBI
Posted by Jonathan Vanasco <jo...@2xlp.com>.
a) i fixed the 'message xxxx' errors - they were indeed from an
accidentally preforked handle. i'll try to make a note or something
for apache docs this evening.
b)
I did a bunch of tracing this morning it seems that apache::dbi isn't
always issuing the rollback at cleanup
I set a trace level on my dbi arg, and have a handler print a marker
for the cleanup phase
the bulk of time I get something like this:
==============CLEANUP DBI::db=HASH(0x1a2c918) trace level set to
0x0/1 (DBI @ 0x0/0) in DBI 1.50-ithread (pid 24285)
<> FETCH('TraceLevel')= 1 ('TraceLevel' from cache) at DBI.pm
line 667
<- STORE('Username' 'XXXXX')= 1 at DBI.pm line 667
<> FETCH('Username')= 'XXXXX' ('Username' from cache) at DBI.pm
line 667
<- STORE('dbi_connect_closure' CODE(0x1a2be3c))= 1 at DBI.pm
line 683
if there's an invalid sql command executed in my transaction though,
==============CLEANUP
is all i get. no cleanup is issued (rollback/closure/etc) on the
dbi, and i'm still using a bad cached handle on subsequent page
views , necessitating a page start.
the above arguments were with a TraceLevel1 - i also did a TraceLevel
15, and saw no additional commands executed.
anyone have a suggestion on where I can look next?
Re: DBD:Pg (Postgres) + Apache::DBI
Posted by Greg Sabino Mullane <gr...@turnstep.com>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
> c- i was getting a bunch of "message type 0x49 arrived from server
> while idle" -> "message type 0x53 arrived from server while idle"
This is due to some errant forking. PostgreSQL (and most other databases
for that matter) does not support forking and then trying to talk to
two clients at once. One of those clients sends something, and the other
one notices the response and basically says "Hey! You talkin' to me?!?"
You are most likely connecting too early. This also explains the other errors
you are seeing. Make sure you use the latest version of DBD::Pg as well,
as some other obscure forking-related problems were recently fixed.
- --
Greg Sabino Mullane greg@turnstep.com
PGP Key: 0x14964AC8 200603191601
http://biglumber.com/x/web?pk=2529DF6AB8F79407E94445B4BC9B906714964AC8
-----BEGIN PGP SIGNATURE-----
iD8DBQFEHcdOvJuQZxSWSsgRAobzAJ9eThLlKi3esmLZcS52TZF5lsycjACdFZNY
Hngofu5QKVcU7k4XspLPsQY=
=raOP
-----END PGP SIGNATURE-----