Acerca de admin

Tras más de 20 años trabajando con tecnologías Oracle, me decidí a recopilar en un Blog algunas de las cosillas útiles para el día a día.

Recuperacion con RMAN desde Dataprotector desde linea de comandos

Muchas veces tenemos el backup integrado por scripts propietarios del software de backup.
Esta integración nos garantiza el pode recuperar con «botón derecho», pero , puede darse el caso de querer recuperar manualmente, bien por que queremos tener el control total sobre el proceso o bien por que es en otra maquina o por que queramos hacer una recuperación mas especifica del RMAN que la que nos ofrezcan los botones del software de backup.

En este caso vamos a hacer una recuperación total de una base de datos que se ha copiado con dataprotector. Entre las cosas que necesitaremos son:

  • Init.ora de la base de datos, deberíamos de hacer una copia del mismo junto con el backup,con lo que podemos sacarlo de ahi
  • DBID de la base de datos, este DBID aparece en el log de rman, con lo que podremos sacarlo del ultimo log del backup
  • Cadena de configuración de la cinta. Esta en las propiedades avanzadas de la política de backup que usamos para copiar nuestra base de datos

Además, necesitaremos ser capaces de llegar al log de la ultima copia de rman, esto se hace desde dataprotector, mirando en las siguientes pestañas

Internal Database
     -> "log del backup"  (tiene el formato fecha/backup)
           -> Propierties (boton derecho)
               --> Messages (el log completo del rman)

Para clarificar un poco los logs, tendremos en este caso:

  • instancia=pruebas
  • Servidor=serveroracle.pamplona.name
  • DBID=3751694031 (obtenido del log del backup desde dataprotector)

Si no tuviésemos el init.ora podríamos recuperarlo también del backup ya que la 11g hace copia del init.ora con el controlfile autobackup, pero, es una buena practica el tener una copia del init.ora en modo texto, ya que, nos evita uno de los pasos mas engorrosos.
Con estas 3 cosas, podemos comenzar la recuperación de la base de datos.

Lo primero que recuperaremos será el controlfile, para ello haremos un script al que llamaremos restore_controlfile.cmd tal que

startup nomount;
set DBID=3751694031
run {
allocate channel 'dev_0' type 'sbt_tape'
 parms 'ENV=(OB2BARTYPE=Oracle8,OB2APPNAME=pruebas,OB2BARLIST=Online Diaria)';
restore controlfile from autobackup;
}

Al que llamaremos con

rman target / cmdfile restore_controlfile.cmd

En este punto, podemos llevarnos la sorpresa de que obtenemos un RMAN-06172

Al igual que vimos en el post RMAN-06172: no AUTOBACKUP found or specified handle is not a valid copy or piece tendremos que decirle exactamente cual es el nombre del controlfile que queremos recuperar, para ello, nos iremos al dataprotector y exploramos el log hasta la última línea en la que encontremos la palabra controlfile

[Normal] From: OB2BAR_DMA@serveroracle.pamplona.name "pruebas"  Time: 06/03/2013 21:21:19
	Starting OB2BAR Backup:serveroracle.pamplona.name: pruebas DP Managed Control File Backup "Oracle8"

La línea que estamos buscando es pruebas DP Managed Control File Backup «Oracle8», que es el fichero dentro de dataprotector donde se encuentra nuestro controlfile.
Así pues, modificaremos el script de backup y ahora será:

startup nomount;
set DBID=3751694031
run {
allocate channel 'dev_0' type 'sbt_tape'
 parms 'ENV=(OB2BARTYPE=Oracle8,OB2APPNAME=pruebas,OB2BARLIST=Online Diaria)';
restore controlfile from 'pruebas DP Managed Control File Backup "Oracle8"';
}

Con esto conseguiremos tener nuestro controlfile restaurado. Ahora, ya tenemos una restauracion standard de RMAN típica de manual.

Monitorizar el alert.log desde una sql remota

El fichero de alertas de oracle alert.log es uno de los ficheros que tradicionalmente revisamos en busca de errores de la base de datos.
Hasta la versión 11g esta monitorización se hacía por medio del scripts que interactuaban con ficheros del sistema operativo, lo que nos llevaba a tener que mantener estos scripts para las distintas versiones de shells de sistema, o tener que instalar algún tipo de interprete en el sistema que nos lo gestionara de manera multiplataforma.

