php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #33994 DB unavailable after forked child exits
Submitted: 2005-08-04 08:03 UTC Modified: 2005-08-05 04:27 UTC
From: greatwhitepine at bigfoot dot com Assigned:
Status: Wont fix Package: Ingres II related
PHP Version: 5.0.4 OS: Tru64 UNIX V5.1B (Rev. 2650)
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: greatwhitepine at bigfoot dot com
New email:
PHP Version: OS:

 

 [2005-08-04 08:03 UTC] greatwhitepine at bigfoot dot com
Description:
------------
As per the manual ingres_connect connections are terminated when the process exits.  When a forked child exits the connection is terminated permanently until the parent process is restarted.

Reproduce code:
---------------
ingres_connect($str_database, $str_username, $str_password);
if (ingres_query('select count(*) from table')) {
  print 'db ok during fork'."\n\n";
}
$int_pid = pcntl_fork();
if(!$int_pid) {
  ingres_connect($str_database, $str_username, $str_password);
  if (ingres_query('select count(*) from table')) {
    print 'db ok for child'."\n\n";
  }
  exit();
} 
ingres_connect($str_database, $str_username, $str_password);
if (!ingres_query('select count(*) from table')) {
  print 'db not ok after fork'."\n\n";
}


Expected result:
----------------
db ok during fork

db ok for child

Actual result:
--------------
db ok during fork

db ok for child


Warning: ingres_query(): Ingres II:  Server or API error : Read from peer process failed; it may have exited. in /home/its/autoldg/lib/php/local/lib_autoldg_daemon.php on line 228

Warning: ingres_query(): Ingres II:  SQLSTATE : 08004 in /home/its/autoldg/lib/php/local/lib_autoldg_daemon.php on line 228
db not ok after fork


Warning: Unknown: Ingres II:  Server or API error : API function cannot be called in the current state. in Unknown on line 0

Warning: Unknown: Ingres II:  SQLSTATE : 5000R in Unknown on line 0

Warning: Unknown: Ingres II:  Unable to close statement !! in Unknown on line 0

Warning: Unknown: Ingres II:  Unable to rollback transaction !! in Unknown on line 0

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2005-08-04 08:14 UTC] greatwhitepine at bigfoot dot com
Sorry, forgot the pcntl_waitpid during my 1st edit (see below).

ingres_connect($str_database, $str_username, $str_password);
if (ingres_query('select count(*) from auto_ldg_run')) {
  print 'db ok during fork'."\n\n";
}
$int_pid = pcntl_fork();
if(!$int_pid) {
  ingres_connect($str_database, $str_username, $str_password);
  if (ingres_query('select count(*) from auto_ldg_run')) {
    print 'db ok for child'."\n\n";
  }
  exit();
} 
pcntl_waitpid ($int_pid, $str_status);
ingres_connect($str_database, $str_username, $str_password);
if (!ingres_query('select count(*) from auto_ldg_run')) {
  print 'db not ok after fork'."\n\n";
}
exit(1);
 [2005-08-04 08:45 UTC] sniper@php.net
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to report
a bug at http://bugs.php.net/how-to-report.php

Use separate connections or something else than ingres (moved to PECL, report bugs on it to pecl.php.net/bugs..)

 [2005-08-04 18:39 UTC] greatwhitepine at bigfoot dot com
Seperate connections does not work (as per the example)!
 [2005-08-05 00:15 UTC] greatwhitepine at bigfoot dot com
Just in case anyone might care I have a workaround...  the parent must not open a db connection until all children have completed.  Thus if the parent needs to use the db before forking child processes it should fork a db_child process to do so.

This code works as expected...
print 'parent before parent query'."\n\n";
$int_pid = pcntl_fork();
if(!$int_pid) {
  ingres_connect($str_database, $str_username, $str_password);
  if (ingres_query('select count(*) from auto_ldg_run')) {  
    print 'db ok for for parent query'."\n\n";
  }
  exit();
} 
pcntl_waitpid($int_pid, $int_returnCode, WUNTRACED);
print 'parent before child process is spawned'."\n\n";
$arr_pids = FALSE;
for ($i=0; $i < 3; $i++) {
  $arr_pids[] = pcntl_fork();
  if(!$arr_pids[$i]) {
    ingres_connect($str_database, $str_username, $str_password);
    if (ingres_query('select count(*) from auto_ldg_run')) {
      print 'db ok for child '.$i." \n\n";
    }
    exit();
  } 
}
for ($i=0; $i < 3; $i++) {
  pcntl_waitpid($arr_pids[$i], $int_returnCode, WUNTRACED);
}
print 'parent after children have completed'."\n\n";
ingres_connect($str_database, $str_username, $str_password);
if (ingres_query('select count(*) from auto_ldg_run')) {
  print 'db ok for parent after children have completed'."\n\n";
}

Output...
parent before parent query

db ok for for parent query

parent before child process is spawned

db ok for child 0 

db ok for child 1 

db ok for child 2 

parent after children have completed

db ok for parent after children have completed
 [2005-08-05 04:27 UTC] greatwhitepine at bigfoot dot com
The workaround is not required if the parent db connections are properly closed before spawning children.  Sorry about that Sniper.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Dec 21 17:01:58 2024 UTC