Linux Shell Limits

Most Oracle database installations on Linux require configuration of shell limits. A typical configuration requires the following changes

Add the following lines to /etc/security/limits.conf

oracle           soft    nproc           2047
oracle           hard    nproc           16384
oracle           soft    nofile          1024
oracle           hard    nofile          65536

Additional memlock limits are required if large pages are configured. The values of these limits is dependent on the number of huge pages allocated. One also occasionally sees other limits such as the stack limit increased.

Add the following line to /etc/pam.d/login

session    required     pam_limits.so

Add the following lines to /etc/profile

if [ $USER = "oracle" ]; then
  if [ $SHELL = "/bin/ksh" ]; then
    ulimit -u 16384
    ulimit -n 65536
  else
    ulimit -u 16384 -n 65536
  fi
fi

I normally reboot the system after configuring the above settings.

During an Enterprise Manager Grid Control installation this week, we made the above changes. But when we tried to login to Oracle we hit the following error:

login as: oracle
oracle@vm7's password:
Last login: Wed Jan 19 05:39:00 2011 from 192.168.5.100
-bash: ulimit: open files: cannot modify limit: Operation not permitted

This error did not occurred if we logged in as root and then entered

[root@vm7]# su - oracle

After some investigation the cause of this error was identified. In /etc/ssh/sshd_config there is a parameter called UsePAM which enables PAM authentication. If this parameter is not set then it defaults to "no". I think it is normally overridden during installation. In order to allow user limits to be set the value should be "yes"

UsePAM=yes

The sshd service must be restarted for the parameter change to take effect:

[root@vm7]# service sshd restart

If the change is successful the new shell limits should be reported by the ulimit command. For example:

[oracle@vm7]$ ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 26560
max locked memory       (kbytes, -l) 1148576
max memory size         (kbytes, -m) unlimited
open files                      (-n) 65536
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 10240
cpu time               (seconds, -t) unlimited
max user processes              (-u) 16384
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

In the above example the limits of interest are open files (-n) which should be 65536 and max user processes (-u) which should be 16384.

In many documents (including some Oracle 11gR2 installation guides) the following lines are recommended for /etc/profile

if [ $USER = "oracle" ]; then
  if [ $SHELL = "/bin/ksh" ]; then
    ulimit -p 16384
    ulimit -n 65536
  else
    ulimit -u 16384 -n 65536
  fi
fi

Not many sites use the Korn shell with Linux but if you do the following error will occur during login:

login as: oracle
oracle@vm7's password:
Last login: Wed Oct 13 07:25:04 2010 from 192.168.5.100
/etc/profile[58]: ulimit: pipe: is read only

The error occurs because the ulimit -p parameter specifies the number of 512-byte blocks for pipe buffering. The Korn shell man page (man ksh) lists most ulimit parameters, but omits the one we need which is -u to specify the number of processes. So /etc/profile should contain:

if [ $USER = "oracle" ]; then
  if [ $SHELL = "/bin/ksh" ]; then
    ulimit -u 16384
    ulimit -n 65536
  else
    ulimit -u 16384 -n 65536
  fi
fi

In the Korn shell we can confirm this using ulimit -a

[oracle@vm7]$ ulimit -a
address space limit (kbytes)   (-M)  unlimited
core file size (blocks)        (-c)  0
cpu time (seconds)             (-t)  unlimited
data size (kbytes)             (-d)  unlimited
file size (blocks)             (-f)  unlimited
locks                          (-L)  unlimited
locked address space (kbytes)  (-l)  1148576
nofile                         (-n)  65536
nproc                          (-u)  16384
pipe buffer size (bytes)       (-p)  4096
resident set size (kbytes)     (-m)  unlimited
socket buffer size (bytes)     (-b)  4096
stack size (kbytes)            (-s)  10240
threads                        (-T)  not supported
process size (kbytes)          (-v)  unlimited

In the above example nofile (-n) should be 65536 and nproc (-u) should be 16384