pg_dump via system() aus php funktioniert nicht

Hallo

In einem php-script habe ich die Zeile

$sSys = system("/usr/bin/pg_dump -U magnus  -c -f /home/jody/progs/magnus2/dumps/dump_magnus2_20120921.sql magnus2", $iRet);

Wenn dieser code ausgefuehrt wird, hat iRet den Wert 1, und kein dump wird geschrieben.
Die variable $sSys ist leer.

Wenn ich die selbe Zeile aud der Konsole eingebe, so funktioniert das.

Das directory /home/jody/progs/magnus2/dumps/ is voll beschreib- und lesbar:

$ ls -ld /home/jody/progs/magnus2/dumps
drwxrwxrwx 2 jody jody 4096 Sep 21 12:00 /home/jody/progs/magnus2/dumps

Auch wenn ich vor dem system-Befehl die Umgebungsvariablen setze,

putenv('PGUSER=magnus');
putenv('PGPASSWORD=das_passwort');

klappt’s nicht.

Die pg_dump version ist

 $ pg_dump --version
pg_dump (PostgreSQL) 9.1.5

Weiss jemand, was hier das problem sein koennte?
Gibt es eine moeglichkeit, herauszufinden warum pg_dump nicht funktioniert?

Danke
Jody

Darfst Du system() denn nutzen?

Bei uns per Default z.B. nicht.


Andreas

Ja - ich darf.
Ich habe versuchshalber mal

$sSys = system("touch /home/jody/progs/magnus2/dumps/testli.txt", $iRet);

gemacht, und das hat geklappt: $iRet war 0, und die Datei testli,txt wurde erzeugt.
Deswegen vermute ich, dass ich irgendein Problem im pg_dump habe… Gibt es eine Moeglichkeit herauszufinden, was genau pg_dump fuer ein Problem hat?
Danke
Jody

Ich hab mal bei einem $KUNDEN hier geschaut, der hat gesetzt:

