Parametrizacion del kernel en linux: swappiness

Hoy vamos a ver una parámetro poco documentado de la relaccion entre Linux y Oracle.
Cuando miramos las recomendaciones de Oracle para el kernel a la hora de instalarlo en un sistema operativo Linux nos encontramos con:
Configuring Kernel Parameters and Resource Limits

fs.aio-max-nr = 1048576
fs.file-max = 6815744
kernel.shmall = 2097152
kernel.shmmax = 536870912
kernel.shmmni = 4096
kernel.sem = 250 32000 100 128
net.ipv4.ip_local_port_range = 9000 65500
net.core.rmem_default = 262144
net.core.rmem_max = 4194304
net.core.wmem_default = 262144
net.core.wmem_max = 1048586

Pero no hay ni rastro de este parámetro swappiness al que hago referencia. Si miramos en la wikipedia nos indica que :

Swappiness es una propiedad del Núcleo Linux que permite establecer un balance entre el uso del Espacio de intercambio (swap en inglés, por eso el nombre de la propiedad) y la Memoria de acceso aleatorio (RAM).
El swappiness puede tomar valores desde el 0 hasta el 100. Si se establece 0 el núcleo intentará no hacer intercambio, mientras que si se establece 100 el sistema intentará mantener la Memoria de acceso aleatorio lo más libre posible haciendo intercambio.

Este valor está configurado por defecto en las distribuciones Linux a 60 ,y como os decía no encontramos apenas referencias a el en la documentación de Oracle.Pero ¿que significa este valor del swappines a 60?

Significa que, cuando lleguemos al uso de ese 60% de memoria el proceso kswapd se lanzará a hacer su trabajo, haciendo que el rendimiento de nuestra base de datos caíga en picado por el uso de recursos del sistema del proceso kswapd.

¿Que hacer si esto ocurre?

La solucion pasa por modificar este parámetro para que el kswapd no empiece hasta un 10% de memoria libre.

echo vm.swappiness=10 >> /etc/sysctl.conf
sysctl -p

Como os comentaba, esta opcion del kernel de linux está muy poco documentada por parte de Oracle, yo solamente he encontrado referencias a ella en:

Clonación de maquinas virtuales con VirtualBox

Esta entrada es una pequeña prolongacion de la entrada , donde partimos de la base de que tenemos un servidor Linux en un entorno VirtualBox con los interfaces de red y los discos necesarios para llevar a cabo una instalación de Oracle RAC

El proceso de clonación de este servidor a uno que llamaremos dataguard sería:

  • Clonado de disco

    Una vez hayamos levantado esta nueva máquina copiada tendremos que llevar a cabo las siguientes modificaciones:

    • Fichero /etc/sysconfig/networ: En este fichero tendremos que poner el nombre del servidor
    • Fichero /etc/sysconfig/network-scripts/ifcfg-eth1 en este fichero habremos de modificar la IP de la eth1
    • Fichero /etc/sysconfig/network-scripts/ifcfg-eth2 en este fichero habremos de modificar la IP de la eth2
    • Fichero /etc/sysconfig/network-scripts/ifcfg-eth2 en este fichero habremos de modificar la IP de la eth2
    • Fichero /etc/udev/rules.d/70-persistent-net.rules: En este fichero el udev tendrá informacion de las interfaces de red de la máquina original, con lo que, deberemos de vaciar todas las líneas para que nuestros interfaces de red funcionen correctamente.

Con todo esto, tendremos ya nuestra infraestuctura virtual para poder hacer pruebas con el RAC

Creación de una plataforma de pruebas RAC con VirtualBox

Hoy vamos a crear otro entorno de pruebas para jugar con el RAC, esta vez lo haremos con la herramienta de virtualización de Oracle VirtualBox ,en nuestro caso bajo un OSX 10.8

Los pasos que seguiremos son:

Creación de máquina virtual y sistema operativo

