25 agosto 2010

Instalar Oracle 11g R2 en CentOS 5.5

Hacia tiempo que no trabajaba con Red Hat, así que para este propósito decidí usar centOS ya que es un clon casi exacto de este, con la ventaja que tiene las actualizaciones gratuitas.

Estuve a punto de probar el entorno gráfico ligero que tiene la versión de servidor, pero estoy acostumbrado a trabajar sin él y como en esta máquina iba a entrar casi siempre por ssh, lo vi un gasto de memoria inútil. Por lo que durante la instalación a la hora de escoger los paquetes desmarqué gnome, y algunas funciones que no iba a utilizar, seguí los pasos correspondientes y deshabilité SELinux.

Los siguientes pasos no son necesarios pero los realicé por comodidad y seguridad. Instalé bash-completion para el autocompletado con el tabulador desde la consola

wget http://www.caliban.org/files/redhat/RPMS/noarch/bash-completion-20060301-1.noarch.rpm
rpm -ivh bash-completion-20060301-1.noarch.rpm
./etc/bash_completion

Configuré sudo para tareas administrativas y bloqueé el usuario root. Instalé y añadí el usuario con permisos para usarlo al grupo wheel

yum install sudo
usermod -G wheel usuario

Edité y descomenté la línea para dar permisos al grupo whell

visudo

%wheel ALL=(ALL) ALL

Ahora salgo del usuario root y deshabilito el login para esta cuenta.

sudo usermod --lock root

Cada vez que necesite una consola con root simplemente con este usuario escribimos

sudo su

Además añadí un PATH para abrir algunas aplicaciones más cómodamente. Busco el texto y lo dejo como se observa debajo, donde 500 es el EUID del usuario al que se aplica el PATH. Si queremos que se aplique a todos simplemente eliminamos el if

sudo vim /etc/profile

if [ "$EUID" = "500" ]; then
  pathmunge /sbin
  pathmunge /usr/sbin
  pathmunge /usr/local/sbin
fi

Al bloquear el login de root no disponía así del PATH, para disponer de él introduciendo sudo su (sudo -i o -l no funciona), hay que escribir lo siguiente después de la función pathmunge

sudo vim /etc/bashrc

pathmunge () {
...
}

if [ "$EUID" = "0" ]; then
  pathmunge /sbin
  pathmunge /usr/sbin
  pathmunge /usr/local/sbin
fi

Para instalar Oracle necesitas instalar unos cuantos paquetes y modificar unas configuraciones del sistema. Para ello creé un script para esta y las posibles próximas veces, que verifica si están hechos los cambios y si no los realiza y si queremos descomprime Oracle en la carpeta adecuada.

vim oracle.sh

#!/bin/bash -
#==========================================================================
#       ARCHIVO: oracle.sh 
#           USO: ./oracle.sh (/ruta/linux_11gR2_database_1of2.zip)/(No/no)
#
#   DESCRIPCION: Realiza las configuraciones necesarias para
#                instalar Oracle
#
#      OPCIONES: $1 (/ruta/linux_11gR2_database_1of2.zip)/(No/no)
#         NOTAS: Para saltar la copia/descompresión de Oracle $1=No/no
#    REQUISITOS: Tener permisos de root - $1
#         AUTOR: Nebur (Más Vale Manya ...), masvalemanya@gmail.com
#           WEB: http://masvale-manya.blogspot.com
#        CREADO: 18/08/10 13:08:28 CEST
#==========================================================================

set -o nounset                         # Treat unset variables as an error

#===  FUNCION  ============================================================
#        NOMBRE:  usuarios
#   DESCRIPCION:  Crea usuarios y grupos para Oracle
#    PARAMETROS:  $1 La contraseña del usuario oracle
#==========================================================================
usuarios ()
{
    grup_u=( "dba" "oinstall" "oracle" )
    grup_users=`echo ${#grup_u[*]}`
    for (( i=0;i<$grup_users;i++ )); do
        if [ $i != 2 ]; then
            if [ "$(grep -w "^${grup_u[$i]}" /etc/group)" = "" ]; then
                groupadd ${grup_u[$i]}
            fi
        else
            if [ "$(grep -w "^${grup_u[$i]}" /etc/passwd)" = "" ]; then
                useradd -g ${grup_u[1]} -G ${grup_u[0]} ${grup_u[$i]}
            else
                usermod -g ${grup_u[1]} -G ${grup_u[0]} ${grup_u[$i]}
            fi
        fi
    done
    echo -e "$1\n$1" | (passwd --stdin ${grup_u[$(( i - 1 ))]})
}    # ----------  end of function usuarios  ----------