Una de las grandes ventajas de la 11g es que Oracle nos ha obsequiado con una tabla de base de datos que mapea esta información del alert.log dentro de la base de datos . Estamos hablando de la tabla x$dbgalertext;

Mediante la tabla x$dbgalertext podemos obtener toda la informacion que está en el alert.log, su contenido es:

SQL> desc X$DBGALERTEXT

           Name                            Null?    Type
           ------------------------------- -------- -------------------------
    1      ADDR                                     RAW(4)
    2      INDX                                     NUMBER
    3      INST_ID                                  NUMBER
    4      ORIGINATING_TIMESTAMP                    TIMESTAMP(3) WITH TIME ZONE
    5      NORMALIZED_TIMESTAMP                     TIMESTAMP(3) WITH TIME ZONE
    6      ORGANIZATION_ID                          VARCHAR2(64)
    7      COMPONENT_ID                             VARCHAR2(64)
    8      HOST_ID                                  VARCHAR2(64)
    9      HOST_ADDRESS                             VARCHAR2(16)
   10      MESSAGE_TYPE                             NUMBER
   11      MESSAGE_LEVEL                            NUMBER
   12      MESSAGE_ID                               VARCHAR2(64)
   13      MESSAGE_GROUP                            VARCHAR2(64)
   14      CLIENT_ID                                VARCHAR2(64)
   15      MODULE_ID                                VARCHAR2(64)
   16      PROCESS_ID                               VARCHAR2(32)
   17      THREAD_ID                                VARCHAR2(64)
   18      USER_ID                                  VARCHAR2(64)
   19      INSTANCE_ID                              VARCHAR2(64)
   20      DETAILED_LOCATION                        VARCHAR2(160)
   21      PROBLEM_KEY                              VARCHAR2(64)
   22      UPSTREAM_COMP_ID                         VARCHAR2(100)
   23      DOWNSTREAM_COMP_ID                       VARCHAR2(100)
   24      EXECUTION_CONTEXT_ID                     VARCHAR2(100)
   25      EXECUTION_CONTEXT_SEQUENCE               NUMBER
   26      ERROR_INSTANCE_ID                        NUMBER
   27      ERROR_INSTANCE_SEQUENCE                  NUMBER
   28      VERSION                                  NUMBER
   29      MESSAGE_TEXT                             VARCHAR2(2048)
   30      MESSAGE_ARGUMENTS                        VARCHAR2(128)
   31      SUPPLEMENTAL_ATTRIBUTES                  VARCHAR2(128)
   32      SUPPLEMENTAL_DETAILS                     VARCHAR2(128)
   33      PARTITION                                NUMBER
   34      RECORD_ID                                NUMBER

Ahora bien, ¿como accedemos a ella?

La tabla no puede ser accedida directamente desde un usuario que no sea sys, así que, lo que haremos será el crear una vista sobre esta tabla (a la que llamaremos por ejemplo ficheroalert ) y permitirle que lo vea a nuestro usuario de monitorizacion.


create view ficheroalert as select  * from sys.x$dbgalertext;
grant select on sys.ficheroalert to MONITORIZACION;

A partir de aquí, solamente tenemos que jugar con los campos descritos arriba y podremos obtener la informacion que deseemos.
En mi caso , por ejemplo, me gustaría saber si ha habido algún mensaje ORA- o ERROR en los ultimos 5 munitos.

La consulta que ejecutaré para obtenerlo es:


select to_char(ORIGINATING_TIMESTAMP, 'dd-mon-yyyy hh24:mi:ss'),
      substr(MESSAGE_TEXT, 1, 300) message_text
    from sys.ficheroalert
    where (MESSAGE_TEXT like '%ORA-%'
            or upper(MESSAGE_TEXT) like '%ERROR%')
     and 
           cast(ORIGINATING_TIMESTAMP as DATE) > sysdate - 5/1440;
            - X/1440 es la X en minutos 

Entrada en ingles en Monitoring the alert.log from a remote sql

Instalación de RAC I Preparativos

Vamos a retomar la instalación de un RAC en una plataforma virtualizada de pruebas con Virtualbox. En este punto tenemos las máquinas creadas y con el sistema operativo instalado, con lo que vamos a utilizar esta entrada para detallar los pasos necesarios para ajustar esos sistemas operativos para la instalacion del grid

Creacion de usuarios y grupos
Lo primero que hemos de hacer es crear los grupos necesarios para nuestra instalación

