perl5-dbi / DBD-MariaDB

Perl MariaDB driver

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

ping after fork

charsbar opened this issue · comments

Hi.

This may or may not be related to #151, but the following test fails with DBD::MariaDB, though it passes with DBD::mysql. Is this an intended change?

use strict;
use warnings;
use Test::More;
use DBI;

ok my $dbh = DBI->connect("dbi:MariaDB:test", $ENV{DB_USER}, $ENV{DB_PASS}, {
    AutoCommit => 1,
    RaiseError => 1,
    PrintError => 0,
    AutoInactiveDestroy => 1,
});

ok $dbh->ping, "ping";

if (my $pid = fork()) {
    exit;
}

ok $dbh->ping, "ping after fork?"; ## failing

done_testing;
commented

Hello @charsbar!

If I'm correct your code does following:

  1. connect to database with AutoInactiveDestroy attribute
  2. create child process

And then in unspecified order even with the option at the same time (on multicore CPU) does following:

  1. child process tries to ping mysql server
  2. parent process checks for InactiveDestroy flag and if is not set then it close connection with mysql server which is shared with child process. InactiveDestroy is not set as it is parent process and therefore is not affected by AutoInactiveDestroy flag.

Because steps 3. and 4. may be done in reverse order, it is fully legal and valid that ping fails as connection would be already closed.

If you swap code in parent and child process then it should always pass (just because AutoInactiveDestroy sets InactiveDestroy in the child process and so child's exit function does not close shared connection with mysql server):

use strict;
use warnings;
use Test::More;
use DBI;

ok my $dbh = DBI->connect("dbi:MariaDB:test", $ENV{DB_USER}, $ENV{DB_PASS}, {
    AutoCommit => 1,
    RaiseError => 1,
    PrintError => 0,
    AutoInactiveDestroy => 1,
});

ok $dbh->ping, "ping";

if (my $pid = fork()) {
    ok $dbh->ping, "ping after fork?"; ## failing
    done_testing;
    exit;
}

exit;

So in my opinion, there is no issue with your code and behavior is correct. You are just hitting race condition if parent process execution is scheduled earlier than child process. It is possible that DBD::mysql cause operating system to do different process scheduling and issue is hit just lower probability.