#===  FUNCION  ============================================================
#        NOMBRE:  backup
#   DESCRIPCION:  Realiza copia de archivo.vell(n)
#    PARAMETROS:  $1 Ruta y nombre archivo
#==========================================================================
backup ()
{
    ext="vell"
    num=""
    while [ -e $1.$ext$num ]; do
        num=$(( num+1 ))
    done
    if [ $num != "" ]; then
        for (( i=0;i<$num;i++ )); do
            p_ext=$(( $num-$(( i+1 )) ))
            if [ $p_ext -eq 0 ]; then
                mv $1.$ext $1.$ext$(( $num-$i ))
            else
                mv $1.$ext$p_ext $1.$ext$(( $num-$i ))
            fi
        done
    fi
    cp $1 $1.$ext
}    # ----------  end of function backup  ----------

#===  FUNCION  ============================================================
#        NOMBRE:  modificar
#   DESCRIPCION:  Añade/modifica en archivo parámetros sueltos
#    PARAMETROS:  $1 parámetros a modificar - $2 valores de parámetros -
#                 $3 archivo a modificar
#==========================================================================
modificar ()
{
    OLD_IFS=$IFS
    IFS=''
    local a_parame="$1[*]"
    local loc_parame=(${!a_parame})
    local a_valor="$2[*]"
    local loc_valor=(${!a_valor})
    IFS=$OLD_IFS
    total=`echo ${#loc_parame[*]}`
  
    let primer=0
    let primero=0
    for (( i=0;i<$total;i++ )); do
        pre_sust="${loc_parame[$i]}${loc_valor[$i]}"
        sust="$(echo "$pre_sust" | sed "s/\.\*/ /g")"
        bus_c=$(grep -w "^$pre_sust" $3)
        bus_p=$(grep -w "^${loc_parame[$i]}" $3)
        if [ "$bus_c" = "" ]; then  
            if [ "$bus_p" = "" ]; then
                if [ $primero -eq 0 ] ; then
                    backup $3
                    ((primero++))
                fi
                if [ $primer -eq 0 ] ; then
                    echo " " >> $3
                    ((primer++))
                fi
                echo $sust >> $3
            else
                if [ $primero -eq 0 ] ; then
                    backup $3
                    ((primero++))
                fi
                bus_p=$(echo "$bus_p" | sed 's/\//\\\//g')
                                sust=$(echo "$sust" | sed 's/\//\\\//g')
                sed -i "s/$bus_p/$sust/" $3
            fi
        fi
    done
}    # ----------  end of function modificar  ----------