/usr/sbin/groupadd -g 501 oinstall
/usr/sbin/groupadd -g 502 dba
/usr/sbin/groupadd -g 505 asmadmin
/usr/sbin/groupadd -g 506 asmdba
/usr/sbin/groupadd -g 507 asmoper

Tras los grupos, creamos los usuarios y los asignamos a los grupos correspondientes

/usr/sbin/useradd -u 501 -g oinstall -G asmadmin,asmdba,asmoper grid
/usr/sbin/useradd -u 502 -g oinstall -G dba,asmdba oracle

Confuguración del fichero hosts

Dado que los equipos van a referenciarse entre ellos constantemente, deberemos de configurar la resolución de nombres entre ellos, la forma mas rápida y sencilla es la de incluir sus nombres en el /etc/hosts de todos los nodos del rac

# Direcciones para nuestros equipos
# HOST y publica  eth0
10.0.2.2  exodar.pamplona.name   exodar
10.0.2.3  rac1.pamplona.name     rac1
10.0.2.4  rac2.pamplona.name     rac2
10.0.2.5  rac3.pamplona.name     rac3
10.0.2.6  rac4.pamplona.name     rac4
10.0.2.24 plantilla.pamplona.name        plantilla


#Virtual  Eth1  direcciones de la red sobre la que se da el servicio 
192.168.1.1  exodar-vip.pamplona.name   exodar-vip
192.168.1.2  rac1-vip.pamplona.name     rac1-vip
192.168.1.3  rac2-vip.pamplona.name     rac2-vip
192.168.1.4  rac3-vip.pamplona.name     rac3-vip
192.168.1.5  rac4-vip.pamplona.name     rac4-vip
192.168.1.24 plantilla-vip.pamplona.name        plantilla-vip

#ScaN  comentadas ya que estan dada de alta en round robin dns
# estas son las verdaderas direcciones de servicio 
#192.168.1.20  ractest.pamplona.name  ractest
#192.168.1.21  ractest.pamplona.name  ractest
#192.168.1.22  ractest.pamplona.name  ractest

#Private ETH2 red privada de los nodos
192.168.2.1  exodar-conn.pamplona.name  exodar-priv
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
192.168.2.24 plantilla-conn.pamplona.name   plantilla-conn

Consideraciones sobre la configuracion de la red

  • El orden de las interfaces de red en todos los nodos ha de ser el mismo
  • La direccion de SCAN (Single Cliente Access Name) es la direccion a la que vamos a aceeder desde los clientes ( IPs de servicio),Grid Infraestructure iniciará el local listener LISTENER sobre todos los nodos para escuchar sobre la local VIP, y SCAN listener LISTENER_SCAN1 para escuchar sobre las SCAN VIPs. Aunque podríamos seguir entrando a las local VIPS del nodo, Oracle recomienda que se acceda siempre a las direcciones de SCAN.
  • La direccion de SCAN debe de ser un nombre del dominio con almenos una direccion y un máximo de tres direcciones,el nombre de la direccion de scan (ractest en nuestro caso) debe de ser global y único y será utilizado por defecto como nombre del cluster
  • Oracle recomienda no configurar SCAN VIP address en el archivo host ya que si se usa en archivo host para resolver el nombre del SCAN, se puede tener una sola SCAN VIP address. Oracle recomienda configurar el SCAN para utilizar DNS Round Robin resolution a con direcciones.

Servidor de NTP
Debemos de estar seguros que la hora de todos nuestros equipos del RAC es idéntica.
Oracle cuenta con el CTSSD(Cluster Time Syncronization Server Daemon) que se encarga de esto, con lo que podemos parar el servicio del sistema operativo NTPD.
Si por el contrario queremos tener el servicio activo, habremos de configurarlo con la opción -x

Creamos accesos por ssh entre los nodos.
Deberemos permitir conexiones y ejecuciones remotas entre los nodos para el usuario grid.
Para ello haremos en uno de los dos nodos:

mkdir .ssh
chmod 700 .ssh
[grid@rac1 ~]$ ssh-keygen -t dsa
Generating public/private dsa key pair.
Enter file in which to save the key (/home/grid/.ssh/id_dsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/grid/.ssh/id_dsa.
Your public key has been saved in /home/grid/.ssh/id_dsa.pub.

Ahora copiaremos

scp id_dsa.pub rac1-vip:/home/grid/.ssh/authorized_keys

y haremos lo mismo con rac1

scp id_dsa.pub rac2-vip:/home/grid/.ssh/authorized_keys

para ver si ha funcionado deberemos de poder hacer libremente ssh desde el usuario grid de rac1 a rac2 y viceversa.

preparamos los parámetros del kernel

Editaremos el fichero /etc/sysctl.cnf y pondremos los siguientes valores para el kernel

# Para Oracle
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

para que el kernel adopte estos valores sintener que reiniciar ejecutaremos el comando

sysctl -p

ademas de esto, tendremos que añadir las siguientes líneas en el fichero /etc/security/limits.conf

# Para Oracle
grid soft nproc 2047
grid hard nproc 16384
grid soft nofile 1024
grid hard nofile 65536

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

comprobamos que en el fichero /etc/pam.d/login este la línea

session required pam_limits.so

Directorios para la instalación
Ahora crearemos los directorios de instalacion.
Habitualmente los elementos de oracle son creados bajo /u01/app /u02 ….
En nuestro caso tratándose de una plataforma de test sobre maquinas virtuales no tenemos un alto número de unidades de disco que montar y donde separar los elementos, con lo que toda nuestra instlacion será llevada a cabo bajo el directorio /oracle aún así y por motivos de compatibilidad, vamos ha hacer un enlace simólico desde /u01 hasta /oracle
así pues, nuestros datos para la instalacion del grid serán
GI_HOME=/oracle/11.2.0/grid
ORACLE_BASE=/oracle/app/grid

Hemos de tener en cuenta que el GI_HOME no debe de estar bajo ningún directorio de oracle_base .
Durante la instalación el GI_HOME será cambiado a root lo que podría causar errores de alguna otra instalación que esté sobre esos discos.

mkdir /oracle
ln -s /oracle /u01
chown -R grid:oinstall /oracle
mkdir -p /oracle/11.2.0/grid
chown -R grid:oinstall /oracle/11.2.0/grid
chmod 775 /oracle/11.2.0/grid

mkdir -p /oracle/app/grid
chown -R grid:oinstall /oracle/app/grid
chmod -R 775 /oracle/app/grid

Configuramos el asmlib

[root@rac2 etc]# /etc/init.d/oracleasm configure -i
Configuring the Oracle ASM library driver.

This will configure the on-boot properties of the Oracle ASM library
driver. The following questions will determine whether the driver is
loaded on boot and what permissions it will have. The current values
will be shown in brackets ('[]'). Hitting without typing an
answer will keep that current value. Ctrl-C will abort.

Default user to own the driver interface []: grid
Default group to own the driver interface []: asmadmin
Start Oracle ASM library driver on boot (y/n) [y]:
Scan for Oracle ASM disks on boot (y/n) [y]:
Writing Oracle ASM library driver configuration: done
Initializing the Oracle ASMLib driver: [ OK ]
Scanning the system for Oracle ASMLib disks: [ OK ]

Aseguramos permisos con UDEV
En linux una de las formas que podemos asegurar que los dispositivos de los discos tendrán los permisos deseados es mediante la creacion de una regla de udev.
Así pues, con el comando blkid comprobaremos que discos tenemos en nuestro sistema.

[root@rac1 /]# blkid
/dev/sda1: UUID="b8327abf-baf7-48c5-baac-b39dc98d6b6e" TYPE="swap"
/dev/sda2: UUID="67748b98-ffde-4dbc-9b14-5da7dae13d65" TYPE="ext4"
/dev/sdb1: LABEL="DISK1" TYPE="oracleasm"
/dev/sdc1: LABEL="DISK2" TYPE="oracleasm"
/dev/sdd1: LABEL="DISK3" TYPE="oracleasm"
/dev/sde1: LABEL="DISK4" TYPE="oracleasm"
/dev/sdf1: LABEL="DISK5" TYPE="oracleasm"
/dev/sdg1: LABEL="OCRVOTING" TYPE="oracleasm"

con lo que sabemos que tenemos los discos sdb,sdc,sdd,sde,sdf, y sdg para asegurar los permisos crearemos el fichero /etc/udev/rules.d/99.oracle.rules con el contenido

# Damos permisos grid:asmadmin a los discos de asm

KERNEL=="sd[b-g]1", OWNER="grid",GROUP="asmadmin", MODE="660" NAME="asmdisk_%k"

comprobamos los permisos

root@rac1 /]# ls -l /dev/sd*
brw-rw---- 1 root disk 8, 0 dic 30 16:56 /dev/sda
brw-rw---- 1 root disk 8, 1 dic 30 16:56 /dev/sda1
brw-rw---- 1 root disk 8, 2 dic 30 16:56 /dev/sda2
brw-rw---- 1 root disk 8, 16 dic 30 16:56 /dev/sdb
brw-rw---- 1 root disk 8, 17 dic 30 16:56 /dev/sdb1
brw-rw---- 1 root disk 8, 32 dic 30 16:56 /dev/sdc
brw-rw---- 1 root disk 8, 33 dic 30 16:56 /dev/sdc1
brw-rw---- 1 root disk 8, 48 dic 30 16:56 /dev/sdd
brw-rw---- 1 root disk 8, 49 dic 30 16:56 /dev/sdd1
brw-rw---- 1 root disk 8, 64 dic 30 16:56 /dev/sde
brw-rw---- 1 root disk 8, 65 dic 30 16:56 /dev/sde1
brw-rw---- 1 root disk 8, 80 dic 30 16:56 /dev/sdf
brw-rw---- 1 root disk 8, 81 dic 30 16:56 /dev/sdf1
brw-rw---- 1 root disk 8, 96 dic 30 16:56 /dev/sdg
brw-rw---- 1 root disk 8, 97 dic 30 16:56 /dev/sdg1