Para empezar, al igual que hicimos  con el KVM instalaremos un servidor linux normal y corriente  al que llamaremos Plantilla.Las características de la máquina serán:

  • 4 Gb de RAM
  • 4 Mb de targeta gráfica
  • 1 Imagen de DVD montada con los fuentes de Oracle
  • 4 Gb de SWAP
  • 16Gb de disco duro
  • Eliminamos el Audio y los USB

El sistema operativo que vamos a instalar es la última distribución de Oracle Linux (en nuestro caso 6.3), haremos la instalación mínima por defecto.
Actualizacion tenemos una entrada «futura» en la que se indica como hacer esta instalación de manera rápida Instalación Básica de Linux para un Oracle 11

Creación de la infraestructura de red

Lo primero que vamos ha hacer es crear las 2 redes privadas que tendrán nuestros equipos.
En este ejemplo los equipos van a tener 3 interfaces de red:

  • Eth0: Ip virtual de la red 192.168.1.X que hara la funcion de virtual
  • Eth1: Ip virtual de la red 192.168.2.X que hara la funcion de privada
  • Eth2: Ip de host asignada por el VirtualBox (10.0.4.X ) y que tendrá salida a internet

Desde las preferencias de nuestro virtualbox y crearemos 2 redes solo anfitrion de la siguiente forma:
Imagen de pantalla adaptador

Imagen de pantalla dhcp

Una vez repetida esta acción con las 3 redes, tendremos un apartado de configuración de red del VirtualBox similar a este:
red

Lo siguiente que tenemos que hacer es añadir 3 interfaces de red a nuestro equipo virtual asignando a cada nueva interfaz de red a una de estas 3 redes solo host que hemos creado.
En la pestaña de red tendremos nuestro Adaptador 1 creado automáticamente por la instalación de la forma

Nosotros tendremos que añadir el resto de adaptadores para que queden

donde debería de haber una correspondencia entre

  • Adaptador2 ->vboxnet1
  • Adaptador3 ->vboxnet2

Creación de arquitectura de discos

Nuestro siguiente punto va a ser crear nuestros discos compartidos, para ello abriremos una ventana de terminal en el equipo en el que estemos instalando el VirtualBox y nos iremos a el directorio donde esten instalados las máquinas (en caso del OSX es en /Users/$usuario/VirtualBox VMs ) y ejecutaremos los siguientes comandos

mkdir discos
cd discos 
VBoxManage createhd --filename asm1.vdi --size 5120 --format VDI --variant Fixed
VBoxManage createhd --filename asm2.vdi --size 5120 --format VDI --variant Fixed 
VBoxManage createhd --filename asm3.vdi --size 5210 --format VDI --variant Fixed 
VBoxManage createhd --filename asm4.vdi --size 1024 --format VDI --variant Fixed 
VBoxManage createhd --filename asm5.vdi --size 1024 --format VDI --variant Fixed

Los ponemos como compartidos

VBoxManage modifyhd asm1.vdi --type shareable
VBoxManage modifyhd asm2.vdi --type shareable
VBoxManage modifyhd asm3.vdi --type shareable
VBoxManage modifyhd asm4.vdi --type shareable
VBoxManage modifyhd asm5.vdi --type shareable

Con esto tenemos creados los discos que usaremos en el RAC, ahora tenemos que añadirlos a nuestra maquina virtual,para ello iremos a la pestaña Almacenamiento de nuestra máquina y crearemos un nuevo interfaz del tipo SCSI, a este almacenamiento le añadiremos los 5 discos quedando de la manera:

Configuraciones del servidor
Llegados a este punto, tenemos todo el hardware listo para nuestra máquina virtual y el siguiente paso será configurarlo dentro del servidor.
Arrancaremos la máquina

Primero añadiremos en los ficheros de configuracion los requisitos de Oracle, en el fichero /etc/sysctl.conf

fs.aio-max-nr = 1048576
fs.file-max = 6815744
kernel.shmall = 2097152
kernel.shmmax = 1054504960
kernel.shmmni = 4096
# semaphores: semmsl, semmns, semopm, semmni
kernel.sem = 250 32000 100 128
net.ipv4.ip_local_port_range = 9000 65500
net.core.rmem_default=262144
net.core.rmem_max=4194304
net.core.wmem_default=262144
net.core.wmem_max=1048586

