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.

Añadir un recurso a grid control /clusterware

Una de las ventajas que nos ofrece Oracle clusterware o Oracle Grid control es el gestionar una serie de elementos/procesos/aplicaciones arrancándolas o parándolas de manera centralizada.

Si instalamos nuestras bases con  la infraestructura de grid control, podemos aprovecharnos de la misma para gestionar en el arranque otros elementos como servidores de aplicaciones o la consola de administracion.Esto puede sernos muy util por ejemplo en caso de reinicio del servidor ya que grid control se puede encargar de levantar estos procesos.

En esta entrada vamos a ver como añadir la consola de administracion a el grid control, pero puede ser igualmente valido para cualquier procesos/servidor como podría ser un tomcat, apache o cualquier cosa por el estilo.

Como pasos prvios necesitaremos:

  • Script de arranque/parada/check de nuestra aplicacion, en nuestro caso estará en /opt/oracle/app/admin/PRUEBAS/consola/dbconsole
  • SID del grid  en nuestro caso +ASM
  • SID de la instancia en nuestro caso PRUEBAS
  • Nombre del servidor: En nuestro caso  pruebas.org

Vamos primero a ver el script que arranca/para /chequea la consola

#! /bin/sh
# Author:    Clemente Pamplona
# Date:      15-10-2012
# Usage:     dbconsole [start|stop|status|check]
# Purpose:   Arranca ,para y quequea la dbconsole 
# Copyright: GNU GPL

export ORACLE_SID=PRUEBAS
export ORAENV_ASK=NO
export ORACLE_BASE=/opt/oracle
export ORACLE_HOSTNAME=pruebas.org
. oraenv 
case $1 in
    START|start)
        emctl start dbconsole
         ;;
    STOP|stop)
        emctl stop dbconsole
        ;;
    STATUS|status)
        emctl status dbconsole
        ;;
    CHECK|check)
      rm /var/tmp/consola_status.txt
      emctl status dbconsole 
      if [ $? != 0 ]
        then exit 1;
        fi
        ;;

    *) echo "Usage: dbconsole [start|stop|status|check]"
       exit
     ;;
   esac

Este script podemos probarlo como usuario oracle en el servidor.

Una vez tenemos nuestro script creado que es capaz de arrancar y parar la consola, cargaremos el entorno del grid.

[oracle@pruebas.org consola]$ . oraenv
ORACLE_SID = [oracle] ? +ASM

Lo primero que vamos ha hacer es comprobar que elementos tiene corriendo nuestro grid

[oracle@pruebas.org consola]$ crs_stat -t
Name              Type                Target    State     Host
-----------------------------------------------------------------
ora.DATA.dg       ora.diskgroup.type ONLINE    ONLINE    pruebas.org
ora.LISTENER.lsnr ora.listener.type  ONLINE    ONLINE    pruebas.org
ora.asm           ora.asm.type       ONLINE    ONLINE    pruebas.org
ora.cssd          ora.cssd.type      ONLINE    ONLINE    pruebas.org
ora.pruebas.db    ora.database.type  ONLINE    ONLINE    pruebas.org
ora.diskmon       ora.diskmon.type   OFFLINE   OFFLINE
ora.evmd          ora.evm.type       ONLINE    ONLINE    pruebas.org
ora.ons           ora.ons.type       OFFLINE   OFFLINE

Vemos como tenemos claramente identificados el ASM, el Listener y la instancia . Así pues vamos  a añadrir un recurso local  tal y como dice la documentacion del crsctl

crsctl add resource dbconsola_pruebas -type local_resource \
-attr "ACTION_SCRIPT=/opt/oracle/app/admin/PRUEBAS/consola/dbconsole,\
 CHECK_INTERVAL='300',\
 RESTART_ATTEMPTS='2',\
 START_DEPENDENCIES=hard(ora.pruebas.db)"

Con esto le indicamos que cree:

  • recurso llamado pruebas
  • del tipo local_resource
  • usará nuestro script para actuar sobre él
  • chequeará su funcionamiento cada 5 minutos (300 segundos)
  • Intentará rearrancarlo 2 veces
  • Para arrancarlo deberá de estar la base de datos pruebas activa

Ahora podremos arrancarlo /pararlo /monitorizarlo desde las herramientas del grid.

$ORACLE_HOME/bin/crsctl start resource dbconsola_pruebas

$ORACLE_HOME/bin/crsctl stop resource dbconsola_pruebas

$ORACLE_HOME/bin/crsctl status resource dbconsola_pruebas

O bien con la salida total del sistema

