Recuperar un spfile borrado

Hoy vamos a ver algo tan sencillo como el recuperar un fichero spfile.

El spfile es la «nueva» version del fichero de configuracion de parametros texto de toda la vida llamado pfile. La principal ventaja que obtenemos con tener un fichero de configuración binario sobre un fichero de texto es que la instancia puede ir actualizando los cambios de configuración que llevas a cabo en la base de datos sin necesidad de tener que actualizarlo manualmente. Hemos de tener en cuenta que, con los nuevos modos de gestión de memoria la configuracion del tamaño de los distintos pooles ya no es estático, con lo que es necesario tener un fichero de datos actualizable si quieres mantener esa informacion en el siguiente arranque.

El fichero spfile es necesario en el momento en el que arrancas la instancia, pero no lo es para el funcionamiento de la base de datos, si  borras este fichero cuando la base de datos esta en funcionamiento todo funcionará correctamente, solamente tendremos errores cuando intentemos modificar algo del spfile, y los errorres que tendremos serán errores de localizacionde fichero del sistema operativo

ORA-01565: error al identificar el archivo '/opt/oracle/product/11.2.0.3/dbhome_1/dbs/spfileorcl.ora'
ORA-27037: no se ha podido obtener el estado del archivo
Linux-x86_64 Error: 2: No such file or directory
Additional information: 3

Pero la base de datos seguirá funcionando correctamente.

Para restaurar un spfile tenemos dos opciones:

1- Restauración desde RMAN

Rman hace una copia del controlfile y el spfile cada vez que llevas a cabo un backup del tablespace system.  Así pues, si hacemos backups full de nuestra base de datos, deberíamos de tener una copia del spfile en el backupset.

La recuperación del fichero es muy sencilla, simplemente hay que decirle que lo restaure del autobackup con el comando:

restore spfile from autobackup;

Si tenemos la base de datos en funcionamiento el comando fallará devolviendonos el error:

RMAN> restore spfile from autobackup;
Starting restore at 29/09/12
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=156 device type=DISK
RMAN-00571: ===========================================================
RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============
RMAN-00571: ===========================================================
RMAN-03002: failure of restore command at 09/29/2012 21:58:30
RMAN-06564: must use the TO clause when the instance is started with SPFILE

la solución a este problema es muy sencilla,  vamos a engañar un poco a nuestra base de datos, vamos a recuperarlo a un lugar alternativo y luego lo moveremos con comandos del sistema operativo (o del asm).

RMAN> restore spfile to '?/dbs/spfile.backup' from autobackup;
Starting restore at 29/09/12
using channel ORA_DISK_1
recovery area destination: /opt/oracle/flash_recovery_area
database name (or database unique name) used for search: ORCL
channel ORA_DISK_1: restoring spfile from AUTOBACKUP /opt/oracle/flash_recovery_area/ORCL/autobackup/2012_09_29/o1_mf_s_795264706_86ffo3j0_.bkp
channel ORA_DISK_1: SPFILE restore from AUTOBACKUP complete
Finished restore at 29/09/12
RMAN> quit
$cd /opt/oracle/product/11.2.0.3/dbhome_1/dbs/
mv spfile.backup spfileorcl.ora

P.D en caso de que la instancia estuviese caída y no tuviesemos el spfile en el momento la base de datos deberá de estar en modo MOUNT

2-Creándolo a partir del alert.log

Cada vez que arrancamos y paramos la base de datos, toda la información del spfile es volcada en el fichero alert.log