#===  FUNCION  ============================================================
#        NOMBRE:  modificar_b
#   DESCRIPCION:  Verifica/añade en archivo bucle especificado
#    PARAMETROS:  $1 parámetros a modificar - $2 linea inicial -
#          $3 principio del bucle - $4 fin del bucle -
#          $5 archivo a modificar
#==========================================================================
modificar_b ()
{
    OLD_IFS=$IFS
    IFS=''
    local a_parame="$1[*]"
    local loc_parame=(${!a_parame})
    IFS=$OLD_IFS
    total=`echo ${#loc_parame[*]}`
  
    line_i=$(grep -n -w "$2" $5 | cut -d':' -f1)
    if [ $line_i != "" ]; then
        line_pa=$(grep -n -w "$3" $5 | cut -d':' -f1)
        i=0
        for line in $line_pa; do
            line_p[$i]=$line
            ((i++))
        done
        line_fa=$(grep -n -w "$4" $5 | cut -d':' -f1)
        i=0
        for line in $line_fa; do
            line_f[$i]=$line
            ((i++))
        done

        i=0
        x=0
        a=0
        z=0
        tot_f=`echo ${#line_f[*]}`

        until [ $a -eq $z ] && [ $a -ne 0 ]; do
            if [ ${line_p[$i]} -eq $line_i ]; then
                ((a++)) && ((i++))
            elif [ ${line_p[$i]} -gt $line_i ]; then
                if [ ${line_p[$i]} -gt ${line_f[$x]} ] && [ ${line_f[$x]} -lt $line_i ]; then
                    ((x++))
                elif [ ${line_p[$i]} -gt ${line_f[$x]} ] && [ ${line_f[$x]} -gt $line_i ]; then
                    ((z++)) && ((x++))
                elif [ ${line_p[$i]} -lt ${line_f[$x]} ] && [ $i -ne $(( tot_f-1 )) ]; then
                    ((a++)) && ((i++))
                elif [ ${line_p[$i]} -lt ${line_f[$x]} ] && [ $i -eq $(( tot_f-1 )) ]; then
                    ((z++)) && ((x++))
                fi
            else
                ((i++))
            fi
        done
  
        verif=0
        for (( i=0;i<$total;i++ )); do
            modif=$(echo ${loc_parame[$i]})
            real=$(echo $(sed $(( line_i+i ))!d $5))
            if [ "$modif" = "$real" ]; then
                ((verif++))
            fi
        done
        primer=0
        if [ $verif -ne $total ]; then
            backup $5
            sed -i $line_i,${line_f[$x]}d $5
            for (( i=0;i<$total;i++ )); do
                if [ $primer -eq 0 ]; then
                    echo " " >> $5
                    ((primer++))
                fi
                echo "${loc_parame[$i]}" >> $5
            done
        fi
    else
        backup $5
        primer=0
        for (( i=0;i<$total;i++ )); do
            if [ $primer -eq 0 ]; then
                echo " " >> $5
                ((primer++))
            fi
            echo "${loc_parame[$i]}" >> $5
        done
    fi
}    # ----------  end of function modificar_b  ----------

#===  FUNCION  ============================================================
#        NOMBRE:  direc
#   DESCRIPCION:  Crea directorios y permisos
#    PARAMETROS:  S1 directorios - $2 usuario propietario -
#          $3 permisos
#==========================================================================
direc ()
{  
    OLD_IFS=$IFS
    IFS=''
    local a_dir="$1[*]"
    local loc_dir=(${!a_dir})
    local a_user="$2[*]"
    local loc_user=(${!a_user})
    local a_per="$3[*]"
    local loc_per=(${!a_per})
    IFS=$OLD_IFS
    total=`echo ${#loc_dir[*]}`
  
    for (( i=0;i<$total;i++ )); do
        if [ ! -d ${loc_dir[$i]} ]; then
            mkdir -p ${loc_dir[$i]}
            chown -R ${loc_user[$i]} ${loc_dir[$i]}
            chmod -R ${loc_per[$i]} ${loc_dir[$i]}
        fi
    done
}    # ----------  end of function direc  ----------

#===  FUNCION  ============================================================
#        NOMBRE:  cop_desc
#   DESCRIPCION:  Copia y descomprime archivos en ruta especificada
#    PARAMETROS:  $1 archivos a copiar - $2 ruta donde copiar
#==========================================================================
cop_desc ()
{
    OLD_IFS=$IFS
    IFS=''
    local a_rarch="$1[*]"
    local loc_rarch=(${!a_rarch})
    IFS=$OLD_IFS
    total=`echo ${#loc_rarch[*]}`
  
    no_u="Error copiando los archivos de instalación"
    for (( i=0;i<$total;i++ )); do
        cp ${loc_rarch[$i]} $2
    done &> /dev/null && echo "..." || echo "$no_u"
    no_u="Error descomprimiendo los archivos de instalación"
    cd $2
    for (( i=0;i<$total;i++ )); do
        arch=$(echo "${loc_rarch[$i]}" | sed 's/\(.*\)\///g')
        unzip $arch
        rm $arch
    done &> /dev/null && echo "..." || echo "$no_u"
}    # ----------  end of function cop_desc  ----------

#--------------------------------------------------------------------------
#  Verifica que somos root y sino salimos
#--------------------------------------------------------------------------
if [ $UID -ne 0 ]; then
    echo "Necesitas ser root (sudo su) para que el script funcione"
    exit
fi