[oracle@pruebas.org consola]$ crs_stat -t
Name              Type                Target    State     Host
-----------------------------------------------------------------
dbco..._pruebas  local_resource      ONLINE    ONLINE    pruebas.org
ora.DATA.dg       ora.diskgroup.type ONLINE    ONLINE    pruebas.org
ora.LISTENER.lsnr ora.listener.type  ONLINE    ONLINE    pruebas.org
ora.asm           ora.asm.type       ONLINE    ONLINE    pruebas.org
ora.cssd          ora.cssd.type      ONLINE    ONLINE    pruebas.org
ora.pruebas.db    ora.database.type  ONLINE    ONLINE    pruebas.org
ora.diskmon       ora.diskmon.type   OFFLINE   OFFLINE
ora.evmd          ora.evm.type       ONLINE    ONLINE    pruebas.org
ora.ons           ora.ons.type       OFFLINE   OFFLINE

 

P.D uede parecer algo evidente, pero, nuestro recurso nunca podrá llamarse ora.

Funcionamiento de las variables NLS

Hoy vamos a ver una de las cosas mas simples que hay en Oracle y de las que mas quebraderos de cabeza traen, la globalizacion.

Las variables que definen el idioma, numeros,fechas, ordenacion… de Oracle son las llamadas variables de globalización de Oracle o  mas comumente parámetros NLS.

Para evitar problemas con los acentos, eñes, puntos/comas,fechas…. deberias de tener claro cual es el NLS_LANG que tienes/quieres . Pero vamos a dejar este NLS_LANG para un poco mas adelante

Las principales variables para un entorno de oracle son:
•    NLS_LANGUAJE: Se usa para los mensajes (incluidos los de error)
•    NLS_DATE_LANGUAJE: Para los nombres de día y mes
•    NLS_SORT: (Binary) para la ordenación lingüística
Adicionalmente, tenemos una variable de entorno que nos define un amplio número de variables , este prámetro es NLS_TERRITORY , esta variable define las  siguientes subvariables
•    NLS_CURRENCY
•    NLS_DUAL_CURRENCY
•    NLS_ISO_CURRENCY
•    NLS_DATE_FORMAT
•    NLS_NUMERICA_CHARACTERS
•    NLS_TIMESTAMP_FORMAT
•    NLS_TIMESTAMP_TZ_FORMAT

Una vez visto esto, volvemos a NLS_LANG que se define como:
NLS_LANG=<language>_<territory>.<character set>  (por ejemplo export NLS_LANG=AMERICAN_AMERICA.WE8ISO8859P1 o en español  export NLS_LANG=SPANISH_SPAIN.WE8MSWIN1252 )
Así pues, si definimos correctamente nuestra variable NLS_LANG tendremos practicamente todas las variables de entorno definidas y conseguiremos que nuestras consultas tengan los caracteres que queremos.

Las variables de globalización de una base de datos se pueden fijar a 5 niveles:

  • Database
  • Instancia
  • Cliente
  • Sesión
  • Sentencia

Cada nivel inferior anula a un superior, es decir, si yo fijo una variable de entorno en una sentencia esta variable prevalecerá sobre las variables de base de datos, instancia o sesion.

Llegados a este punto, sabemos que queremos, pero, no sabemos que tenemos. ¿Como podemos saber que parámetros NLS tenemos definidos en nuestro cliente/aplicacion?

La solucion es muy sencilla, solamente tenemos que conectarnos y preguntar.

Para ver todas las variables de nuestra conexion de cliente

SQL> set pagesize 200;
column parameter format a25;
column value format a40;
select * from v$nls_parameters;

PARAMETER                 VALUE
------------------------- ----------------------------------------
NLS_LANGUAGE              SPANISH
NLS_TERRITORY             SPAIN
NLS_CURRENCY              
NLS_ISO_CURRENCY          SPAIN
NLS_NUMERIC_CHARACTERS    ,.
NLS_CALENDAR              GREGORIAN
NLS_DATE_FORMAT           DD/MM/RR
NLS_DATE_LANGUAGE         SPANISH
NLS_CHARACTERSET          WE8MSWIN1252
NLS_SORT                  SPANISH
NLS_TIME_FORMAT           HH24:MI:SSXFF
NLS_TIMESTAMP_FORMAT      DD/MM/RR HH24:MI:SSXFF
NLS_TIME_TZ_FORMAT        HH24:MI:SSXFF TZR
NLS_TIMESTAMP_TZ_FORMAT   DD/MM/RR HH24:MI:SSXFF TZR
NLS_DUAL_CURRENCY         
NLS_NCHAR_CHARACTERSET    AL16UTF16
NLS_COMP                  BINARY
NLS_LENGTH_SEMANTICS      BYTE
NLS_NCHAR_CONV_EXCP       FALSE