Starting up:
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
  processes                = 150
  memory_target            = 1536M
  control_files            = "/opt/oracle/oradata/orcl/control01.ctl"
  control_files            = "/opt/oracle/flash_recovery_area/orcl/control02.ctl"
  db_block_size            = 8192
  compatible               = "11.2.0.0.0"
  db_recovery_file_dest    = "/opt/oracle/flash_recovery_area"
  db_recovery_file_dest_size= 3882M
  undo_tablespace          = "UNDOTBS1"
  remote_login_passwordfile= "EXCLUSIVE"
  db_domain                = ""
  dispatchers              = "(PROTOCOL=TCP) (SERVICE=orclXDB)"
  local_listener           = "LISTENER_ORCL"
  audit_file_dest          = "/opt/oracle/admin/orcl/adump"
  audit_trail              = "DB"
  db_name                  = "orcl"
  open_cursors             = 300
  diagnostic_dest          = "/opt/oracle"
.
.
.

Asimismo, tambien deja reflejados los cambios que hacemos si ejecutamos

SQL> alter system set undo_retention=9000;

Y luego miramos el alert, vemos que

ALTER SYSTEM SET undo_retention=9001 SCOPE=BOTH;

Con lo que, podremos  regenerar nuestro spfile creando un fichero de texto con estos valores  (fichero parameter file de texto clásico) , y despues ejecutando el comando.

create spfile from pfile='/tmp/init_SID.ora'

P.D  si la isntancia está levantada, aqui tendremos el mismo problema que cuando intentamos recuperar de RMAn con autobackup, con lo que tendremos que aplicar la misma solución, engañar a oracle desde el sistema operativo

create spfile='?/dbs/spfile.backup' from pfile='/tmp/initSID.ora'
cd $ORACLE_PRODUCT/dbs
mv spfile.backup spfileorcl.ora

 

 

 

 

 

Eventos de espera en disco I

Hoy vamos a hablar un poquito mas de ajuste de bases de datos.

Aplicando la lógica mas pura, si queremos que todo vaya fluido, lo primero que tendremos que prestar atencion a que es lo que nos está haciendo esperar. Así pues, una de las primeras cosas que tenemos que mirar para ajustar una base de datoslos eventos de espra que mas se producen.

Si generalizamos hasta lo evidente, podemos decir que Oracle puede tener problemas de cpu,memoria o disco (esperemos que sea un «o» en ved de un un «y» ) . En esta entrada vamos a dar una pequeña explicación de cuales son los eventos de espera en disco mas comunes.

  • log file sync
  • log file parallel write
  • db file scattered read
  • db file sequential read

log file sync

Cuando una sesion de usuario hace un commit, la información del redo de esta sesion debe de ser llevada al redo log file, este evento nos indica que estamos esperando a que el LGWR nos indique que esta información está guardada correctament en el redo log.
La aparicion de este evento en el «top ten» puede indicarnos un alto número de commits de aplicación.

log file parallel write

Este evento es muy similar al anterior, solamente que es parte normal del funcionamiento de oracle que lleva la informacion la informacion del redo a el redo log (el anterior lo causaba un commit)

db file sequential read

Este evento nos indica que la instancia está esperando una peticion de entrada/salida,esta lectura se está haciendo de bloques contiguos de disco (de ahí lo de sequential).
Por lo general suelen ser lecturas de bloques sueltos, y suele estar asociada a lecturas de filas indexadas

db file scattered read

Es similar a la anterior excepto que en este caso está a la espera de multiples bloques.
Habitualmente está asociada a Full scan tables. Este evento puede tener relaccion con el parámtro DB_FILE_MULTIBLOCK_READ_COUNT en el que indicamos a oracle el numero de bloques consecutivos a leer en una operacion de I/O para un full scan.

Una vez visto lo que quiere decirnos cada uno de estos 4 eventos,es facil entender el porque de que algunos de ellos esten en la parte alta de los eventos de espera de los informes de AWR .

Creando grupos de consumidores. A la caza del bloqueo II

Hasta el momento, en la entrada   A la caza del bloqueo I   teníamos  un  plan de recursos llamado NO_LOCKS que mataba aquellos procesos que estaban mas de 5 segundos bloqueando otra consulta. Este plan de consumidores no era muy util , ya que podía provocar estragos matando indiscriminadamente cualquier bloqueo de mas de 5 segundos, con lo que hoy daremos un paso mas para hacer de ese plan de recursos algo mas útil.

