pg_upgrade schlägt fehl | waiting for server to start.... stopped waiting

Hallo liebe PostgreSQL Experten,

ich habe ein Problem, an dem ich momentan fast am verzweifeln bin: Im Zuge der Installation der von mir entwickelten Software, ist es notwendig, eine lokal auf Windows 7 installierte PostgreSQL Datenbank von Version 9.1 auf 9.5 zu updaten. Für dieses Update habe ich ein Windows Powershell Skript geschrieben.
Mein Problem ist, dass der darin enthaltene “pg_upgrade.exe” Befehl innerhalb des Skriptes, aus mir unerklärlichen Gründen, fehlschlägt.

Es scheint sich um das gleiche Problem, wie hier
beschrieben zu handeln.

Das komische ist: Führe ich das Powershell Skript außerhalb des Installationsprozesses (z.B. über die Powershell ISE) aus, funktioniert das Upgrade problemlos. Nur während des Installationsvorganges, beim Start des Skriptes aus AdvancedInstaller heraus ergibt sich folgender Fehler:

Performing Consistency Checks
-----------------------------
Checking cluster versions                                   ok
Checking database user is the install user                  ok
Checking database connection settings                       ok
Checking for prepared transactions                          ok
Checking for reg* system OID user data types                ok
Checking for contrib/isn with bigint-passing mismatch       ok
Checking for invalid "line" user columns                    ok
Creating dump of global objects                             ok
Creating dump of database schemas
  postgres
  spaceserver
  template1
                                                            ok
Checking for presence of required libraries                 ok
Checking database user is the install user                  ok
Checking for prepared transactions                          ok

If pg_upgrade fails after this point, you must re-initdb the
new cluster before continuing.

Performing Upgrade
------------------
Analyzing all rows in the new cluster                       ok
Freezing all rows on the new cluster                        ok
Deleting files from new pg_clog                             ok
Copying old pg_clog to new server                           ok
Setting next transaction ID and epoch for new cluster       ok
Deleting files from new pg_multixact/offsets                ok
Copying old pg_multixact/offsets to new server              ok
Deleting files from new pg_multixact/members                ok
Copying old pg_multixact/members to new server              ok
Setting next multixact ID and offset for new cluster        ok
Resetting WAL archives                                      ok

*failure*

Der oben verlinkte Beitrag aus der PostgreSQL Mailing Liste sagt etwas über unzureichende Rechte. Allerdings führe ich das Powershell Skript bereits mit Administrator Rechten aus. Dementsprechend müsste der “pg_upgrade.exe” Befehl diese Rechte erben. Im Falle der Ausführung aus der Powershell ISE tut er das scheinbar auch.

Im Logfile “pg_upgrade_server_start.log” steht dann das folgende:

-----------------------------------------------------------------
  pg_upgrade run on Thu Oct 20 18:45:56 2016
-----------------------------------------------------------------


-----------------------------------------------------------------
  pg_upgrade run on Thu Oct 20 18:45:56 2016
-----------------------------------------------------------------



command: "C:\Users\Test\AppData\Local\Temp\backup_os_20161020184439\postgresql-9.3\bin/pg_ctl" -w -l "pg_upgrade_server.log" -D "C:\Users\Test\AppData\Local\Temp\backup_os_20161020184439\postgresql-9.3\data" -o "-p 50432 -c autovacuum=off -c autovacuum_freeze_max_age=2000000000 " start >> "pg_upgrade_server_start.log" 2>&1
waiting for server to start.... done
server started


command: "C:\Users\Test\AppData\Local\Temp\backup_os_20161020184439\postgresql-9.3\bin/pg_ctl" -w -l "pg_upgrade_server.log" -D "C:\Users\Test\AppData\Local\Temp\backup_os_20161020184439\postgresql-9.3\data" -o "-p 50432 -b " start >> "pg_upgrade_server_start.log" 2>&1
waiting for server to start.... done
server started


command: "C:\B.Braun Space\OnlineSuite\pgsql\bin/pg_ctl" -w -l "pg_upgrade_server.log" -D "C:\B.Braun Space\OnlineSuite\pgsql\data" -o "-p 50432 -b -c synchronous_commit=off -c fsync=off -c full_page_writes=off " start >> "pg_upgrade_server_start.log" 2>&1
waiting for server to start.... done
server started


command: "C:\B.Braun Space\OnlineSuite\pgsql\bin/pg_ctl" -w -l "pg_upgrade_server.log" -D "C:\B.Braun Space\OnlineSuite\pgsql\data" -o "-p 50432 -b -c synchronous_commit=off -c fsync=off -c full_page_writes=off " start >> "pg_upgrade_server_start.log" 2>&1
waiting for server to start.... stopped waiting

Hier der Auszug aus dem Powershell Skript, mit dem ich den pg_upgrade.exe Befehl ausführe:

# Re-Write old pg_hba.conf file to allow all users to connect withot password
	$pgHbaConfFileStr = Join-Path $oldPgDataFolder "pg_hba.conf"
	$pgHbaConfFileBakStr = Join-Path $oldPgDataFolder "pg_hba.conf.bak"
	if(-not (Test-Path $pgHbaConfFileStr)) {
	    Write-Output "Error: Unable to find pg_hba.conf in $oldPgDataFolder"
	    Exit 1
	}
	#Backup pg_hba.conf to pg_hba.conf.bak
	Move-Item $pgHbaConfFileStr $pgHbaConfFileBakStr -Force
	$hbaConfText = @("host   all    all   127.0.0.1/32  trust","host   all    all   ::1/128       trust")
	[IO.File]::WriteAllLines($pgHbaConfFileStr, $hbaConfText)
	#Set environment variables for pg_upgrade.exe
	$ENV:PGBINOLD=$oldPgBinFolder
	$ENV:PGDATAOLD=$oldPgDataFolder
	$ENV:PGBINNEW=$pgBinDir
	$ENV:PGDATANEW=$pgDataDir
	
	$ENV:PGUSER="postgres"
	$ENV:PGPASSWORD=$postgreAdminPwd
	
	Write-Output "Executing pg_upgrade command ..."
	
	& $pgBinDir\pg_upgrade.exe --link