#--------------------------------------------------------------------------
#  Verifica que se ha introducido $1 y es correcto
#--------------------------------------------------------------------------
if [ $# -le 0 ]; then
    echo "Necesitas introducir la ruta de linux_11gR2_database_1of2.zip. ./oracle.sh /ruta/linux_11gR2_database_1of2.zip o No/no si no deseas que se descomprima Oracle en a carpeta adecuada"
    exit
fi
if [ $# -gt 1 ]; then
    echo "No puedes usar más de un parametro. ./oracle.sh /ruta/linux_11gR2_database_1of2.zip o No/no si no deseas que se descomprima Oracle en a carpeta adecuada"
    exit
fi
if [ $1 != "No" ] && [ $1 != "no" ]; then
    if [ ! -e $1 ]; then
        echo "No existe linux_11gR2_database_1of2.zip en la ruta especificada o no ha especificado No para saltarse la copia de Oracle en la carpeta oportuna"
        exit
    fi
    p2=$(echo $1 | sed "s/1of2/2of2/g")
    if [ ! -e $p2 ]; then
        echo "No existe linux_11gR2_database_2of2.zip en la ruta especificada"
        exit
    fi
fi

#--------------------------------------------------------------------------
#  Crea usuarios y grupos para Oracle
#--------------------------------------------------------------------------
echo "Introduzca la contraseña para el usuario oracle:"
read pass

echo "Creando usuarios y grupos ..."
si_u="Cambios realizados con éxito"
no_u="Error creando usuarios y grupos"
usuarios $pass &> /dev/null && echo "$si_u" || echo "$no_u"

#--------------------------------------------------------------------------
#  Modifica los parámetros del kernel
#--------------------------------------------------------------------------
parame=( "kernel.shmmni =" "kernel.sem =" "fs.file-max =" "net.ipv4.ip_local_port_range =" "net.core.rmem_default =" "net.core.wmem_default =" "net.core.rmem_max =" "net.core.wmem_max =" "fs.aio-max-nr =" )
valor=( " 4096" " 250 32000 100 128" " 6815744" " 9000 65500" " 262144" " 262144" " 4194304" " 1048576" " 1048576" )
archivo="/etc/sysctl.conf"
no_u="Error modificando los parámetros del Kernel. Puede restaurar $archivo.vell"

echo "Modificando los parámetros del Kernel ..."
modificar parame valor $archivo &> /dev/null && echo "$si_u" || echo "$no_u"
no_u="Error cargando los parámetros del Kernel."
sysctl -p &> /dev/null && echo "..." || echo "$no_u"

unset parame
unset valor

#--------------------------------------------------------------------------
#  Modifica los limites de shell
#--------------------------------------------------------------------------
parame=( "oracle.*soft.*nproc" "oracle.*hard.*nproc" "oracle.*soft.*nofile" "oracle.*hard.*nofile" )
valor=( " 2047" " 16384" " 1024" " 65536" )
archivo="/etc/security/limits.conf"
no_u="Error modificando los limites del shell. Puede restaurar $archivo.vell"
echo "Modificando los limites del shell ..."
modificar parame valor $archivo &> /dev/null && echo "..." || echo "$no_u"
unset parame
unset valor

parame="session required /lib/security/pam_limits.so"
valor=" "
archivo="/etc/pam.d/login"
no_u="Error modificando los limites del shell. Puede restaurar $archivo.vell"
modificar parame valor $archivo &> /dev/null && echo "..." || echo "$no_u"
unset parame
unset valor

while read LINE; do
    parame[$i]=$LINE
    ((i++))
done<
if [ \$USER = "oracle" ]; then
    if [ \$SHELL = "/bin/ksh" ]; then
        ulimit -p 16384
        ulimit -n 65536
    else
        ulimit -u 16384 -n 65536
    fi
    umask 022
fi
BUCLE
ini="if \[ .*USER = \"oracle\" \]; then"
bucle_i="if.*then"
bucle_f="fi"
archivo="/etc/profile"
no_u="Error modificando los limites del shell. Puede restaurar $archivo.vell"
modificar_b parame "$ini" "$bucle_i" "$bucle_f" $archivo &> /dev/null && echo "$si_u" || echo "$no_u"

#--------------------------------------------------------------------------
#  Crea los directorios con los permisos necesarios
#--------------------------------------------------------------------------
dir=( "/opt/oracle/product" "/opt/oraInventory" )
usu=( "oracle:oinstall" "oracle:oinstall" )
per=( "775" "775" )

echo "Creando directorios y permisos necesarios ..."
no_u="Error creando los directorios y permisos necesarios"
direc dir usu per &> /dev/null && echo "$si_u" || echo "$no_u"
unset dir

#--------------------------------------------------------------------------
#  Instala los paquetes necesarios
#--------------------------------------------------------------------------
echo "Instalando los paquetes necesarios ..."
no_u="Error instalando los paquetes necesarios"
yum -y install binutils compat-libstdc++-33 elfutils-libelf elfutils-libelf-devel elfutils-libelf-devel-static  gcc gcc-c++ glibc glibc-common glibc-devel glibc-headers kernel-headers kernel-devel ksh libaio libaio-devel libgcc libgomp libstdc++ libstdc++-devel make sysstat unixODBC unixODBC-devel pdksh &> /dev/null && echo "$si_u" || echo "$no_u"

#--------------------------------------------------------------------------
#  Copia en ubicación y descomprimimos oracle
#--------------------------------------------------------------------------
dir="/opt/oracle"
sdir="/database"
echo "Copiando y descomprimiendo Oracle ..."
if [ $1 != "No" ] && [ $1 != "no" ]; then
    archivo=( "$1" "$p2" )
    if [ -d $dir$sdir ]; then
        echo "La carpeta $dir$sdir existe. ¿Quiere seguir con la copia de Oracle en la carpeta adecuada?"
        echo "(1)Si (2)No"
        while [ "$respuesta" != 1 ] && [ "$respuesta" != 2 ]; do
            read respuesta
            case  respuesta in
                1) cop_desc archivo $dir
                    ;;
                2) echo "Recuerda que debes descomprimir Oracle en $dir"
                    ;;
                *) echo "Debes escoger entre 1 ó 2"
                    ;;
            esac    # --- end of case ---
        done
    else
        cop_desc archivo $dir
    fi