En esta entrada vamos a crear un grupo de consumidores, este grupo de consumidores nos permitirá afinar el perfil de los usuarios sobre los que queremos aplicar nuestro pal de recursos.

El grupo de consumidores lo vamos a llamar USER_NO_LOCK_ALLOW y lo crearemos de la siguiente manera:

BEGIN
 dbms_resource_manager.clear_pending_area();
 dbms_resource_manager.create_pending_area();
 dbms_resource_manager.create_consumer_group(
consumer_group =>'USER_NO_LOCK_ALLOW','Grupo de consumidores alos que no permitiremos bloqueos '
);
 dbms_resource_manager.submit_pending_area();
END;

 

Una vez tenemos nuestro grupo de consumidores creado, es el momento de decidir que usuarios queremos tener dentro de el y cuales no. Oracle 11g nos da muchas opciones para seleccionar este grupo de usuarios, algunas de ellas son:

Por esquema

Si quisieramos añadir a los usuarios del esquema «esquema1» a este grupo de consumidores usariamos el parámetro dbms_resource_manager.oracle_user  del paquete dbms_resource_manager

BEGIN
dbms_resource_manager.clear_pending_area();
dbms_resource_manager.create_pending_area();
dbms_resource_manager.set_consumer_group_mapping(
dbms_resource_manager.oracle_user,'esquema1','USER_NO_LOCK_ALLOW'
);
dbms_resource_manager.submit_pending_area();
 END;

Por maquina cliente

Supongamos que queramos aplicar incluir en nuestro grupo de consumidores solamente las sesiones que se ejecutan desde el servidor cliente «WORKGROUP\client1», para ello  usaríamos dbms_resource_manager.client_machine

BEGIN
dbms_resource_manager.clear_pending_area();
dbms_resource_manager.create_pending_area();
dbms_resource_manager.set_consumer_group_mapping(
dbms_resource_manager.client_machine,'WORKGROUP\MAQUINA1','USER_NO_LOCK_ALLOW'
);
dbms_resource_manager.submit_pending_area();
END;

Por programa

Para separar por programa usaremos la llamada dbms_resource_manager.client_program

BEGIN
dbms_resource_manager.clear_pending_area();
dbms_resource_manager.create_pending_area();
dbms_resource_manager.set_consumer_group_mapping(
dbms_resource_manager.client_program,'PROGRAMA1','USER_NO_LOCK_ALLOW'
);
dbms_resource_manager.submit_pending_area();
END;

Como podeis ver, las posibilidades son muy grandes, en esta entrada nos hemos centrado en capturar sesiones por parámetros de login, pero la funcion dbms_resource_manager.set_consumer_group_mapping permite también seleccionar usuarios por atributos de runtime-.

La lista de las opciones la podeis encontrar en la documentación del paquete
dbms_resource_manager.set_consumer_group_mapping, pero a groso modo se puede resumir en:
Login Attributes

  • oracle_user
  • service_name
  • client_os_user
  • client_program
  • client_machine

 Runtime Attributes

  • module_name
  • module_name_action
  • service_module
  • service_module_action

Ahora solamente nos quedará el incluir este grupo de consumidores en nuestro plan de recursos, indicándole que son los consumidores de este grupo a los que no se les debe permitir el bloquear al resto de los usuarios . Pero esto será en otra entrada.

Creando una estrategia de seguridad incremental con image copies

Hoy vamos a ver como plantear una estrategia de seguridad distinta a la clásica estrategia de RMAN backupsets , esta nueva estrategia se va a basar en image copies y nos va a requerir mucho mas espacio en disco ( el mismo que la base de datos),pero lo que nos permitirá es por el contrario un tiempo de recuperación muchisimo menor.

Nos aseguramos que tenemos suficiente espacio en la FRA (Flash Recovery Area) para albergar nuestra base de de datos entera.

