domingo, 2 de octubre de 2016

Validando inicio automático con scripts de Oracle en Linux

Hace poco tuve que revisar una base Oracle 11g en Linux que no estaba inciando cuando el servidor se reinciaba, a pesar de estar configurada para hacerlo.

Comparto la experiencia, ya que esto es algo bien simple pero que puede llevar algo de tiempo resolverlo ya que la documentación no es explícita en este punto: las entradas en /etc/oratab que configuran el inicio de una base no tienen que tener ningún comentario al final para que funcionen.

Esto quiere decir que esta entrada en /etc/oratab se ignora:
        TEST:/u01/app/oracle/product/11.2.0/db_1:Y               # line added by Agent

Contexto

Antes de ir al detalle, un poco de contexto: ¿cómo se puede configurar el inicio automático de una base de datos Oracle?. Hay dos opciones, dependiendo de si estamos usando clusterware o no:
  •  configurando scripts en /etc/init.d
  • Esta es la opción clásica desde 9i con algunas variantes
    Hay un muy buen blog post from Tim Hall explicando las opciones   
  • usando Oracle Clusterware
  • Desde 10g para base RAC o standalone.
    Notar que Oracle Restart (disponible desde 11g para standalone) es deprecado en 12c y se recomienda usar Clusterware con ASM en instalaciones standalone.
    Hay un muy buen post por Bjoern validando el uso de GI y otro de Bobby mostrando que se puede usar Restart en 12c
¿Cuál es la recomendación de Oracle en 12c para instalaciones no RAC? Usar scripts

Validando la configuración

El primer paso es validar que tenemos todo configurado para el incio automático:
  • el script dbora está instalado en /etc/init.d/dbora
  • la variable ORACLE_HOME tiene el path de nuestra instalación en ese script
  • los scripts dbshut y dbstart existen en nuestro Oracle home (vienen por defecto, pero por las dudas)
  • el script dbora está configurado para ejecutarse con el inicio y baja del SO
  • /etc/oratab tiene una entrada con "Y" para la base que queremos manejar con estos scripts
En mi caso, todo estaba en su lugar:
    [oracle@oraculo ~]$ cat /etc/init.d/dbora
    #!/bin/sh
    # chkconfig: 345 99 10
    # description: Oracle auto start-stop script.
    #
    # Change the value of ORACLE_HOME to specify the correct Oracle home
    # directory for your installation.

    ORACLE_HOME=/u01/app/oracle/product/11.2.0/db_1
    #
    # Change the value of ORACLE to the login name of the
    # oracle owner at your site.
    #
    ORACLE=oracle
    PATH=${PATH}:$ORACLE_HOME/bin
    export ORACLE_HOME PATH
    #

    case $1 in
    'start')
            runuser -l $ORACLE -c '$ORACLE_HOME/bin/dbstart $ORACLE_HOME &'
            touch /var/lock/subsys/dbora
            ;;
    'stop')
            runuser -l $ORACLE -c '$ORACLE_HOME/bin/dbshut $ORACLE_HOME'
            rm -f /var/lock/subsys/dbora
            ;;
    *)
            echo "usage: $0 {start|stop}"
            exit
            ;;
    esac
    #
    exit
   
    [oracle@oraculo ~]$ ls -lrt /u01/app/oracle/product/11.2.0/db_1/bin/dbstart
    -rwxr-x--- 1 oracle oinstall 13957 Sep  9  2014 /u01/app/oracle/product/11.2.0/db_1/bin/dbstart

    [oracle@oraculo ~]$ ls -lrt /u01/app/oracle/product/11.2.0/db_1/bin/dbshut*
    -rwxr-x---. 1 oracle oinstall 6030 Jan  1  2000 /u01/app/oracle/product/11.2.0/db_1/bin/dbshut

    [oracle@oraculo ~]$ chkconfig --list dbora
    dbora           0:off   1:off   2:off   3:on    4:on    5:on    6:off
   
    [oracle@oraculo ~]$ cat /etc/issue
    Red Hat Enterprise Linux Server release 6.6 (Santiago)
    Kernel \r on an \m

    [oracle@oraculo ~]$ tail /etc/oratab
    ##
    ## Multiple entries with the same $ORACLE_SID are not allowed.
    ##
    ##
    +ASM1:/u01/app/11.2.0/grid:N            # line added by Agent
    OLDT:/u01/app/oracle/product/11.2.0/db_1:N              # line added by Agent
    TEST:/u01/app/oracle/product/11.2.0/db_1:Y               # line added by Agent

