Fixing Postgres on Mac 10.7 Tiger for Django

I’m currently in the process of downsizing my number of computers to a single laptop (or maybe two… I mean who doesn’t need at least 2 laptops these days?), so I got a used macbook pro from a friend and have been trying to make the conversion to developing on it. So far I’ve spent far more time sysadmining on the mac than I have on ubuntu in the last 2 years. Not worth it for the pretty icons, but I really just go the macbook for the touchpad and battery life which are pretty gangbusters.

Anyways, setting up postgresql. Given that I’m not a Mac guy, I’m not 100% sure that everything I recommend here is the best way to do it, but I figured I’m not the only one who will run into these issues, so here’s my steps:

1) I set up my machine using pydanny’s snippet here: https://github.com/pydanny/pydanny-computer-setup/blob/master/mba-osx-lion.rst.

Here’s the postgres part:

$ sudo sysctl -w kern.sysv.shmall=65536
$ sudo sysctl -w kern.sysv.shmmax=16777216

Basically, what this is doing is setting up 2 kernel memory management values. If you are curious and want to see what the values are previous to changing them, you can do this:

$ sudo sysctl kern.sysv.shmall
$ sudo sysctl kern.sysv.shmmax

Then you use brew to install postgres and initialize a database to store all the info that postgres needs to run. The final command then is to actually start postgres running (the -D command specifies where the database you just initialized is located).

$ brew install postgresql
$ initdb /usr/local/var/postgres
$ postgres -D /usr/local/var/postgres

You probably don’t want to have to type that whole business out every time you want to reload/stop/start postgres though, so put this in you ~/bash_profile:

export PGDATA='/usr/local/var/postgres/'

Now you can leave off the -D /path/ part. Just type pg_ctl start to start up postgresql.

Troubleshooting

So that may have worked perfectly for you, but it didn’t for me.

Issue #1: Postgres comes bundled with Lion, or rather some someone decided that they would just put a box filled with shit into the OS and write postgres on it and hope no one noticed. Because of this, when you try to run psql, you’ll get a permission error. Bash is trying to use the wrong version of psql or whatever postgres binary you’re trying to run. To fix this, you need to put the brew installed binaries first on the path. Put this in your ~/.bash_profile:

export PATH=/usr/local/bin:$PATH

Issue #2: The kern.sysv.shmall and shmmax values from above didn’t work for me. It was working for a bit, but then stopped (weird huh? I’m thinking maybe that the shmall/shmmax that I set earlier got unset somehow). I kept getting nasty messages like this:

$ pg_ctl start
server starting
$ FATAL:  could not create shared memory segment:
Cannot allocate memory 
DETAIL:  Failed system call was shmget(key=5432001, size=16498688, 03600).
HINT:  This error usually means that PostgreSQL's request for a shared 
memory segment exceeded available memory or swap space, or exceeded your
kernel's SHMALL parameter.  You can either reduce the request size or 
reconfigure the kernel with larger SHMALL.  To reduce the request 
size (currently 16498688 bytes), reduce PostgreSQL's shared_buffers
parameter (currently 1536) and/or its max_connections parameter 
(currently 104).
The PostgreSQL documentation contains more information about 
shared memory configuration.

After spending a while reading the documentation and lamenting how much easier this would be if Apple spent as much time making their development environment work as they did printing money, I finally just upped the values a lot

$ sudo sysctl -w kern.sysv.shmmax=32768000
$ sudo sysctl -w kern.sysv.shmall=8000

One note on this: the shmall value is a value in pages (which are 1024 bytes * 4). The shmmax value (from what I could tell) has to be 4096*shmall, so I just picked a random value and now it works.

Issue #3: Django was giving me a connection error when trying to run syncdb (oddly enough, dbshell worked. I think this may have something to do with reading vs. writing, so it could be my fault). Here’s the last bit of traceback:

.../python2.7/site-packages/django/db/backends/postgresql_psycopg2/base.py", line 140, in _cursor
    self.connection = Database.connect(**conn_params)
psycopg2.OperationalError: could not connect to server: Permission denied
	Is the server running locally and accepting
	connections on Unix domain socket "/var/pgsql_socket/.s.PGSQL.5432"?

Someone in #django was kind enough to point me in the direction of this fix: change the HOST value in the database dictionary in settings.py to this:

'HOST': '/tmp',

Ok, so I agree. WTF. But everything seems to be working now, so I’m just going to roll with it. Hope this helps someone out there.

 

Comments

  1. Thanks for this. Total feel the WTF on “‘HOST’: ‘/tmp’,”

  2. Chris Shenton says:

    Just encountered this myself. When installing postgres with homebrew, it tells you to install such that the daemon runs as your username, instead of some privileged ‘postgres’ user. Specifying ‘/tmp’ tells the daemon to create the socket file that clients connect to into /tmp, a directory to which mortal users can write.

    If you use the default blank, the postgres daemon tries to create the socket in the /var/ directory, which mere mortals cannot write to. This is fine — and in fact more secure — when postgres is running as a privileged user, but fails since you don’t have rights to write there.

  3. Thank you…been regretting my upgrade to 10.7.3 for the last couple of hours.

  4. Fastest fixing experience ever! Thank you!

Speak Your Mind

*