fi
chown -R oracle:oinstall $dir

echo "La preparación ha terminado. Inicia sesión como usuario oracle y si usas ssh -X recuerda que la variable DISPLAY debe ser localhost:10.0. Después ejecuta $dir$sdir/runInstaller"

Le damos permiso de ejecución y ejecutamos como root (sudo su, ya que necesita el PATH creado anteriormente)

chmod +x oracle.sh
./oracle.sh /ruta/linux_11gR2_database_1of2.zip

Tras esto iniciamos sesión como usuario oracle y iniciamos la instalación

cd /opt/oracle/database
./runInstaller

Seguimos los pasos de la instalación teniendo encuenta indicarle las siguientes opciones:
- Crear y configurar una base de datos
- Oracle Base: /opt/oracle
- Software localización: /opt/oracle/product/11.2.0/dbhome_1
- Localización archivos Database: /opt/oracle/oradata
- OSDBA Group: oinstall
- Directorio de Inventaro: /opt/oraInventory

Para arrancar oracle puedes crear un script al inicio o uno normal. Lo que tienes que tener en cuenta para estos es:
Variables de entorno

ORACLE_OWNER=oracle
ORACLE_BASE=/opt/oracle
ORACLE_HOME=$ORACLE_BASE/product/11.2.0/dbhome_1
ORACLE_SID=orcl
PATH=/usr/sbin:$PATH
PATH=$ORACLE_HOME/bin:$PATH

Arrancar, parar aplicaciones ejecutado por el usuario oracle

lsnrctl start #Abrir Listener
dbstart #Abrir Base de Datos
emctl start dbconsole #Abrir Oracle Enterprise manager

emctl stop dbconsole #Cerrar Oracle Enterprise manager
dbshut #Cerrar Base de Datos
lsnrctl stop #Cerrar Listener

1 comentario:

Nebur dijo...

He recibido un par de correos que me pedían una explicación de como ejecutar el script porque "no les corrió". No se si os referís a esto, ya que no especificáis, pero intento explicarme mejor.
- Necesitas realizar los pasos del path porque en el script, por ejemplo, esta: useradd en vez de /usr/sbin/useradd.
- Supongamos que en /home/masvalemanya tenéis los archivos linux_11gR2_database_1of2.zip y linux_11gR2_database_2of2.zip.
- Creamos el script y le damos permisos de ejecución: chmod +x oracle.sh
- Luego como root:
./oracle.sh /home/masvalemanya/linux_11gR2_database_1of2.zip