Vemos que tenemos 15,4 Gb libres en la FRA,  la ocupación de nuestra base de datos la calcularemos desde el sistema operativo con el comando

[oracle@test] du -sh oradata/orcl/
5.5G    oradata/orcl/

Ahora haremos un backup de toda nuestra base de datos  al que llamaremos incremental en copias

Nos conectamos a nuestra base de datos y al catálogo de RMAN y ejecutaremos el comando:

run {
1> recover copy of database with tag 'incremental en copias';
2 > backup incremental level 1 for recover of copy with tag 'incremental en copias' database;
}

Viendo el texto de nuestro bloque RUN, lo primero que os estareis preguntando es :
¿por que hacemos un recover si lo que queremos hacer es un backup?
veamos que hacen las  dos lineas del script de backup, pero vamos a verlo en orden inverso.

2> La línea backup incremental level 1 for recover of copy with tag ‘incremental en copias’ database; nos va ha hacer un backup image copy de los ficheros de la base de datos, en caso de no encontrar alguna copia anterior con el tag ‘incremental en copias’  hará una imagecopy completa del datafile, pero , si encontrara una imagecopy anterior con ese tag, lo que hará es copiar solamente los cambios incrementales de esa imagecopy.

1> El comando recover copy of database with tag ‘incremental en copias’; no va ha hacer un recovery de los ficheros de la base de datos, lo que va ha hacer es, recuperar sobre la image copy ‘incremental en copias’ los cambios incrementales que encuentre creados por la línea  2> .

Esto que a priori puede ser muy lioso, se ve claramente si ejecutamos nuestros bloque de rman varias veces.

Vamos a ejecutar nuestros script de backup para comprobar que lo dicho anteriormente es cierto


Veamos la salida del comando en la primera ejecucion

Vemos la linea 1 del script  no ha hecho nada, y nuestra linea 2  es similar a la que saldría haciendo un simple backup  basado encopias de todos los datafiles de la base de datos.

Ejecucion 1
Starting recover at 23/08/12
using channel ORA_DISK_1
no copy of datafile 1 found to recover
no copy of datafile 2 found to recover
no copy of datafile 3 found to recover
no copy of datafile 4 found to recover
no copy of datafile 5 found to recover
Finished recover at 23/08/12

Starting backup at 23/08/12
using channel ORA_DISK_1
no parent backup or copy of datafile 3 found
no parent backup or copy of datafile 1 found
no parent backup or copy of datafile 2 found
no parent backup or copy of datafile 4 found
no parent backup or copy of datafile 5 found
channel ORA_DISK_1: starting datafile copy
input datafile file number=00003 name=/opt/oracle/oradata/orcl/undotbs01.dbf
output file name=/opt/oracle/flash_recovery_area/ORCL/datafile/o1_mf_undotbs1_83dn40z2_.dbf tag=INCREMENTAL EN COPIAS RECID=94 STAMP=792092958
channel ORA_DISK_1: datafile copy complete, elapsed time: 00:02:18
channel ORA_DISK_1: starting datafile copy
input datafile file number=00001 name=/opt/oracle/oradata/orcl/system01.dbf
output file name=/opt/oracle/flash_recovery_area/ORCL/datafile/o1_mf_system_83dn8gv0_.dbf tag=INCREMENTAL EN COPIAS RECID=95 STAMP=792093020
channel ORA_DISK_1: datafile copy complete, elapsed time: 00:00:55
channel ORA_DISK_1: starting datafile copy
input datafile file number=00002 name=/opt/oracle/oradata/orcl/sysaux01.dbf
output file name=/opt/oracle/flash_recovery_area/ORCL/datafile/o1_mf_sysaux_83dnb5vv_.dbf tag=INCREMENTAL EN COPIAS RECID=96 STAMP=792093064
channel ORA_DISK_1: datafile copy complete, elapsed time: 00:00:45
channel ORA_DISK_1: starting datafile copy
input datafile file number=00004 name=/opt/oracle/oradata/orcl/users01.dbf
output file name=/opt/oracle/flash_recovery_area/ORCL/datafile/o1_mf_users_83dnclot_.dbf tag=INCREMENTAL EN COPIAS RECID=97 STAMP=792093085
channel ORA_DISK_1: datafile copy complete, elapsed time: 00:00:15
channel ORA_DISK_1: starting datafile copy
input datafile file number=00005 name=/opt/oracle/oradata/orcl/example01.dbf
output file name=/opt/oracle/flash_recovery_area/ORCL/datafile/o1_mf_example_83dnd1yn_.dbf tag=INCREMENTAL EN COPIAS RECID=98 STAMP=792093093
channel ORA_DISK_1: datafile copy complete, elapsed time: 00:00:07
Finished backup at 23/08/12

