Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

Handle DBI connection lost

by bash (Scribe)
on Feb 22, 2017 at 19:17 UTC ( [id://1182551]=perlquestion: print w/replies, xml ) Need Help??

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

Hello,
I have script that is connected to PostgreSQL and run 24x7.
Some times we need to restart PostgreSQL or some connection problem can occur, so script is needed to reconnect on this situations.

There are two ways:
1) check connection before every statement execution
2) check connection on errors

I decided to go by way 2, because I don't want to add extra overhead by calling ping() every time we execute statement
So my problem is how to be sure that DBI error is about "connection".
Here is my prototype based on 'Active' attribute and on state() method.
eval { $dbh->do(...); }; if (my $e = $@) { if ($dbh->{Active} != 1 || $dbh->state =~ /08\d{3}/){ # reconnect and retry } else { # not connection related error } }

Is it correct way?
And how to emulate connection lost for testing (maybe fork and close handler from child)?

update 2017-02-23
I emulated connection lost via fork:
unless (fork()) { $dbh->{InactiveDestroy} = 0; exit; } wait();
My observation shows that:
$dbh->{Active} == 1 even if dbh return "DBD::Pg::db selectrow_array failed: no connection to the server".
$dbh->{Active} == '' only if you explicitly call $dbh->disconnect;
But $dbh->state works like expected.

Still interesting in any production experience with robust handling for connection lost.

PS. To be sure that ping is really slow down I performed simple test
sub query { $dbh->selectrow_array(q{ SELECT now() }); } sub ping_and_query { $dbh->selectrow_array(q{ SELECT now() }) if $dbh->ping; } cmpthese(-2, { 'query' => \&query, 'ping+query' => \&ping_and_query, }); --- Rate ping+query query ping+query 6349/s -- -39% query 10327/s 63% --

Replies are listed 'Best First'.
Re: Handle DBI connection lost
by RonW (Parson) on Feb 22, 2017 at 23:24 UTC

    Reconnect and retry is better suited for automatic recovery from a network "glitch" than from a DB server restart.

    According to one of the IT people I know at work, when a DB server needs to be restarted, they notify clients to shutdown their apps, first, then do the DB restart, then notify clients they may restart there apps.

Re: Handle DBI connection lost
by Mr. Muskrat (Canon) on Feb 23, 2017 at 16:04 UTC
      PgBouncer is good advice for server restart. Thank you.
      But it doesn't solve network issues.
Re: Handle DBI connection lost
by Your Mother (Archbishop) on Feb 24, 2017 at 15:46 UTC

    This is what I used to solve an issue with a customer job that takes days to run on installations which have occasional DB restarts (for no good reason but that's another story): DBIx::RetryOverDisconnects.

      Interesting package... especially some "hacks" like dbh-> swap_inner_handle
Re: Handle DBI connection lost
by Anonymous Monk on Feb 22, 2017 at 19:38 UTC
    Restart your script when you restart the database.
      If you have many database requests per second then it's very hard to restart script and database synchronously, especially when you have many instances of this script spread across cluster.
        Still, it does not seem to make sense to let your script continue to run when the database is down.
Re: Handle DBI connection lost
by gsiems (Deacon) on Feb 24, 2017 at 19:14 UTC
      Yep, i've looked at this module. Unfortunately it goes by way 1, i.e. ping'ing server before every request.

        You sure?

        "In fixup mode, DBIx::Connector executes the block without pinging the database. But in the event the block throws an exception, if DBIx::Connector finds that the database handle is no longer connected, it will reconnect to the database and re-execute the block."

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1182551]
Approved by stevieb
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others wandering the Monastery: (5)
As of 2024-04-23 21:33 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found