Tuning/tuneable kernel parameters

Note: Oracle 8.1.x seems to work fine with Linux 2.4.x kernels with no modifications

Note 2: If you see anything wrong, out of date, or something that should be changed for the better, please let me know!

The linux kernel has many parameters that may be tuned, and are not well documented.
Shared memory has been a big issue with the advent of Oracle on linux, and so has large
memory support ( > 1Gb).
Huge Shared Memory Segments

/proc/sys/kernel/shmmax

cat /proc/sys/kernel/shmmax
1999999999
 

shmmax controls the maximum amount of memory to be allocated for shared memory,
1,999,999,999 in this instance.


include/asm-i386/shmparam.h
 

shmparam.h contains definitions for the shared memory structures.


#define _SHM_ID_BITS 7
#define _SHM_IDX_BITS 16
 

_SHM_ID_BITS + _SHM_IDX_BITS must be <= 24 on the i386


#define SHMMAX 0xA000000 /* max shared seg size (bytes) */
#define SHMMIN 1 /* min seg size */
#define SHMMNI 200 /* max # segments system-wide */
#define SHMSEG 200 /* max shared segments/process */
 

In this case, the maximum shared segment is 167,772,160 bytes, with a total maximum segments of 200, and a maximum of 200 segments / process.
include/linux/sem.h
 
sem.h defines how shared memory is to be used:  The number of semaphore identifiers, number of semaphores per ID, max total semaphores, max number of operations per semop call,  etc.  Oracle is concerned primarily with the numer of semaphores per ID.  In order to achieve the results that follow:
#define SEMMNI  128  ?  max # of semaphore identifiers
#define SEMMSL  512  <= 512 max num of semaphores per id 
#define SEMMNS  (SEMMNI*SEMMSL)  ? max # of semaphores in system 
#define SEMOPM  100  ~ 100 max num of ops per semop call 
#define SEMVMX  196608 semaphore maximum value 

include/asm-i386/page.h


NOTE
Kernel versions greater than 2.2.10 define this in the make config portion of kernel setup, so this does not apply to kernels after 2.2.10

DO NOT CHANGE:


include/asm/i-386/page.h
arch/i386/vmlinux.lds

IF YOUR KERNEL IS > 2.2.10


page.h contains many memory structure definitions, one of them being the maximum amount of physical ram that is supported.


#define __PAGE_OFFSET (0x80000000)

This allows up to 2Gb of ram. The stock value is 0xC0000000 For a maximum of 1Gb of ram. As documented in page.h, this change requires a complimentary change to the kernel linker script, vmlinux.lds:
arch/i386/vmlinux.lds . = 0x80000000 + 0x100000;
 
This will link the kernel with support for up to 2Gb of ram. The stock value is again 0xC0000000, as these values must compliment each other. With the above modifications and a subsequent recompilation of the linux kernel, the system is ready to support an application that needs an insane amount of memory space.
Oracle will be the test subject in this case. Normal output of Oracle installed on an un-modified system with 512Mb of ram is:
SVRMGR> startup
ORACLE instance started.
Total System Global Area 4554000 bytes
Fixed Size  48400 bytes
Variable Size  4227072 bytes
Database Buffers 204800 bytes
Redo Buffers  73728 bytes

With the proper kernel modifications (and Oracle modifications detailed below), the parameters expand as follows:
 
SVRMGR> startup
ORACLE instance started.
Total System Global Area 469019920 bytes
Fixed Size 48400 bytes
Variable Size 261804032 bytes
Database Buffers 204800000 bytes
Redo Buffers 2367488 bytes

Clearly, Oracle is now ready for some real data space. However, the application itself must be modified to essentially lower it's entry point into the system's memory. Since it's algorithm is a bit odd, this allows it to utilize more physical ram.


1. cd $ORACLE_HOME/rdbms/lib
2. rm ../../lib/libclntsh.so.1.0
3. make clean
4. make ksms.s
5. Edit ksms.s and change the offset: .

set sgabeg,0X20000000 --->
.set sgabeg,0X0A000000
536,870,912 > 167,772,160
Oracle is linked at install time with the default value of 0x20000000.
6. make ksms.o
7. make
8. make install
 
This will allow Oracle to better utilize the shared memory segments. The upper limits appear to be 470Mb for one instance of Oracle at this time. Oracle's shared memory usage can be seen with ipcs(8):


[oracle@db3 lib]$ ipcs
 
------ Shared Memory Segments ------
key shmid owner perms bytes nattch
0xa3f82e08 800 oracle 640 469377024 7
------ Semaphore Arrays --------
key semid owner perms bytes nsems
0x00000000 2048 oracle 640 512
0x00000000 2177 oracle 640 512
0x00000000 2178 oracle 640 26
------ Message Queues --------
key msqid owner perms used-bytes messages


Questions? Comments?