Ich hoffe wirklich, dass ihr mir weiterhelfen könnt, denn ich bin wirklich am Ende mit meinem Latein.

Grüße, André

ohne das jetzt im Detail zu analysieren (ich außerdem nix Windows):

  • es ist eine schlechte Idee, mit pg_upgrade gleich 4 Versionen überspringen zu wollen
  • Du hast hoffentlich ein aktuelles Backup
  • Du hast hoffentlich das aktuellste pg_upgrade verwendet
  • die DB (die alte) lief hoffentlich mit der aktuellsten Minor-Version
  • schlechte Idee, fsync=off zu verwenden. Ganz schlecht, übrigens.
  • schlechte Idee mit autovacuum = off. Ebenfalls: ganz schlecht
  • alle ‘Virenscanner’ und Tischbrandschutzmauern deaktiviert?

Wie groß ist die DB? Die Tatsache, daß das unter Windows läuft, läßt mich vermuten: eher klein. Wie groß sind die Anforderungen bzgl. Ausfallzeit? Da es unter Windows läuft: vermutlich eh egal. Warum also gehst Du nicht den sicheren Weg via Dump&Restore?

Hallo akretschmer, vielen Dank schon mal für deine Antwort.
Wenn ich die Wahl hätte, würde ich auch lieber ein Datenbank-Update auf Linux durchführen :p

Die genaue Datenbank Größe ist von Installation zu Installation unterschiedlich. Sie kann aber mitunter mehrere GB groß geworden sein. Ich suchte daher nach einem schnelleren Weg als “Dump&Restore”, da dies wohl für eine sehr große Datenbank äußerst lange dauern würde. Die Ausfallzeit der Datenbank ist nicht weiter relevant. Wichtig ist nur, dass nach Abschluss der Installationsroutine die Datenbank ohne Datenverlust in der Version 9.5 läuft.

Es war mir nicht bewusst, dass das Update via pg_upgrade so fehleranfällig ist.

Okay, diese Optionen wurden intern von dem pg_upgrade Befehl an den Server übergeben, darauf habe ich ja keinen Einfluss.

Das pg_upgrade ist das aus der neu installierten (entpackten) PostgreSQL Version 9.5.4-2

Da es sich um eine Update Routine handelt, die später auf allen Kundeninstallation funktionieren soll, ist es wichtig dass das Backup&Restore ohne Datenverlust durchgeführt wird. Eine Blockade durch einen Virenscanner oder Firewall würde ich jetzt mal ausschließen, da ich meine Update-Routine in einer VM mit sauber installierten Windows 7 teste.

Also aus deinen Anmerkungen verstehe ich, dass ein Update der Datenbank mittels pg_upgrade --link die denkbar schlechteste Option darstellt. Das heißt ich komme an einem Dump&Restore wohl nicht vorbei? Hast du zufällig Erfahrungswerte bzgl. der Performance von Dump&Restore bei großen Datenbanken?

Gruß André

Hi,

also, pg_upgrade kann funktionieren, und auch 3-4 Versionen überspringen, aber es birgt halt Risiken. Wichtig ist, daß auch die ‘alte’ Version auf einer aktuellen Minor-Version läuft, IIRC gab es da auch kürzlich einen Patch.

Mehrere GB - das ist, sorry, peanuts. (ich interpretiere das mal mit einigen GB, wohl unter 10). Nach dem, was Du schilderst, erscheint es mir am einfachsten und sichersten, die neuere Version (also 9.5 oder 9.6) zu installieren (zumindest daraus das pg_dump), einen Dump zu ziehen (im Custom-Format), das alte PG entsorgen, das neue drauf und mit pg_restore und evtl. mit mehreren Jobs (-j) den Dump einzuspielen.

Re-Write old pg_hba.conf file to allow all users to connect withot password

Das muss bei der “neuen” pg_hba.conf auch gemacht werden - zumindest solange das pg_upgrade läuft.
Ist das so?

Ich bin mir auch nicht ganz sicher, ob das mit dem --link bei einem so große Versionssprung so eine gute Idee ist.
Funktioniert das ohne --link?

beim Start des Skriptes aus AdvancedInstaller heraus ergibt sich folgender Fehler

Das deutet auf Probleme mit den Zugriffsrechten hin. Wie werden denn die Datenverzeichnisse angelegt?
Wird das mit dem gleichen Benutzer gemacht, der auch pg_ctl ausführt?

Pfade mit Leerzeichen drin können durchaus auch ein Problem sein - vor allem weil die notwendigen Anführungszeichen sehr vorsichtig gesetzt werden müssen. Ich hatte mal den Fall, dass dieser Aufruf:

"C:\B.Braun Space\OnlineSuite\pgsql\bin\pg_ctl.exe" start -D ...

fehlschlägt. Der folgende aber nicht:

"C:\B.Braun Space\OnlineSuite\pgsql\bin\"pg_ctl.exe start -D ...

Der Dateiname darf nicht in den Anführungszeichen stehen. Das hat wohl was damit zu tun, dass pg_ctl versucht Adminrechte “loszuwerden” und sich dabei irgendwie neu startet - und das schlägt fehl wenn die Anführungszeichen das .exe mit einschließen.

Hast Du es mal mit Pfaden ohne Leerzeichen versucht?