Pero luego de reiniciar el servidor, la base no levantó.

Investigando el problema

Al ejectuar el script dbstart, se generan dos archivos de log:
    /u01/app/oracle/product/11.2.0/db_1/listener.log
    /u01/app/oracle/product/11.2.0/db_1/startup.log
En mi caso solo estaba creado el de listener, no el de la base.

Mirando el código del script dbstart, y después de habilitar trace agregando la variable ORACLE_TRACE=T en su código, algunos mensajes extras y reiniciar, encontré el problema en esta parte del código:
    ORACLE_SID=`echo $LINE | awk -F: '{print $1}' -`
    ...
    # Proceed only if last field is 'Y'.
    if [ "`echo $LINE | awk -F: '{print $NF}' -`" = "Y" ] ; then
 Validando ese código con nuestro archivo de configuración:
    [oracle@oraculo ~]$ cat /etc/oratab | awk -F: '{print $NF}' -
    #Backup file is  /u01/app/oracle/product/11.2.0/db_1/srvm/admin/oratab.bak.TESTlinux1 line added by Agent
    ##
    #
    #
    #
    ## This file is used by ORACLE utilities.  It is created by root.sh
    ## and updated by either Database Configuration Assistant while creating
    ## a database or ASM Configuration Assistant while creating ASM instance.
    #
    ## A colon is used as the field terminator.  A new line terminates
    ## the entry.  Lines beginning with a pound sign, '#', are comments.
    ##


    ##
    ## The first and second fields are the system identifier and home
    ## directory of the database respectively.  The third filed indicates
    ## to the dbstart utility that the database should , "Y", or should not,
    ## "N", be brought up at system boot time.
    ##
    ## Multiple entries with the same $ORACLE_SID are not allowed.
    ##
    ##
    N            # line added by Agent
    N              # line added by Agent
    Y               # line added by Agent

Cada línea es lo que se compara con "Y".
Para que ese código funcione, las líneas del archivo /etc/oratab deben terminar con la Y:

    [oracle@oraculo ~]$ echo "TEST:/u01/app/oracle/product/11.2.0/db_1:Y" | awk -F: '{print $NF}' -
    Y
Después de quitar los comentarios al final de la entrada en /etc/oratab, al siguiente reinicio del servidor ahora se reinicia la base:
    [oracle@oraculo ~]$ tail /etc/oratab
    ## "N", be brought up at system boot time.
    ##
    ## Multiple entries with the same $ORACLE_SID are not allowed.
    ##
    ##
    +ASM1:/u01/app/11.2.0/grid:N            # line added by Agent
    OLDT:/u01/app/oracle/product/11.2.0/db_1:N              # line added by Agent
    TEST:/u01/app/oracle/product/11.2.0/db_1:Y
   
    [oracle@oraculo ~]$ uptime
     12:13:10 up 4 days,  1:50,  1 user,  load average: 2.10, 1.31, 1.02

    [oracle@oraculo ~]$ ls -lrt /u01/app/oracle/product/11.2.0/db_1/startup.log
    -rw-r--r-- 1 oracle oinstall 2334 Sep 28 10:46 /u01/app/oracle/product/11.2.0/db_1/startup.log

    [oracle@oraculo ~]$ tail -17 /u01/app/oracle/product/11.2.0/db_1/startup.log
    ORACLE instance started.

    Total System Global Area 8017100800 bytes
    Fixed Size                  2244192 bytes
    Variable Size            1392509344 bytes
    Database Buffers         6610223104 bytes
    Redo Buffers               12124160 bytes
    Database mounted.
    SQL>
    Database altered.

    SQL> Disconnected from Oracle Database 11g Release 11.2.0.3.0 - 64bit Production
    + '[' 0 -eq 0 ']'
    + echo ''

    + echo '/u01/app/oracle/product/11.2.0/db_1/bin/dbstart: Database instance "TEST" warm started.'
    /u01/app/oracle/product/11.2.0/db_1/bin/dbstart: Database instance "TEST" warm started.
    [oracle@oraculo ~]$
Un saludo.