putenv('PG_HOST=
putenv('PG_DB=
putenv('PG_USER=
putenv('PG_PASS=

Deine Werte im ersten Posting sahen a bissl anders aus…

Andreas

Danke fuer den Hinweis.

Ich habe diese Zeilen vor dem system-call eingefuegt:

putenv('PG_USER=magnus');
putenv('PG_PASS=das_passwort');
putenv('PG_DB=magnus2');
putenv('PG_HOST=localhost');

Aber leider hat es nicht gefruchtet: Ich kriege das selbe Verhalten: $iRet ist 1, und kein dump wurde geschrieben…

Ich habe es nun auch mit exec() versucht, da man hier die Ausgabe in einem Array erhaelt:

exec('/usr/bin/pg_dump -U magnus  -c -f /home/jody/progs/magnus2/dumps/dump_magnus2_20120921.sql magnus2', $output, $iRet);

Wenn ich nun sizeof(output) mache, so ist das 0 (d.h. 0 Zeilen).
Das deckt sich mit der Tatsache dass der Rueckgabewert von system() leer war (Rueckgabewert von system() ist die letzte Zeile der Ausgabe des ausgefuehrten Befehls).

Des weiteren habe ich noch

$sSys = system("/usr/bin/pg_dump --version", $iRet);

gemacht;
der wert von $sSys war dann “pg_dump (PostgreSQL) 9.1.5” und $iRet war 0.

D.h. es ist nicht ein Problem von pg_dump an sich, sondern es muss mit den Parametern zusammenhaengen (denke ich); ich habe aber keine Ahnung woran es liegen koennte…
Schreibt pg_dump moeglicherweise etwas in ein log-file? Und wenn ja, welches waere das?

Danke
Jody

Steht was im Log von PostgreSQL? Und was besagt die pg_hba.conf, sind Zugriffe via host (also TCP/IP) erlaubt? Via Command-Line kommst du ja auf Socken daher …


Andreas

Hoi Andreas

Das logfile ist zeigt nur den start von postgres an, sonst nichts. (Wenn ich pg_dump auf der Kommandozeile mit einem ansichtlichen Fehler mache, wird das geloggt)

Im pg_hba.conf habe ich

# TYPE  DATABASE        USER            ADDRESS                 METHOD

# "local" is for Unix domain socket connections only
local   all             all                                     md5
# IPv4 local connections:
host    all             all             127.0.0.1/32            md5
# IPv6 local connections:
host    all             all             ::1/128                 md5

Das sollte eigegntlich in Ordnung sein, da die Webapplikation, in welcher ich den dump machen will,
sonst problemlos alle Daten aus der DB holen und anzeigen kann…

Bezueglich des log files bin ich nicht sicher, ob das gut eingestellt ist:

log_destination = 'stderr'              # Valid values are combinations of
                                        # stderr, csvlog, syslog, and eventlog,
                                        # depending on platform.  csvlog
                                        # requires logging_collector to be on.

# This is used when logging to stderr:
logging_collector = on          # Enable capturing of stderr and csvlog
                                        # into log files. Required to be on for
                                        # csvlogs.
                                        # (change requires restart)

# These are only used if logging_collector is on:
#log_directory = 'pg_log'                # directory where log files are written,
log_directory = '/tmp'         # directory where log files are written,
                                        # can be absolute or relative to PGDATA
#log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log'        # log file name pattern,
                                        # can include strftime() escapes
#log_file_mode = 0600                   # creation mode for log files,

Ich habe das log_directory auf “/tmp” gesetzt, weil mit der Grundeinstellung kein log file geschrieben wurde.
(Am liebsten waere mir ein log-file in /var/log oder in einem Unterverzeichnis davon…)

Danke
Jody

Hallo

Ich habe mich wieder diesem pg_dump problem gewidmet.
Die postgres logs landen jetzt als syslog im /var/log/messages

Wenn ich das pg_dump in meinem php-script laufen lasse, so funktioniert es immer noch nicht,
aber andererseits zeigt das log keinen postgres-fehler an.

Ich habe nun den log-level auf DEBUG5 gesetzt, und dann einmal pg_dump aus dem php-script ausgefuehrt,
und anschliessend den genau gleichen Befehl von der Kommandozeile aus.
Der log-output der zwei Aktionen unterscheidet sich stark, nur schon von der Anzahl der Zeilen her (47 im script-Fall, 400 im konsolen-Fall)
Das meiste in diesen log-files ist fuer mich unverstaendlich…

Hier das Logging fuer pg_dump vom PHP-Skript aus
log_php-dump - Pastebin.comHier das Logging fuer pg_dump von der Konsoleausl
log_pgdump_console - Pastebin.com

Kann jemand das deuten?
Danke
Jody

So als Schnellschuß: exec() oder wie auch immer das pg_dump aufgerufen wird ist disabled.

Andreas

Hallo Andreas

Nein, exec() ist nicht disabled.

Wenn ich die Zeile
exec("/usr/bin/pg_dump -U $g_user -c -f $sPath $sDBName", $output, $iRet);
durch
exec("/usr/bin/pg_dump --version", $output, $iRet);
ersetze, so hat $iRet den Wert 0 und das erste Element in $output ist “pg_dump (PostgreSQL) 9.1.5”

Der Fehler passiert wahrscheinlich irgendwo in der Ausfuehrung von pg_dump,
aber wie gesagt, die log files, die ich gemacht habe (siehe obigen post) sagen mir nicht viel…

Jody

Hallo
Ich habe die Loesung meines Problems gefunden und will sie hier der Nachwelt weitergeben.

Das Problem lag beim Zugriff des users ‘apache’ auf den Socket des postgres servers.

Auf den Socket koennen alle zugreifen,

$ ls -l /run/postgresql/.s.PGSQL.5432
srwxrwxrwx 1 postgres postgres 0 Jan 7 22:31 /run/postgresql/.s.PGSQL.5432

aber auf das darueberliegende Verzeichnis kann nur vom user ‘postgres’ oder von der Gruppe ‘postgres’ zugegriffen werden:

$ ls -ld /run/postgresql
drwxrwx— 2 postgres postgres 80 Jan 7 20:35 /run/postgresql

Die Loesung bestand nun darin, den User ‘apache’ der Gruppe ‘postgres’ hinzuzufuegen (wichtig: apache neu starten),
und sicher zu stellen, dass das Passwort aus der Environment-Variable PGPASSWORD gelesen wird (und nicht PG_PASS).
(ich habe in pg_hba alles auf ‘md5’ gestellt, s. oben, alter post vom 21.09.2012; ich glaube, mit ‘ident’ oder ‘peer’ klappt’s nicht)

Die relevanten Zeilen sind nun:

putenv(‘PGPASSWORD=das_passwort’);
exec(“/usr/bin/pg_dump -U $g_user -c -f $sPath $sDBName”, $output, $iRet);

und es geht :slight_smile:

Ich nehme an, das “frueher” der user ‘apache’ automatisch zum Mitglied der Gruppe ‘postgres’ gemacht wurde,
aber aus irgendeinem Grund passiert das nicht mehr…


Gruss
jody

Ja, der gute Tom Lane mal wieder, gell?


Andreas

So ist es! :slight_smile:
Jody