server start fails with "pclose failed: No child processes"

Hallo,

ich habe ein Problem mit dem Starten des Servers nach dem Einspielen eines Backups. Der Ablauf ist wie folgt:

  1. Server starten: OK
su postgres -c "pg_ctl start -w -D ${DATADIR}"
  1. Backup einspielen:
createdb -E UTF8   -U postgres mydb_restore
psql -U postgres -d mydb_restore -f ${VAR_DIR}/mydbsql_br.dmp > /dev/null  2>/dev/null
if [ $? -eq 0 ]
 then
   echo " mydb SQL database successful restored to database mydb_restore ...."
   echo " drop database mydb ...."
   dropdb -U postgres mydb >/dev/null 2>/dev/null
   echo " rename database mydb_restore to mydb ...."
   psql  -U postgres -t -A -c "ALTER DATABASE mydb_restore RENAME TO mydb;"
 else
   echo " ERROR: restoring mydb SQL database FAILED ....."
fi
  1. Server stoppen: OK
su postgres -c "pg_ctl stop -w -D ${DATADIR}"
  1. Server erneut starten: ERROR
su postgres -c "pg_ctl start -w -D ${DATADIR}"
>> ...
>> pclose failed: No child processes
>> The program "postgres" is needed by pg_ctl but was not found in the
>> same directory as "/opt/system_root/pgsql/9.0/bin/pg_ctl".
>> Check your installation.
>> ...

Das Programm “postgres” ist natürlich im genannten Pfad vorhanden. Der Fehler ist zu 100% reproduzierbar.
Die Postgres-Executables sind kompiliert unter SLES11SP2-32 bit, ausgeführt wird das ganze auf einem SLES11SP2-64 bit Linux (die eigentliche Anwendung ist ein 32-bit Executable). Bisher lief das Ganze problemlos, erst seit kurzem (mit einem speziellen Backup) tritt das Problem auf.


Der Fehler tritt in folgendem Ablauf auf:

basis.sh
=> basis.pl
   => System("pg_restore.sh") [Server start OK]
   => System("test.sh") [Server start OK]
=> test.sh [Server start NICHT OK]

Weitere Fakten:

  • zwischen dem Aufruf von basis.pl und test.sh in basis.sh befindet sich kein weiterer Code
  • zum gleichen Zeitpunkt, wo der Serverstart in Basis.sh fehlschlägt kann der Server in einer anderen Shell problemlos gestartet und gestoppt werden.
  • der Fehler tritt nicht auf, wenn basis.sh gerade neu gestartet ist, sondern nur, wenn der o.g. Ablauf aus dem Normalbetrieb heraus stattfindet

Ich halte das Ganze für einen Fehler von Postgres, der halt nur unter sehr speziellen Umständen (= Zustand des Betriebssystems / der Datenbank) zu Tage tritt.
Mein nächster Schritt wäre Postgres unter GDB-Kontrolle zu starten und so dem Ganzen auf die Schliche zu kommen.

Da ich mit GDB nun nicht so ganz auf Du&Du bin (insbesondere muss man ja wohl Sub-Prozesse debuggen) wäre ich für alternative Tipps für das prinzipielle Vorgehen mehr als dankbar!


Danke im Voraus,
Rüdiger



Ach ja, hier noch straces vom Gut- und Schlechtfall:

Gutfall:

rt_sigprocmask(SIG_BLOCK, [INT CHLD], [], 8) = 0
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7fa52a9629d0) = 24516
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigaction(SIGINT, {0x435740, [], SA_RESTORER|SA_RESTART, 0x7fa529ff9bf0}, {0x1, [], SA_RESTORER|SA_RESTART, 0x7fa529ff9bf0}, 8) = 0
rt_sigaction(SIGINT, {0x1, [], SA_RESTORER|SA_RESTART, 0x7fa529ff9bf0}, {0x435740, [], SA_RESTORER|SA_RESTART, 0x7fa529ff9bf0}, 8) = 0
wait4(-1, could not change directory to "/root"
waiting for server to start.... done
server started
[{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 24516
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
--- SIGCHLD (Child exited) @ 0 (0) ---

Schlechtfall:

rt_sigprocmask(SIG_BLOCK, [INT CHLD], [], 8) = 0
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f96afde19d0) = 17945
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigaction(SIGINT, {0x435740, [], SA_RESTORER|SA_RESTART, 0x7f96af478bf0}, {0x1, [], SA_RESTORER|SA_RESTART, 0x7f96af478bf0}, 8) = 0
rt_sigaction(SIGINT, {0x1, [], SA_RESTORER|SA_RESTART, 0x7f96af478bf0}, {0x435740, [], SA_RESTORER|SA_RESTART, 0x7f96af478bf0}, 8) = 0
wait4(-1, pclose failed: No child processes
The program "postgres" is needed by pg_ctl but was not found in the
same directory as "/opt/system_root/pgsql/9.0/bin/pg_ctl".
Check your installation.
[{WIFEXITED(s) && WEXITSTATUS(s) == 1}], 0, NULL) = 17945
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
--- SIGCHLD (Child exited) @ 0 (0) ---

Der Vollständigkeit halber:

  • in der Situation wo pclose() von pg_ctl.c (bzw. port/exec.c) scheitert scheitert auch der system()-Aufruf zum Starten des postgres Server Prozesses
  • mein Problem läst sich durch eine Änderung in der Umgebung lösen