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;
Hello @charsbar!
If I'm correct your code does following:
- connect to database with AutoInactiveDestroy attribute
- create child process
And then in unspecified order even with the option at the same time (on multicore CPU) does following:
- child process tries to ping mysql server
- 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.