Starting Control File and SPFILE Autobackup at 23/08/12
piece handle=/opt/oracle/flash_recovery_area/ORCL/autobackup/2012_08_23/o1_mf_s_792093100_83dndg0h_.bkp comment=NONE
Finished Control File and SPFILE Autobackup at 23/08/12

 

Si lo ejecutamos por segunda vez, el comando recover copy of database with tag ‘incremental en copias’  (línea 1) seguirá sin encontrar un backup llamado asi, con lo que no aplicará nada, pero el comando backup incremental level 1 for recover of copy with tag ‘incremental en copias’ database; (línea 2)  si que encontrará cambios en la base de datos, con lo que si que debería de copiar nuevos datos.
Veamos que ocurre si lo ejecutamos de nuevo

Ejecucion 2
RMAN> run {
recover copy of database with tag 'incremental en copias';
backup incremental level 1 for recover of copy with tag 'incremental en copias' database;
}2> 3> 4>

Starting recover at 23/08/12
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=149 device type=DISK
no copy of datafile 1 found to recover
no copy of datafile 2 found to recover
no copy of datafile 3 found to recover
no copy of datafile 4 found to recover
no copy of datafile 5 found to recover
Finished recover at 23/08/12

Starting backup at 23/08/12
using channel ORA_DISK_1
channel ORA_DISK_1: starting incremental level 1 datafile backup set
channel ORA_DISK_1: specifying datafile(s) in backup set
input datafile file number=00003 name=/opt/oracle/oradata/orcl/undotbs01.dbf
input datafile file number=00001 name=/opt/oracle/oradata/orcl/system01.dbf
input datafile file number=00002 name=/opt/oracle/oradata/orcl/sysaux01.dbf
input datafile file number=00004 name=/opt/oracle/oradata/orcl/users01.dbf
input datafile file number=00005 name=/opt/oracle/oradata/orcl/example01.dbf
channel ORA_DISK_1: starting piece 1 at 23/08/12
channel ORA_DISK_1: finished piece 1 at 23/08/12
piece handle=/opt/oracle/flash_recovery_area/ORCL/backupset/2012_08_23/o1_mf_nnnd1_INCREMENTAL_EN_COPIA_83dntqbk_.bkp tag=INCREMENTAL EN COPIAS comment=NONE
channel ORA_DISK_1: backup set complete, elapsed time: 00:03:15
Finished backup at 23/08/12

Starting Control File and SPFILE Autobackup at 23/08/12
piece handle=/opt/oracle/flash_recovery_area/ORCL/autobackup/2012_08_23/o1_mf_s_792093756_83do0xlz_.bkp comment=NONE
Finished Control File and SPFILE Autobackup at 23/08/12

¿Que ocurrirá en la tercera ejecución?

El comando recover copy of database with tag ‘incremental en copias’ ya tiene que haber encontrado datos ya que tiene la primera copia,con lo que esta vez si que ejecutará en recover, pero no lo hará sobre los datafiles originales, sino que aplicará los cambios que hemos guardado en la ejecución 2 sobre las copias de la ejecución 1 y el incremental que hemos hecho antesvolverá a encontrar cambios en la base de datos, con lo que si que debería de volver a copiar nuevos datos.
Veamos la salida de esta tercera ejecución:

 Ejecucion 3
