PostgreSQL auf Mac OS X 10.5

Nov 2007
04

19 Kommentar(e)

Eingetragen von Martin Maciaszek

Vor einer Weile habe ich in meinem Blog geschrieben, wie man PostgreSQL auf Mac OS X 10.4 (aka Tiger) installiert. Seitdem ist eine Weile ins Land gegangen. PostgreSQL ist inzwischen bei 8.2.5 angekommen und es existiert eine 8.3 beta 2. Nicht ganz unerwähnt bleiben sollte auch die Tatsache, daß vor kurzem Mac OS X 10.5 (aka Leopard) erschien. Änderungen in Mac OS X 10.5 machen haben dazu geführt, daß meine alte Anleitung als überholt angesehen werden kann. Deshalb folgt hier die aktualisierte Version.

Für die Installation brauchst du Xcode 3.0. Es befindet sich auf der Installations-DVD von Leopard bzw. du kannst von von Apples Developer Connection herunterladen. Ist Xcode installiert, kannst du mit der eigentlichen Installation von PostgreSQL loslegen. Ich werde im Laufe dieser Anleitung PostgreSQL 8.3 beta 2 bei mir installieren, doch die einzelnen Installationsschritte sollten auch mit 8.2 und 8.1 ohne Änderungen funktionieren.

Warnung: Einige der folgenden Schritte (wie z.B. das Anlegen der Gruppe/User) führen Änderungen an wichtigen Systemeinstellungen durch. Unbedachte Änderungen und Fehler können hier schnell dazu führen, daß das System unbenutzbar wird. Sagt nicht, ich hätte euch nicht gewarnt! Ich habe anhand dieser Schritte PostgreSQL auf 2 Rechnern bereits erfolgreich eingerichtet. Statistisch gesehen, macht das eine Erfolgsquote von 100% (*auf die Schulter klopf*), doch ich kann nicht garantieren, daß es überall ohne Probleme abläuft. Solltest du Probleme haben oder gar Fehler in der Anleitung entdeckt haben, so kannst du mich gerne per Email kontaktieren (s. Impressum) oder einen Kommentar unter diesem Artikel hinterlassen.

Lade dir zuerst den Quelltext von PostgreSQL herunter. Unter http://www.postgresql.org/ftp/latest/ findest du stehts die aktuelle stabile Release. Die richtige Datei heißt in der Regel postgresql-8.x.x.tar.gz bzw. postgresql-8.x.x.tar.bz2. Extrahiere das Archiv an einer geeigneten Stelle und begib dich mit dem Terminal in dieses Verzeichnis. Von da aus, kannst du PostgreSQL mit folgender Zeile kompilieren und installieren:

./configure --prefix=/Library/PostgreSQL --enable-thread-safety \
--with-krb5 --with-bonjour --with-openssl --with-gssapi \
&& make && sudo make install

An dieser Stelle möchte ich anmerken, daß Mac OS X 10.5 DTrace mit an Bord hat und PostgreSQL 8.3 auch mit DTrace-Support kompiliert werden kann. Leider kennen die Makefiles von PostgreSQL 8.3 in der aktuellen Beta nur die Solaris-Version von DTrace und brechen auf Mac OS X mit einer Fehlermeldung beim kompilieren ab. Ich hoffe, daß dieses Problem bis zur Release von PostgreSQL 8.3 behoben wird. Sollten spätere Versionen von PostgreSQL in dieser Hinsicht korrigiert werden, so reicht es aus, die obige Configure-Zeile um --enable-dtrace zu erweitern.

Damit PostgreSQL auch laufen kann, benötigt es einen Systemuser. In meiner früheren Anleitung für Tiger hatte ich mich für die User-ID 73 entschieden, da diese frei war. Unter Leopard sind fast alle freien User-IDs unter 100 belegt. Ich habe mich also für die User-ID 183 entschieden.

Eine weitere Änderung gegenüber Tiger, ist der Wegfall des Netinfo Managers sowie der NetInfo-Kommandozeilentools wie niutil. Ab Leopard gibt es nur noch das Open Directory und das Kommandozeilentool dscl. Die benötigte Gruppe und den User legst du mit folgenden Befehlen an:

sudo dscl . -create /Groups/_postgres 
sudo dscl . -create /Groups/_postgres RealName 'PostgreSQL Server'
sudo dscl . -create /Groups/_postgres PrimaryGroupID 183          
sudo dscl . -create /Groups/_postgres UserShell /usr/bin/false
sudo dscl . -create /Groups/_postgres Password '*'
sudo dscl . -create /Groups/_postgres NFSHomeDirectory /var/empty

sudo dscl . -create /Users/_postgres   
sudo dscl . -create /Users/_postgres Password '*'
sudo dscl . -create /Users/_postgres RealName 'PostgreSQL Server'
sudo dscl . -create /Users/_postgres PrimaryGroupID 183
sudo dscl . -create /Users/_postgres UniqueID 183      
sudo dscl . -create /Users/_postgres UserShell /usr/bin/false
sudo dscl . -create /Users/_postgres NFSHomeDirectory /Users/Shared/PostgreSQL

Den Erfolg dieser Zeilen kannst du überprüfen, indem du id _postgres eingibst. Dies sollte folgende Zeile zurückliefern:

uid=183(_postgres) gid=183(_postgres) groups=183(_postgres)

Durch die Installation in /Library/PostgreSQL befinden sich die Kommandozeilentools von PostgreSQL an einem etwas mühsam erreichbaren Ort. Um dir das Leben zu erleichtern kannst du entweder /Library/PostgreSQL/bin zu deinem $PATH hinzufügen, oder Symlinks zu den Tools in einem Verzeichnis erstellen, welches sich im $PATH befindet. Ich habe mich für letzteres entschieden und einen Haufen Symlinks in /usr/local angelegt. Da Leopard ein geradezu jungfräuliches /usr/local-Verzeichnis mitliefert, war es bei mir nötig, die leeren Verzeichnisse für die Tools und ihre Man-Pages zuerst mit sudo mkdir -p /usr/local/{bin,man/man1,man/man7} anzulegen. Das symlinken erledigt dieses kleine Skript.

#!/bin/sh

POSTGRES_DIR=/Library/PostgreSQL
DEST_DIR=/usr/local
SYMLINK_DIRS="bin man/man1 man/man7"

