Oracle DBD with 19c - forked child hangs on exit
Tim Wolfe <[email protected]> Tue, 10 May 2022 14:22:30 -0400
| Newsgroups | gmane.comp.lang.perl.modules.dbi.general |
|---|---|
| Message-ID | <CAOzaiSPsBOJ4MGDabxdVvRhanC-28kf-5c6Afg+_3rdWkbrU6Q@mail.gmail.com> |
--000000000000046fdd05deac694d
Content-Type: text/plain; charset="UTF-8"
We just upgraded one of our database servers from Oracle 12.2.0.1 to
19.15.0 and one our perl programs is behaving differently. We are running
with RedHat 8.4 using Perl v5.26.3 and the latest DBD::Oracle and DBI from
cpan.
Under 19c, a forked child hangs on exit if the parent has (or had) an
oracle connection where the connection handle is a global (using 'our').
This does not happen if the connection handle is a local (declared with
'my'). When running against a 12c database, with DBD::Oracle using 12c
libraries, the child process exits normally regardless of how the variable
is 'declared'.
Note also that this issue does not happen if the child exec's another
program.
The block of code below exhibits the issue in our environment. This is just
a simplification. The real code uses packages and so the connection handle
needs to be a global.
Any help appreciated.
use strict;
use warnings;
use DBI;
# If $dbh declared with my, this works witn 19c
# otherwise, exit in child below never returns
our $dbh = DBI->connect('dbi:Oracle:ORCL', 'scott', 'tiger',
{ RaiseError => 1, AutoCommit => 0, PrintError
=> 0, InactiveDestroy => 1 });
print "Connected to db\n";
$dbh->disconnect;
#undef $dbh; # Child process exits normally if this uncommented
my $pid;
$pid = fork;
if( $pid == 0 ) {
print "This is child process\n";
print "Child process exiting now\n";
exit 0; # Never returns if $dbh is a global
}
print "This is parent process and child ID is $pid\n";
print "Parent Waiting on child\n";
my $chldPid = wait;
print "Parent done. Child pid $chldPid has completed\n";
exit 0;
--000000000000046fdd05deac694d
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">
<p>We just upgraded one of our database servers from Oracle 12.2.0.1 to=20
19.15.0 and one our perl programs is behaving differently. We are=20
running with RedHat 8.4 using Perl v5.26.3 and the latest DBD::Oracle=20
and DBI from cpan.</p>
<p>Under 19c, a forked child hangs on exit if the parent has (or had) an
oracle connection where the connection handle is a global (using=20
'our'). This does not happen if the connection handle is a local=20
(declared with 'my'). When running against a 12c database, with=20
DBD::Oracle using 12c libraries, the child process exits normally=20
regardless of how the variable is 'declared'.</p>
<p>Note also that this issue does not happen if the child exec's anothe=
r program.</p>
<p>The block of code below exhibits the issue in our environment. This=20
is just a simplification. The real code uses packages and so the=20
connection handle needs to be a global.</p>
<p>Any help appreciated.</p>
<div><br></div><div>
<pre class=3D"gmail-lang-sql gmail-s-code-block"><code class=3D"gmail-hljs =
gmail-language-sql">use strict;
use warnings;
use DBI;
# If $dbh declared <span class=3D"gmail-hljs-keyword">with</span> my, this =
works witn <span class=3D"gmail-hljs-number">19</span>c
# otherwise, exit <span class=3D"gmail-hljs-keyword">in</span> child below =
never <span class=3D"gmail-hljs-keyword">returns</span>
our $dbh <span class=3D"gmail-hljs-operator">=3D</span> DBI<span class=3D"g=
mail-hljs-operator">-</span><span class=3D"gmail-hljs-operator">></span>=
<span class=3D"gmail-hljs-keyword">connect</span>(<span class=3D"gmail-hljs=
-string">'dbi:Oracle:ORCL'</span>, <span class=3D"gmail-hljs-string=
">'scott'</span>, <span class=3D"gmail-hljs-string">'tiger'=
</span>,
{ RaiseError <span class=3D"gmail-hljs-operator">=3D=
</span><span class=3D"gmail-hljs-operator">></span> <span class=3D"gmail=
-hljs-number">1</span>, AutoCommit <span class=3D"gmail-hljs-operator">=3D<=
/span><span class=3D"gmail-hljs-operator">></span> <span class=3D"gmail-=
hljs-number">0</span>, PrintError <span class=3D"gmail-hljs-operator">=3D</=
span><span class=3D"gmail-hljs-operator">></span> <span class=3D"gmail-h=
ljs-number">0</span>, InactiveDestroy <span class=3D"gmail-hljs-operator">=
=3D</span><span class=3D"gmail-hljs-operator">></span> <span class=3D"gm=
ail-hljs-number">1</span> });
print "Connected to db\n";
$dbh<span class=3D"gmail-hljs-operator">-</span><span class=3D"gmail-hljs-o=
perator">></span><span class=3D"gmail-hljs-keyword">disconnect</span>;
#undef $dbh; # Child process exits normally if this uncommented
my $pid;
$pid <span class=3D"gmail-hljs-operator">=3D</span> fork;
if( $pid <span class=3D"gmail-hljs-operator">=3D</span><span class=3D"gmail=
-hljs-operator">=3D</span> <span class=3D"gmail-hljs-number">0</span> ) {
print "This is child process\n";
print "Child process exiting now\n";
exit <span class=3D"gmail-hljs-number">0</span>; # Never <span clas=
s=3D"gmail-hljs-keyword">returns</span> if $dbh <span class=3D"gmail-hljs-k=
eyword">is</span> a <span class=3D"gmail-hljs-keyword">global</span>
}
print "This is parent process and child ID is $pid\n";
print "Parent Waiting on child\n";
my $chldPid <span class=3D"gmail-hljs-operator">=3D</span> wait;
print "Parent done. Child pid $chldPid has completed\n";
exit <span class=3D"gmail-hljs-number">0</span>;</code></pre>
</div></div>
--000000000000046fdd05deac694d--