Al fichero /etc/security/limits.conf

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

Y crearemos el usuario Oracle con:

groupadd -g 1000 oinstall
groupadd -g 1200 dba
useradd -u 1100 -g oinstall -G dba oracle
passwd oracle

En lo referente a las interfaces de red, añadiremos al fichero /etc/hosts las líneas:


# HOST eth0 
# Direcciones para nuestros equipos (en una red normal seria publicas o de host)
192.168.1.1  exodar-priv.pamplona.name    exodar-priv  exodar
192.168.1.2  rac1-priv.pamplona.name    rac1-priv  rac1
192.168.1.3  rac2-priv.pamplona.name    rac2-priv  rac2
192.168.1.4  rac3-priv.pamplona.name    rac3-priv  rac3
192.168.1.5  rac4-priv.pamplona.name    rac4-priv  rac4
192.168.1.24 plantilla-priv.pamplona.name       plantilla-priv

#Virtual  Eth0 que cogeran los local listeners
192.168.1.12  rac1-vip.pamplona.name     rac1-vip
192.168.1.13  rac2-vip.pamplona.name     rac2-vip
192.168.1.14  rac3-vip.pamplona.name     rac3-vip
192.168.1.15  rac4-vip.pamplona.name     rac4-vip
#ETH0 que usara el RAC, ScaN  comentadas ya que estan configuradas en round robin de dns
#192.168.2.20   ractest.pamplona.name   ractest
#192.168.2.21   ractest.pamplona.name   ractest
#192.168.2.22   ractest.pamplona.name   ractest

#interconexcion  Eth1
192.168.2.1  exodar-conn.pamplona.name     exodar-conn
192.168.2.2  rac1-conn.pamplona.name     rac1-conn
192.168.2.3  rac2-conn.pamplona.name     rac2-conn
192.168.2.4  rac3-conn.pamplona.name     rac3-conn
192.168.2.5  rac4-conn.pamplona.name     rac4-conn


y configuraremos las interfaces de red modificando los ficheros

/etc/sysconfig/network-scripts/ifcfg-eth0

DEVICE=eth0
BOOTPROTO=none
IPADDR=192.168.1.24
NETMASK=255.255.255.0
ONBOOT=yes
TYPE=Ethernet
IPV6INIT=no
NAME=eth0

/etc/sysconfig/network-scripts/ifcfg-eth1

DEVICE=eth1
BOOTPROTO=none
IPADDR=192.168.2.24
NETMASK=255.255.255.0
ONBOOT=yes
TYPE=Ethernet
IPV6INIT=no
NAME=eth1

/etc/sysconfig/network-scripts/ifcfg-eth2

DEVICE=eth2
BOOTPROTO=dhcp
ONBOOT=yes
TYPE=Ethernet
IPV6INIT=no
NAME=eth2

Después crearemos nuestros discos de ASM, para ello, primero habremos de particionar los discos /dev/sdb,/dev/sdc,/dev/sdd,/dev/sde y /dev/sdf . EL proceso será el mismo para los 5

# fdisk /dev/sdb
Command (m for help): n
Command action
   e   extended
   p   primary partition (1-4)
p
Partition number (1-4): 1
First cylinder (1-16065, default 1):
Using default value 1
Last cylinder or +size or +sizeM or +sizeK (1-16065, default 16065):
Using default value 16065

Command (m for help): p
Disk /dev/sdb: 5368 MB, 5368709120 bytes
255 heads, 63 sectors/track, 652 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0xa03e3f05
 Device Boot      Start         End      Blocks   Id  System
/dev/sdd1               1         652     5237158+  83  LinuxLinux

Command (m for help): w
The partition table has been altered!
Calling ioctl() to re-read partition table.
Syncing disks.
#

