11 November 2007
linux / unix kernel parameters
I have a confession to make: the linux/unix kernel parameters have always been somewhat of a mistery to me and while I have installed several databases on linux and solaris systems I never realy understood how to tune them. I just followed the oracle installation documentation and metalink note 169706.1.
But recently I had to perform an installation on a 64bit linux system. The database in question was going to be used to develop a data warehouse system and the company asked to have at least a buffer cache of 4 GB. Now the box had 16 GB of ram so this requirement should not pose any problem.
So I started preparing the os for the installation and looked to
metalink for the recommended kernel values. At that point I
noticed that the value for the shmmax parameter on linux 64bit
was stated as “max(ram in bytes, 4GB) / 2″
“max(ram in bytes/2, 4 GB * 1024^3)”. This limit of 4 GB seems a
little bit strange to me for a 64bit system, so I posted a
service request on this and started a quest for more information
on the kernel parameters.
I found an excellent explanation
here, but after reading it I started to ask myself more
questions on the values recommended by Oracle in the
installation guide and on metalink.
As I understand it, the
shmmax parameter is
supposed to be the maximum size of a single shared memory
segments (and the oracle sga is build out of these shared memory
segments). The shmmni parameter gives the
maximum number of shared memory segments system wide and
shmall gives the total amount of shared memory
(expressed in pages).
If I combine the 3 definitions I understand that the maximum
shared memory will be the minimum between shmmax * shmmni and
shmall * page_size.
When I calculate the parameters with the values specified in metalink note 169706.1 (for my system with 16 GB ram) I get the following results:
shmmax = min(4294967296, RAM in bytes) /2 = min(4294967296, 17179869184)/2 = 4294967296/2 = 2147483648shmmax = min(RAM in bytes / 2 , 4294967296) = min (17179869184 / 2, 4294967296) = 4294967296
shmmni = 4096
shmall = shmmax / page_size = 2147483648 / 4096 = 524288
shmall = shmmax / page_size = 4294967296 / 4096 = 1048576
Which would mean that on my system I get a maximum of 2 GB 4 GB of shared memory, and thus a maximum sga of
2GB 4 GB (actually less, because this limit is
system wide and not only for my oracle instance). Needless to
say that when you are needing a 64bit system, this 2 GB
4 GB limit is a little bit on the low side…
In metalink note 169706.1 there is, next to the shmall
parameter, a link to another note (301830.1)
which states to set the shmall parameter to “ram size /
page_size” instead of shmmax / page_size. For my system with 16
GB of ram, this would give a shmall of 4194304 instead of 524288
and thus indeed fixing my problem.
Also if you would compare the proposed values in the
installation guide with those from metalink you will notice that
the shmall in the installation guide (2097152) is much higher
then on metalink (allowing for 8 GB of shared memory when your
pagesize is 4096) and that there is no 4GB limitation in the
calculation of the shmmax parameter.
During my searh Oracle also responded on my SR on metalink,
saying that the 4 GB limit in the shmmax calculation is not an
os limit but an oracle limit. They also said that this was
because 4GB is the maximum size of a core dump. Now what the
size of the core dump has to do with the size of a shared memory
segment is yet unclear to me, and it also makes me wonder if my
calculation of shmmax is correct. (After having received
some feedback by oracle it indeed turned out that my formulla
for shmmax was not correct, so I have made the necessary
adjustments in the post)
I will keep searching for this and update the post when I have
more information.
shmmax and solaris 10
A couple of days later, I needed to install oracle on a
solaris 10 system. Now with solaris 10 the way to specify kernel
parameters differs from the prior solaris versions. You now no
longer need to put your kernel parameters in the /etc/system
file, but instead use projects and projmod.
Because of past experiences on solaris 10 I already knew that
the oracle installation guide was not very correct on how to
work with projects (and because of my newly gained understanding
of the kernel parameters) I started to search for more
information on solaris 10 kernel parameters.
I soon found out that the parameter project.max-shm-memory
which is replacing the old shmmax parameter differs not only in
name and how to set it (note that using prctl to set the
kernel parameter, as suggested in the installation guide will
make the parameter not persistant), but
also in definition!
When you look at the
solaris tunable parameters reference manual you will note
that the parameter is not specifying the maximum size of a
single shared memory segment, but instead the maximum
shared memory for your entire project. In the
installation guide, however, oracle is still using the same
value for the new project.max-shm-memory parameter as with the
old shmmax parameter. So when you follow the recommended values
for the installation guide you would suddenly limit the total
sga size for all databases on your system to 4GB (unless you use
different users with different projects for your databases).
So be warned: when it comes to kernel parameters, don’t just take the values specified in the installation guide.
I have made some corrections in the past after receicing some more feedback from oracle.
As it turned out, I misinterpreted the formulla for shmmax on metalink.
It should be “max(ram in bytes/2, 4 GB * 1024^3)” and not “max(ram in bytes, 4GB * 1024^3) / 2″.
If you use this formulla in your calculations you would get a maximum of 4 GB shared memory instead of 2 GB.
Still waiting on feedback about the core dump limitation.
Comment by dhoogfr — 13 November 2007 @ 12:00
Pingback by linux / unix kernel parameters follow-up « Irrelevant thoughts of an oracle DBA — 27 November 2007 @ 21:21
Nice article
Comment by everton r — 14 July 2008 @ 22:50