RMAN> run {
recover copy of database with tag 'incremental en copias';
backup incremental level 1 for recover of copy with tag 'incremental en copias' database;
}
2> 3> 4>
Starting recover at 23/08/12
using channel ORA_DISK_1
channel ORA_DISK_1: starting incremental datafile backup set restore
channel ORA_DISK_1: specifying datafile copies to recover
recovering datafile copy file number=00001 name=/opt/oracle/flash_recovery_area/ORCL/datafile/o1_mf_system_83dn8gv0_.dbf
recovering datafile copy file number=00002 name=/opt/oracle/flash_recovery_area/ORCL/datafile/o1_mf_sysaux_83dnb5vv_.dbf
recovering datafile copy file number=00003 name=/opt/oracle/flash_recovery_area/ORCL/datafile/o1_mf_undotbs1_83dn40z2_.dbf
recovering datafile copy file number=00004 name=/opt/oracle/flash_recovery_area/ORCL/datafile/o1_mf_users_83dnclot_.dbf
recovering datafile copy file number=00005 name=/opt/oracle/flash_recovery_area/ORCL/datafile/o1_mf_example_83dnd1yn_.dbf
channel ORA_DISK_1: reading from backup piece /opt/oracle/flash_recovery_area/ORCL/backupset/2012_08_23/o1_mf_nnnd1_INCREMENTAL_EN_COPIA_83dntqbk_.bkp
channel ORA_DISK_1: piece handle=/opt/oracle/flash_recovery_area/ORCL/backupset/2012_08_23/o1_mf_nnnd1_INCREMENTAL_EN_COPIA_83dntqbk_.bkp tag=INCREMENTAL EN COPIAS
channel ORA_DISK_1: restored backup piece 1
channel ORA_DISK_1: restore complete, elapsed time: 00:00:07
Finished recover at 23/08/12

Starting backup at 23/08/12
using channel ORA_DISK_1
channel ORA_DISK_1: starting incremental level 1 datafile backup set
channel ORA_DISK_1: specifying datafile(s) in backup set
input datafile file number=00003 name=/opt/oracle/oradata/orcl/undotbs01.dbf
input datafile file number=00001 name=/opt/oracle/oradata/orcl/system01.dbf
input datafile file number=00002 name=/opt/oracle/oradata/orcl/sysaux01.dbf
input datafile file number=00004 name=/opt/oracle/oradata/orcl/users01.dbf
input datafile file number=00005 name=/opt/oracle/oradata/orcl/example01.dbf
channel ORA_DISK_1: starting piece 1 at 23/08/12
channel ORA_DISK_1: finished piece 1 at 23/08/12
piece handle=/opt/oracle/flash_recovery_area/ORCL/backupset/2012_08_23/o1_mf_nnnd1_INCREMENTAL_EN_COPIA_83do2ztw_.bkp tag=INCREMENTAL EN COPIAS comment=NONE
channel ORA_DISK_1: backup set complete, elapsed time: 00:02:26
Finished backup at 23/08/12

Starting Control File and SPFILE Autobackup at 23/08/12
piece handle=/opt/oracle/flash_recovery_area/ORCL/autobackup/2012_08_23/o1_mf_s_792093966_83do7h1p_.bkp comment=NONE
Finished Control File and SPFILE Autobackup at 23/08/12

Así pues vemos como vamos teniendo un juego de image copies de la base de datos que se van actualizando diariamente.

Alguna de las características de este backup son.

  1. Menor tiempo de recuperacion: El tiempo de recuperacion de uno de estos datafiles  será mas corto que el tiempo que empleariamos en restaurarlo desde un backuppiece ya que el level 0 es un backup image copy
  2. Alta ocupacion en disco: Estos ficheros son un image copy,lo que significa que estamos copiando todo el fichero a la FRA, este la ocupación del datafile al 10% o al 100%