|
Running PostgreSQL in a jail is interesting. There are shared memory issues which can
be resolved by setting security.jail.sysvipc_allowed via sysctl. I tried that.
I failed. The problem I encountered during initdb is:
# su -l pgsql -c initdb
The files belonging to this database system will be owned by user "pgsql".
This user must also own the server process.
The database cluster will be initialized with locale C.
creating directory /usr/local/pgsql/data ... ok
creating directory /usr/local/pgsql/data/global ... ok
creating directory /usr/local/pgsql/data/pg_xlog ... ok
creating directory /usr/local/pgsql/data/pg_xlog/archive_status ... ok
creating directory /usr/local/pgsql/data/pg_clog ... ok
creating directory /usr/local/pgsql/data/pg_subtrans ... ok
creating directory /usr/local/pgsql/data/pg_twophase ... ok
creating directory /usr/local/pgsql/data/pg_multixact/members ... ok
creating directory /usr/local/pgsql/data/pg_multixact/offsets ... ok
creating directory /usr/local/pgsql/data/base ... ok
creating directory /usr/local/pgsql/data/base/1 ... ok
creating directory /usr/local/pgsql/data/pg_tblspc ... ok
selecting default max_connections ... 10
selecting default shared_buffers ... 50
creating configuration files ... ok
creating template1 database in /usr/local/pgsql/data/base/1 ... FATAL: could
not create shared memory segment: Function not implemented
DETAIL: Failed system call was shmget(key=1, size=1327104, 03600).
child process exited with exit code 1
initdb: removing data directory "/usr/local/pgsql/data"
I initially thought I had to set this flag on each of the jails. I was wrong.
After a bit of trial and error, I discovered the problem. I had added this value
to /etc/sysctl.conf:
# For PostgreSQL jails
security.jail.sysvipc_allowed=1
After a reboot, the above entry ensures this setting after a reboot:
# sysctl security.jail.sysvipc_allowed
security.jail.sysvipc_allowed: 1
When starting a jail, I noticed this:
# /etc/rc.d/jail start pg82
Configuring jails: sysvipc_allow=NO.
Starting jails: pg82.unixathome.org.
Why was it saying sysvipc_allow=NO? Additionally, in the jail and in the host
system, I was now seeing this:
# sysctl security.jail.sysvipc_allowed
security.jail.sysvipc_allowed: 0
Not only was the jail not getting the right value, the value in the host system
was being reset.
Looking at /etc/rc.d/jail for "Configuring jails", I found more clues
leading me to /etc/defaults/rc.conf, where I found this setting:
jail_sysvipc_allow="NO" # Allow SystemV IPC use from within a jail
Ahh, OK, so now I needed to set this in /etc/rc.conf
jail_sysvipc_allow="YES" # For PostgreSQL
After restarting the pg82 jail, I found the security.jail.sysvipc_allowed was correctly
set, in both the jail and the host. I tried the initdb again:
# su -l pgsql -c initdb
The files belonging to this database system will be owned by user "pgsql".
This user must also own the server process.
The database cluster will be initialized with locale C.
creating directory /usr/local/pgsql/data ... ok
creating directory /usr/local/pgsql/data/global ... ok
creating directory /usr/local/pgsql/data/pg_xlog ... ok
creating directory /usr/local/pgsql/data/pg_xlog/archive_status ... ok
creating directory /usr/local/pgsql/data/pg_clog ... ok
creating directory /usr/local/pgsql/data/pg_subtrans ... ok
creating directory /usr/local/pgsql/data/base ... ok
creating directory /usr/local/pgsql/data/base/1 ... ok
creating directory /usr/local/pgsql/data/pg_tblspc ... ok
selecting default max_connections ... 10
selecting default shared_buffers ... 50
creating configuration files ... ok
creating template1 database in /usr/local/pgsql/data/base/1 ... FATAL: could
not create semaphores: No space left on device
DETAIL: Failed system call was semget(1, 17, 03600).
HINT: This error does *not* mean that you have run out of disk space.
It occurs when either the system limit for the maximum number of
semaphore sets (SEMMNI), or the system wide maximum number of semaphores
(SEMMNS), would be exceeded. You need to raise the respective kernel parameter.
Alternatively, reduce PostgreSQL's consumption of semaphores by reducing its
max_connections parameter (currently 10).
The PostgreSQL documentation contains more information about configuring your system for PostgreSQL.
child process exited with exit code 1
initdb: removing data directory "/usr/local/pgsql/data"
I am familiar with this message. It is related to kernel settings. I added these values
to /boot/loader.conf on the host system and rebooted:
kern.ipc.semmni=256
kern.ipc.semmns=512
kern.ipc.semmnu=256
The reboot is necessary because those settings are read-only and cannot be modified after
booting the kernel. With those changes, the initdb ran to completion:
# su -l pgsql -c initdb
The files belonging to this database system will be owned by user "pgsql".
This user must also own the server process.
The database cluster will be initialized with locale C.
creating directory /usr/local/pgsql/data ... ok
creating subdirectories ... ok
selecting default max_connections ... 100
selecting default shared_buffers/max_fsm_pages ... 24MB/153600
creating configuration files ... ok
creating template1 database in /usr/local/pgsql/data/base/1 ... ok
initializing pg_authid ... ok
initializing dependencies ... ok
creating system views ... ok
loading system objects' descriptions ... ok
creating conversions ... 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
WARNING: enabling "trust" authentication for local connections
You can change this by editing pg_hba.conf or using the -A option the
next time you run initdb.
Success. You can now start the database server using:
postgres -D /usr/local/pgsql/data
or
pg_ctl -D /usr/local/pgsql/data -l logfile start
I was then able to start PostgrSQL, create users, etc. I repeated
the process for two other jails, then ran into this problem for the
third jail:
# su -l pgsql -c initdb
The files belonging to this database system will be owned by user "pgsql".
This user must also own the server process.
The database cluster will be initialized with locale C.
creating directory /usr/local/pgsql/data ... ok
creating directory /usr/local/pgsql/data/global ... ok
creating directory /usr/local/pgsql/data/pg_xlog ... ok
creating directory /usr/local/pgsql/data/pg_xlog/archive_status ... ok
creating directory /usr/local/pgsql/data/pg_clog ... ok
creating directory /usr/local/pgsql/data/pg_subtrans ... ok
creating directory /usr/local/pgsql/data/base ... ok
creating directory /usr/local/pgsql/data/base/1 ... ok
creating directory /usr/local/pgsql/data/pg_tblspc ... ok
selecting default max_connections ... 10
selecting default shared_buffers ... 50
creating configuration files ... ok
creating template1 database in /usr/local/pgsql/data/base/1 ... FATAL: could
not create shared memory segment: Cannot allocate memory
DETAIL: Failed system call was shmget(key=1, size=1122304, 03600).
HINT: This error usually means that PostgreSQL's request for a shared memory
segment exceeded available memory or swap space. To reduce the request size
(currently 1122304 bytes), reduce PostgreSQL's shared_buffers parameter
(currently 50) and/or its max_connections parameter (currently 10).
The PostgreSQL documentation contains more information about shared memory
configuration.
child process exited with exit code 1
initdb: removing data directory "/usr/local/pgsql/data"
I decided to double the settings in /etc/sysctl.conf on the host system:
kern.ipc.semmni=512
kern.ipc.semmns=1024
kern.ipc.semmnu=512
But that did not solve the problem. Stopping PostgreSQL on the other two jails did.
This allowed the initdb to complete. But I was still unable to get all the
PostgreSQL servers running in each jail.
After a few more trial and error attempts, I discovered that the settings I had in
/boot/loader.conf contained syntax errors. Instead of SETTING=VALUE, I had
SETTING: VALUE. Fixing that, and rebooting, allowed me to get all five instances
of PostgreSQL running concurrently. But there was a bit more to it than just that.
I tried various things. I tried running each postmaster on a different port
(didn't help). I also tried running each postmaster as a different GID (that did
help). That is the key. I will explain.
|