for CUR_DIR in $SYMLINK_DIRS; do
  for CUR_FILE in $POSTGRES_DIR/$CUR_DIR/*; do
    sudo ln -nfs $CUR_FILE $DEST_DIR/$CUR_DIR${CUR_FILE#$POSTGRES_DIR/$CUR_DIR}
  done
done

Teste nun mit which psql, ob die PostgreSQL-Kommandozeilentools auch wirklich erreichbar sind. (In der Zsh könnte es nötig werden, vorher noch rehash auszuführen, damit neue Programme im $PATH erkannt werden)

Ich habe mich entschieden, die Datenbank unter /Users/Shared/PostgreSQL abzulegen (siehe auch NFSHomeDirectory des Users _postgres). Da dieses Verzeichnis normalerweise nicht existiert, mußt du es zuerst anlegen:

sudo mkdir -p /Users/Shared/PostgreSQL
sudo chown _postgres:_postgres /Users/Shared/PostgreSQL

Als nächstes muß die Datenbank initialisiert werden. Während der Initialisierung wirst du nach dem Passwort für den Datenbank-Superuser (in meinem Fall postgres genannt) gefragt. Da du diesen Datenbank-Superuser brauchst, um weitere User und Datenbanken anzulegen, wäre es äußerst ungeschickt, seine Logindaten zu verlieren. Die Datenbank initialisierst du mit diesem Befehl:

sudo -u _postgres initdb -U postgres -A md5 -W -E UTF8 \
-D /Users/Shared/PostgreSQL/data

Sollte die Initialisierung mit folgenden Ausgaben fehlschlagen, so begib dich zuerst mit cd ~ in dein Heimatverzeichnis und führe dann die Initialisierung erneut aus.

could not identify current directory: Permission denied
could not identify current directory: Permission denied
could not identify current directory: Permission denied
The program "postgres" is needed by initdb but was not found in the
same directory as "initdb".
Check your installation.

Eine erfolgreiche Initialisierung dagegen sollte ungefähr so aussehen:

The files belonging to this database system will be owned by user "_postgres".
This user must also own the server process.

The database cluster will be initialized with locale de_DE.UTF-8.
The default text search configuration will be set to "german".

creating directory /Users/Shared/PostgreSQL/data ... ok
creating subdirectories ... ok
selecting default max_connections ... 20
selecting default shared_buffers/max_fsm_pages ... 2400kB/20000
creating configuration files ... ok
creating template1 database in /Users/Shared/PostgreSQL/data/base/1 ... ok
initializing pg_authid ... ok
Enter new superuser password: 
Enter it again: 
setting password ... ok
initializing dependencies ... ok
creating system views ... ok
loading system objects' descriptions ... ok
creating conversions ... ok
creating dictionaries ... ok
setting privileges on built-in objects ... ok
creating information schema ... ok
vacuuming database template1 ... ok
copying template1 to template0 ... ok
copying template1 to postgres ... ok

Success. You can now start the database server using:

    postgres -D /Users/Shared/PostgreSQL/data
or
    pg_ctl -D /Users/Shared/PostgreSQL/data -l logfile start

Da ich PostgreSQL für die Entwicklung mit Rails benutze, möchte ich gerne wissen, welche Befehle an die Datebank gesendet werden. Solltest du die Datenbank in einer Produktivumgebung einsetzen wollen, so würde ich Logging auf die wirklich wichtigen Meldungen beschränken, da es sonst die Datenbank unnötig ausbremsen könnte.

Lege in /var/log ein Verzeichnis für die PostgreSQL-Logfiles an.

sudo mkdir /var/log/postgres

In der früheren Anleitung habe ich PostgreSQL die Logfiles direkt schreiben lassen. Leider hat PostgreSQL die unangenehme Eigenheit, an den Namen eines jeden Logfiles eine Zufallszahl anzuhängen, was es etwas mühsam machte, das aktuelle Logfile zu finden. Deshalb werde ich diesmal über den Syslog loggen lassen. Füge dazu in der /etc/syslog.conf folgende Zeile hinzu:

local3.*                                /var/log/postgres/postgres.log

Dieses Logfile soll auch jeden Tag um Mitternacht gegen ein neues ausgetauscht werden, damit es nicht zu sehr anwächst. Dies erledigt folgende Zeile in der /etc/newsyslog.conf:

/var/log/postgres/postgres.log          644  5     *    @T00  J

Lege nun ein leeres Logfile an und starte den Syslog-Daemon mit diesen Befehlen:

sudo touch /var/log/postgres/postgres.log
sudo kill -HUP $(cat /var/run/syslog.pid)

Jetzt muß noch PostgreSQL wissen, daß es auch den Syslog benutzen soll. Dies geschieht mit folgenden Zeilen in der /Users/Shared/PostgreSQL/data/postgresql.conf:

log_destination = 'syslog'
syslog_facility = 'LOCAL3'

Wo wir noch in der Konfigurationsdatei von PostgreSQL drin sind, sollten wir auch noch festlegen, was PostgreSQL loggen soll. Ich empfehle für den Anfang folgendes: (s. PostgreSQL Doku: Error Reporting and Logging)

log_line_prefix = '%u@%h:/%d '
log_statement = 'all'

Damit ist PostgreSQL nun endlich bereit zum Start. Es wäre jedoch auf die Dauer etwas mühselig, PostgreSQL immer von Hand zu starten. Ich habe deshalb ein Launchd-Skript erstellt, was PostgreSQL automatisch beim Booten startet. Das Skript sieht folgendermaßen aus:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>org.postgresql.postmaster</string>
    <key>UserName</key>
    <string>_postgres</string>
    <key>OnDemand</key>
    <false/>
    <key>ProgramArguments</key>
    <array>
        <string>/Library/PostgreSQL/bin/postmaster</string>
        <string>-D</string>
        <string>/Users/Shared/PostgreSQL/data</string>
        <string>-c</string>
        <string>log_connections=YES</string>
    </array>
    <key>ServiceDescription</key>
    <string>PostgreSQL Server</string>
</dict>
</plist>

Speichere dieses Skript unter dem Namen org.postgresql.postmaster.plist im Verzeichnis /Library/LaunchDaemons und lade es in den Launchd mit sudo launchctl load /Library/LaunchDaemons/org.postgresql.postmaster.plist. Wenn alles gutgegangen ist, solle PostgreSQL nun laufen. Bei mir sieht dies so aus:

Venus:~ fastjack$ ps ax | grep postmaster
 5315   ??  Ss     0:00.31 /Library/PostgreSQL/bin/postmaster -D /Users/Shared/PostgreSQL/data -c log_connections=YES

Und die Datenbank akzeptiert auch Verbindungen zu ihr:

Venus:~ fastjack$ psql -U postgres template1
Password for user postgres: 
Welcome to psql 8.3beta2, the PostgreSQL interactive terminal.

Type:  \copyright for distribution terms
       \h for help with SQL commands
       \? for help with psql commands
       \g or terminate with semicolon to execute query
       \q to quit

template1=# 

Da dies ein Blog über Ruby on Rails ist, wäre diese Anleitung nicht vollständig, ohne zu erwähnen, wie das passende Postgres-Gem installiert wird. Da sich PostgreSQL an einer für andere Unix-Systeme ungewöhnliches Stelle befindet, fällt die normale Installation erstmal auf die Nase, weil es PostgreSQL nicht findet. Du mußt also dem Gem mitteilen, wo es die PostgreSQL-Libraries und -Includes findet. Der vollständige Befehl sieht so aus:

sudo gem install postgres -- --with-pgsql-lib-dir=/Library/PostgreSQL/lib \
--with-pgsql-include-dir=/Library/PostgreSQL/include

Das war’s. Es ist geschafft. PostgreSQL läuft und mit dem Postgres-Gem kannst du auf die Datenbank aus deinen Rails-Anwendungen zugreifen.


19 Kommentar(e) zu PostgreSQL auf Mac OS X 10.5

  1. MasterOfDesaster sagte:

    Tue Nov 20 14:06:40 UTC 2007

    hab alles wie beschrieben gemacht (auf os x 10.5.1).

    jedoch kommt das ins log: @:/ LOG: could not bind IPv6 socket: Address already in use Nov 20 12:39:33 siggi postgres[410]: [1-2] @:/ HINT: Is another postmaster already running on port 5432? If not, wait a few seconds and retry. Nov 20 12:39:33 siggi postgres[410]: [2-1] @:/ FATAL: could not create shared memory segment: Invalid argument Nov 20 12:39:33 siggi postgres[410]: [2-2] @:/ DETAIL: Failed system call was shmget(key=5432001, size=11386880, 03600). Nov 20 12:39:33 siggi postgres[410]: [2-3] @:/ HINT: This error usually means that PostgreSQL’s request for a shared memory segment exceeded your kernel’s SHMMA

    help, please?

  2. Martin Maciaszek sagte:

    Thu Nov 22 08:06:31 UTC 2007

    Kann es sein, daß du noch an den Einstellungen für das Shared Memory in der postgresql.conf was geändert hast?

    Ich hatte eine ähnliche Fehlermeldung vor Jahren mal unter FreeBSD, als ich an den Einstellungen für die maximale Anzahl von Verbindungen herumgespielt habe. Diese Einstellungen solltest du erstmal auf dem Default belassen. Alternativ könntest du auch mal Googlen, wie du den Shared Memory vergrößern kannst. Ich nehme an, daß es über irgendeinen sysctl geht. (Weiß es aber nicht aus dem Kopf)

    Die Warnung, daß er sich nicht mit dem IPv6-Socket verbinden kann, habe ich bei mir auch. Ist aber nicht schlimm. Die wenigsten Clients verbinden sich mit der Datenbank per IPv6 und die Datenbank läuft ohne Probleme auch so.

  3. Rabbit sagte:

    Fri Dec 07 21:24:43 UTC 2007

    Muss man denn unter Leopard keine Parameter mehr für den Kernel angeben? Bei 10.4 war das doch noch notwendig - oder? Bei Leopard gibt es die Datei /etc/rc nicht mehr. Wie wird das jetzt gemacht?

  4. Martin Maciaszek sagte:

    Sat Dec 08 08:33:04 UTC 2007

    Also ich habe bei mir nie an den Kernelparametern herumgespielt. PostgreSQL lief auch so.

  5. Tino sagte:

    Sat Dec 08 17:16:28 UTC 2007

    Danke für die ausführliche Anleitung.

    Nun habe ich aber das Problem, dass die Datenbank bei mir nicht startet.

    ps ax | grep postmaster 532 s000 R+ 0:00.00 grep postmaster

    Wo wird denn geloggt, was beim Versuch PostreSQL zu starten passiert? Ich denk, dass würde weiterhelfen.

  6. Martin Maciaszek sagte:

    Sun Dec 09 11:32:01 UTC 2007

    Wenn du streng meiner Anleitung gefolgt bist, solltest du in /var/log/postgres/postgres.log das Logfile finden.

  7. Phil sagte:

    Sun Dec 09 20:58:06 UTC 2007

    Hallo

    Vielen dank für diese super Anleitung! Ich habe alles nach ihr gemacht. Aber leider scheitert es ganz am Schluss beim laden beim starten. Wenn ich den Befehl “sudo launchctl load /Library/LaunchDaemons/org.postgresql.postmaster.plist” eingebe dann kommt immer folgende Meldung:

    launchctl: Dubious permissions on file (skipping): /Library/LaunchDaemons/org.postgresql.postmaster.plist nothing found to load

    Was soll ich nun machen ?

  8. Martin Maciaszek sagte:

    Mon Dec 10 07:59:35 UTC 2007

    Die “dubious permissions”-Meldung würde darauf hindeuten, daß die Datei vermutlich nicht dem User “root” und der Gruppe “wheel” gehört, oder merkwürdige Zugriffsrechte besitzt. Versuch doch mal folgendes:

    sudo chown root:wheel /Library/LaunchDaemons/org.postgresql.postmaster.plist

    sudo chmod 644 /Library/LaunchDaemons/org.postgresql.postmaster.plist

    Das sollte die Permissions wieder geradebügeln.

  9. Tom sagte:

    Thu Dec 13 11:14:36 UTC 2007

    Super! Scheint funktioniert zu haben, vielen Dank! :) (PostGres 8.2.5) Musste auch den “Dubios User”-Fix durchführen (hab das Script vorher mit dem Finder+Identifizierung in das Verzeichniss geschoben).

  10. Bernd sagte:

    Sun Dec 23 18:20:49 UTC 2007

    Hat alles super funktioniert (8.2.5), vielen Dank für die Anleitung. Leider funktioniert die Installation vom Postgres-Gem nicht :-(

    Mein Log sieht genau so aus wie das hier:

    http://pastie.caboo.se/pastes/131771

    http://64.233.183.104/search?q=cache:-ar3t1onNNAJ:pastie.caboo.se/pastes/131771+compat.c:20:+error:+redefinition+of+parameter+‘PQdescribePrepared’compat.c:+In+function+‘PQsetClientEncoding’:&hl=de&ct=clnk&cd=1&client=safari

    Kann jemand helfen?

  11. Helge sagte:

    Sat Dec 29 17:42:04 UTC 2007

    Rabbit: die Kernelparameter legst du (wie auch unter 10.4!) in /etc/sysctl.conf ab, zB: —snip:/etc/sysctl.conf— kern.sysv.shmmax=167772160 kern.sysv.shmall=65536 —snap— Die Werte sollte man auf jeden Fall anheben, damit die sharedbuffers bzw workmem Parameter in der postgresql.conf auf annehmbare Werte gesetzt werden koennen.

  12. Klaus Hartl sagte:

    Thu Jan 24 17:17:16 UTC 2008

    @Bernd - ich hatte das gleiche Problem, folgendes hat geholfen:

    sudo env ARCHFLAGS=”-arch i386” gem install postgres

    hier gefunden: http://www.justatheory.com/computers/programming/ruby/postgresgemon_leopard.html

  13. Medman sagte:

    Mon Feb 04 19:25:25 UTC 2008

    Hallo Martin,

    zuerst mal vielen Dank für die super Anleitung - jetzt hab ich einen funktionierenden Postgres Server unter Leopard. Ich hab jetzt aber ein Problem. Wenn ich mich mit dem Tool “pgAdmin III” auf den Server verbinde erhalte ich folgende Meldung, sobald ich eine Datenbank öffne:

    The server lacks instrumentation functions.

    ….PostgreSLQ 8.2 and above include the instrumentation functions in the “adminpack” contrib module. After the module is installed, you need to create the instrumentation functions in your maintenance database using the admin.sql script (admin81.sql for PostgreSQL 8.1) which are usually located in the pgsql share directory (e.g. /usr/local/pgsql/share) …

    Wie kann ich denn dieses contrib Module “adminpack” installieren?

    Wäre halt cool, wenn man das “offizielle” GUI Frontend mit Deiner Art der Installation laufen lassen könnte.

    Danke für Tips.

  14. Ralf Hessmann sagte:

    Tue Feb 05 14:15:53 UTC 2008

    Martin, vielen Dank für diese präzise Anleitung !

    Ich musste nur die gem-Installation anpassen:

    sudo env ARCHFLAGS=’-arch i386’ gem install postgres (Pfadeangaben waren nicht nötig).

    Und wegen meiner CutAndPaste-Methode bin ich über eine kleine Namensungleichheit in der Anleitung gestolpert:

    “org.postgres.postmaster.plist” und “/…/org.postgresql.postmaster.plist”

    Nun läuft PostgreSQL 8.3 prima.

    Gruß Ralf

  15. Medman sagte:

    Wed Feb 06 11:11:17 UTC 2008

    Nochmal zur Aktiviertung des adminpack in Deiner Installation. Dazu habe ich folgende Information gefunden - läuft problemlos und pgAdmin III nervt nicht mehr mit “fehlendem Adminpack” Dauermeldungen.

    http://www2.russbrooks.com:8080/2007/10/7/postgresql-on-mac-os-x-10-4-install-notes

  16. Martin Maciaszek sagte:

    Mon Feb 11 05:58:04 UTC 2008

    Danke für den Hinweis auf die falschen Dateinamen des Launchd-Skriptes. Ich habe es korrigiert.

  17. Heiko Thimm sagte:

    Fri Feb 15 11:35:28 UTC 2008

    Vielen Dank für diese Anleitung. Ich habe einige fertige Pakete ausprobiert, die immer wieder an der einen oder anderen Stelle nicht weiter kamen. Hier lief alles wie am Schnürchen. Grosses Kino!

  18. Tilman sagte:

    Wed Jul 16 15:11:36 UTC 2008

    Hallo,

    leider habe ich ein kleines Problem mit dem angegeben Skript (zur “Änderung” der Links) Ich bekomme, wenn ich das Skript aufrufe (./symlink_pgsql.sh) immer folgenden Fehler :

    usage: ln [-Ffhinsv] sourcefile [targetfile] ln [-Ffhinsv] sourcefile … targetdir link sourcefile targetfile

    Hast einer eine Idee?

    Der Aufruf von id _postgres liefert noch das gewünschte Ergebnis. Den Quelltext von PostgreSQL habe ich im “Applications” Ordner entpackt.

  19. Martin Maciaszek sagte:

    Tue Jul 22 00:29:03 UTC 2008

    Hmm, also die Fehlermeldung kann ich mir nicht ganz erklären. Wurde PostgreSQL denn in /Library/PostgreSQL installiert? Existieren in /usr/local die bin/, man/man1 sowie man/man7-Verzeichnisse?

    Mein Vorschlag wäre, im Skript vor der Zeile mit “sudo ln -nfs…” noch folgende Zeile einzufügen:

    sudo mkdir -p $CUR_DIR

    Damit sollten die möglicherweise fehlenden Zielverzeichnisse erstellt werden.

Hinterlasse einen Kommentar