19 rows selected.

o la variable languaje exportada del entorno

 SQL> SELECT USERENV ('language') FROM DUAL;

USERENV('LANGUAGE')
----------------------------------------------------
SPANISH_SPAIN.WE8MSWIN1252

Con esto seguramente encontremos la explicación de por que las fechas no nos salen como queremos, vemos caracteres extraños en las ñ o nos fallan las inseciones por culpa de los . y ,

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.

Error RMAN-06172 recuperando del autobackup

En la entrada anterior  vimos como recuperar un spfile desde el backup con rman.

Desgraciadamente no siempre todo funciona a la primera, y , como Murphy nunca falla, el error inusual siempre tiene que tocarnos a nosotros. La teoría nos dice que  para recuperar un spfile o un controlfile de rman solamente hay que hacer

RMAN> restore spfile from autobackup;

Pero que ocurre si no funciona?

La recuperacion tanto del controlfile como del spfile puede complicarse si recibimos un RMAN-06172 . La salida del comando será algo similar a esto :

Starting restore at 28/09/12
allocatedchannel: ORA_DISK_1
channel ORA_DISK_1: sid=85 instance=pruebas devtype=DISK
recovery area destination: +DG_FRA
database name (ordatabaseuniquename) used for search: PRUEBAS
channel ORA_DISK_1: no autobackupsfound in the recovery area
channel ORA_DISK_1: looking for autobackup on day: 20120928
channel ORA_DISK_1: looking for autobackup on day: 20120927
channel ORA_DISK_1: looking for autobackup on day: 20120926
channel ORA_DISK_1: looking for autobackup on day: 20120925
channel ORA_DISK_1: looking for autobackup on day: 20120924
channel ORA_DISK_1: looking for autobackup on day: 20120923
channel ORA_DISK_1: looking for autobackup on day: 20120922
Channel ORA_DISK_1: no autobackup in 7 daysfound
RMAN-00571:   =================================
RMAN-00569: == ERROR MESSAGE STACK FOLLOWS
RMAN-00571: ===================================
RMAN-03002: failure of restorecommand at 09/28/2012 11:40:37
RMAN-06172: no autobackup found or  specified handle is not a valid copy or piece

Llegados a este punto lo primero que tenemos que comprobar es si reamente tenemos algún backup de nuestro spfile.

RMAN por defecto hace una copia de controlfile y spfile cada vez que se lleva a backup el tablespace system, así pues, si tenemos un backup válido en cinta de este tablespace deberemos de tener un backup del spfile.  Para consultar donde está esta backup, nos conectaremos desde  rman y ejecutaremos la consulta

RMAN >List backup;

Este comando nos volcará mucha información ordenada cronológicamente, con lo que nosotros tendremos que buscar en la parte inferior el registro del último día de backup donde esté el spfile.

El registro dirá algo como:

BS Key  Type LV SizeDeviceTypeElapsed Time Completion Time
------- ---- -- ---------- ----------- ------------ ---------------
797503  Incr 0  5.44G      SBT_TAPE    00:03:52     27/09/12
        BP Key: 797556   Status: AVAILABLE  Compressed: NO  Tag: TAG20120926T210038
Handle: intranet_backup<pruebas_8084:795042038:1>.dbf   Media:
List of Datafiles in backup set 797503
  File LV TypeCkp SCN    Ckp Time Name
  ---- -- ---- ---------- -------- ----
  1    0  Incr 139540429  26/09/12 +DG_DAT/pruebas/datafile/system.257.713298945
  2    0  Incr 139540429  26/09/12 +DG_DAT/pruebas/datafile/undotbs1.262.713298945
  3    0  Incr 139540429  26/09/12 +DG_DAT/pruebas/datafile/sysaux.261.713298945
  4    0  Incr 139540429  26/09/12 +DG_DAT/pruebas/datafile/undotbs2.264.713298947
  5    0  Incr 139540429  26/09/12 +DG_DAT/pruebas/datafile/users.345.713298947
  6    0  Incr 139540429  26/09/12 +DG_DAT/pruebas/datafile/pruebas.260.730901167

BS Key  Type LV SizeDeviceTypeElapsed Time Completion Time
------- ---- -- ---------- ----------- ------------ ---------------
797504Incr 0  15.00M     SBT_TAPE    00:00:06     27/09/12
        BP Key: 797557   Status: AVAILABLE  Compressed: NO  Tag: TAG20120926T210038