ejecutamos

udevadm control --reload-rules
/sbin/start_udev

Y comprobamos los permisos, tenemos que:

[root@rac1 rules.d]# ls -l /dev/sd*
brw-rw---- 1 root disk 8, 0 dic 30 15:01 /dev/sda
brw-rw---- 1 root disk 8, 1 dic 30 15:01 /dev/sda1
brw-rw---- 1 root disk 8, 2 dic 30 15:01 /dev/sda2
brw-rw---- 1 root disk 8, 16 dic 30 15:01 /dev/sdb
brw-rw---- 1 grid asmadmin 8, 17 dic 30 15:01 /dev/sdb1
brw-rw---- 1 root disk 8, 32 dic 30 15:01 /dev/sdc
brw-rw---- 1 grid asmadmin 8, 33 dic 30 15:01 /dev/sdc1
brw-rw---- 1 root disk 8, 48 dic 30 15:01 /dev/sdd
brw-rw---- 1 grid asmadmin 8, 49 dic 30 15:01 /dev/sdd1
brw-rw---- 1 root disk 8, 64 dic 30 15:01 /dev/sde
brw-rw---- 1 grid asmadmin 8, 65 dic 30 15:01 /dev/sde1
brw-rw---- 1 root disk 8, 80 dic 30 15:01 /dev/sdf
brw-rw---- 1 grid asmadmin 8, 81 dic 30 15:01 /dev/sdf1
brw-rw---- 1 root disk 8, 96 dic 30 15:01 /dev/sdg
brw-rw---- 1 grid asmadmin 8, 97 dic 30 15:01 /dev/sdg1

Comprobacion de prerequisitos

Ahora podremos comprobar que esta todo correcto con el comando


./runcluvfy.sh stage -pre crsinst -n rac1,rac2 -r 11gR2 

El siguiente paso será la instalación del Grid Infraestructure

Problemas con los requerimientos del cliente 11gr2 en windows

Volvemos tras las vacaciones navideñas con una pequeña entrada de esas tremendamente simples, pero que pueden ser evitarnos una gran pérdida de tiempo.

Una de las cosas mas engorrosas de las instalaciones de Oracle es la instalación del cliente, en primer lugar, porque pocas veces nos especifican que es exactamente los componentes del cliente que necesitan, y en segundo lugar, por que, hasta estas últimas versiones la instalación ( especialmente la desinstalación) del cliente de windows era muy engorrosa.

Pues bien, el otro día en la instalación de un cliente 11gr2 en windows me encontré con un error nuevo:

error_instalacion_XP

Mi windows XP detectaba un error en los requerimientos de la instalacion del cliente (no instantclient), cuando, todos los requerimientos eran correctos.

La solución es tan sencilla como el habilitar el uso compartido de C$. Parece ser que el instalador utiliza «\\< servidor >\C$\temp» , con lo que si no está habilitado el recurso, la instalación falla.

La información completa del caso está (como siempre) en metalink, en la nota «Installation of 11gR2 on Windows Fails Checking Requirements [ID 1133495.1]»

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