Tras haber particionado los 5 discos crearemos discos ASM sobre ellos con el comando

# /usr/sbin/oracleasm createdisk DISK1 /dev/sdb1
Writing disk header: done
Instantiating disk: done
# /usr/sbin/oracleasm createdisk DISK2 /dev/sdc1
Writing disk header: done
Instantiating disk: done
# /usr/sbin/oracleasm createdisk DISK3 /dev/sdd1
Writing disk header: done
Instantiating disk: done
# /usr/sbin/oracleasm createdisk DISK4 /dev/sde1
Writing disk header: done
Instantiating disk: done
# /usr/sbin/oracleasm createdisk DISK5 /dev/sdf1
Writing disk header: done
Instantiating disk: done
# 

Podremos comprobar que los discos estan creados con la orden


[root@pruebas ~]# oracleasm listdisks
DISK1
DISK2
DISK3
DISK4
DISK5

Y con eso ya tenemos un servidor que nos puede servir de plantilla para nuestras futuras pruebas del RAC.
En la siguiente entrada duplicaremos los servidores e instalaremos nuestro Oracle RAC 11g

oracleasm cuando no tienes la versión excta del kernel

Hoy vamos a ver una solucion casera y no soportada para cuando no tenemos la versión exacta del kernel y el módulo oracleasm.

El módulo oracleasm viene empaquetado (para RedHat,Centos) en un fichero .rpm y lo deja en el directorio /lib/modules/2.6.XX/kernel/drivers/addon/oracleasm/  . El problema lo tenemos cuando por algun motivo es necesario el actualizar la version del kernel y no hay un paquete específico de asmlib para este kernel.

En la mayoría de las veces, la nueva  version del kernel es un cambio menor de versión, y el módulo de la asmlib funcionará correctamente, nuestro problemas será que el sistema operativo intentará montar ese módulo para la versión del kernel que tenemos . Si tenemos la version YY  el sistema operativo lo buscará en /lib/modules/2.6.YY/kernel/drivers/addon/oracleasm/  y,  como hemos dicho antes, el módulo estará en /lib/modules/2.6.XX/kernel/drivers/addon/oracleasm/  lo que significa que en el arranque no cargará el módulo –> No ira el ASM –> No arrancará las instancias.

La solucion (como decía antes no soportada ) es simlemente asegurarnos que, vamos a tener nuestro modulo en el directorio que lo va a buscar el sistema operativo en el arranque.

Para ello miraremos al arrancar si exsiste el fichero  del módulo para  nuestro kernel  /lib/modules/2.6.YY/kernel/drivers/addon/oracleasm/oracleasm.ko , si no exsiste creamos el directorio y lo copiamos, si exsite, salimos y listo .

El script quedaría tal que:

#!/bin/bash
#
#  Script que copia el módulo de  oracleasm a directorio
#   kernel/drivers/addon/oracle de nuestro kernel actual
#
case "$1" in
start )
  ORIG_MODULE="/lib/modules/2.6.18-308.13.1.el5/kernel/drivers/addon/oracleasm/oracleasm.ko"
  MODULE_DIR=/lib/modules/`uname -r`/kernel/drivers/addon/oracle
  if [ ! -f ${MODULE_DIR} ]
  then
      mkdir -p ${MODULE_DIR}
      cp -p ${ORIG_MODULE} ${MODULE_DIR}
  fi
  depmod -a
;;
stop)
   true
;;
*)
    echo $"Usage: $0 {start|stop}"
    RETVAL=1
;;
esac

Una de las cosas que tenemos que tener en cuenta es que esto funcionará solo para versiones menores del kernel.

He de advertir de nuevo que, esta solución no es una solución soportada , con lo que su uso  podría limitar el soporte que oracle pueda darnos en caso de surgir algún problema, sin embargo puede ser una solucion muuy cómoda en máquinas de desarrollo,test o servidores en los que, la base de datos comparte equipo con servidores de aplicaciones o frontales web y la actualizacion de kernel no es una opcion sino una necesidad.