Handle:pruebas_backup<pruebas_8085:795042273:1>.dbf   Media:
  Control File Included: Ckp SCN: 139541276    Ckp time: 27/09/12
SPFILE Included: Modification time: 27/09/12

Aquí podemos ver como el 27 del 9 hicimos backup del tablespace system en el backupset 797504 lo que provoca que el RMAN haga backup de el SPFILE en el backupset  797504 en un fichero que el software de backup tiene identificado como  “pruebas_backup<pruebas_8085:795042273:1>.dbf”

Luego, si que tenemos respaldado el spfile.

¿Que hacemos ahora para recuperarlo?

Simplemente tendremos que ejecutar el comando de restauración indicando exactamente desde el fichero en el que queremos hacer la copia.

Vamos a rizar un poco mas el rizo y hagamos que la copia no esté ya en  la FRA,sino que el contenido ya está en cinta. Lo primero que tendremos que hacer es localizar un canal a cinta, para ello lo más sencillo es buscar el script de backup y copiar los parámteros específicos de  la línea del allocate channel .

En nuestro caso el resultado será :

allocate channel 'dev_0' type 'sbt_tape'   
parms 'ENV=(OB2BARTYPE=Oracle8,OB2APPNAME=pruebas,OB2BARLIST=pruebas_backup)';

Así pues, ya tenemos la línea que nos conectará con el software de backup, ahora tenemos que indicarle el nombre del fichero del cual queremos sacar el spfile, en nuestro caso hemos visto  que era  “pruebas_backup<pruebas_8085:795042273:1>.dbf” .

Con esto solamente nos queda hacer un bloque run de RMAN que nos recupere el spfile a una ubicación alternativa:

run {
allocate channel 'dev_0' type 'sbt_tape'
parms 'ENV=(OB2BARTYPE=Oracle8,OB2APPNAME=pruebas,OB2BARLIST=pruebas_backup)';
restore  spfile to '/tmp/spfile_restaurado_cinta.ora' from 'pruebas_backup<pruebas_8085:795042273:1>.dbf';
 }

Nos conectaremos a  nuestra base de datos target  y catálogo y ejecutamos nuestro bloque run,con el resultado:

run {
allocate channel 'dev_0' type 'sbt_tape'
parms 'ENV=(OB2BARTYPE=Oracle8,OB2APPNAME=pruebas,OB2BARLIST=pruebas_backup)';
restore  spfile to '/tmp/spfile_restaurado_cinta.ora' from 'pruebas_backup<pruebas_8085:795042273:1>.dbf';
}
3>allocatechannel 'dev_0' type 'sbt_tape'
parms 'ENV=(OB2BARTYPE=Oracle8,OB2APPNAME=pruebas,OB2BARLIST=pruebas_backup)';
4>restorespfileto '/tmp/spfile_restaurado_cinta.ora' from 'pruebas_backup<pruebas_8085:795042273:1>.dbf';
5> }
allocatedchannel: dev_0
channel dev_0: sid=147 instance=pruebas1 devtype=SBT_TAPE
channel dev_0: Data Protector A.06.11/PHSS_40470/PHSS_40471/DPSOL_00391/DPLNX_
Startingrestore at 28/09/12
channel dev_0: autobackupfound: pruebas_backup<pruebas_8085:795042273:1>.dbf
[Normal] From: OB2BAR_SBT_CHANNEL@server.local "pruebas"  Time: 09/28/12 12:29:09
Starting OB2BAR Restore: server.local:pruebas_backup<pruebas_8085:795042273:1>.dbf "Oracle8"
[Normal] From: OB2BAR_SBT_CHANNEL@server.local "pruebas"  Time: 09/28/12 12:29:09
Starting OB2BAR Restore: server.local:pruebas_backup<pruebas_8085:795042273:1>.dbf "Oracle8"
[Normal] From: OB2BAR_SBT_CHANNEL@server.local "pruebas"  Time: 09/28/12 12:29:10
Completed OB2BAR Restore: server.local:pruebas_backup<pruebas_8085:795042273:1>.dbf "Oracle8"
[Normal] From: OB2BAR_SBT_CHANNEL@server.local "pruebas"  Time: 09/28/12 12:29:10
Completed OB2BAR Restore: server.local:pruebas_backup<pruebas_8085:795042273:1>.dbf "Oracle8"
channel dev_0: SPFILE restorefromautobackup complete
Finishedrestore at 28/09/12
releasedchannel: dev_0
Recovery Manager complete..

Ahora solamente tenemos que buscar el fichero /tmp/spfile_restaurado_cinta.ora donde tenemos la imagen del  spfile recuperada del backup.

 

 

 

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