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.

Bienvenidos a Oracle 18c

Si.
Habeis oido bien.
Vamos a tener oracle 18c.

¿que ha pasado con la 13,14,15,16 y 17 ?

Realmente no ha pasado nada, puesto que la 18c es lo mismo que la 12.2.0.2 . Lo que ocurre es que Oracle va a cambiar la notacion de las bases de datos, nombrandolas por el año en el que esta y el trimestre

Si miramos la grafica de suporte con las versiones (Doc ID 742060.1) vemos claramente como la 12 pasa a 18

Esto viene bien explicado en los blogs de Oracle que enlazamos abajo, y especialmente en el de Mike Dietrich’s, que os aclara que ahora vamos a pasar de tener PSU y BP a tener , RU y RUR

Veamos rapidamente que es cada una de las cosas :

  • PSU EL PSU (Patch Set Update) contenia una agrupacion de parches.
  • BU EL BU (Bundle update) contenia una agrupacion de parches y ADEMAS , los fixes y mejoras de la base de datos.

Es decir, el PSU solventaba bugs, pero no modificaba las funcionalidades, algo que es si que hacian los Bundle Patches

¿Que vamos a tener ahora?

  • RU: Son practicamente el equivalente a los BP , ya que contienen los parches y las mejoras, se estima que su lanzamiento sera trimestral y seran cumulativos.
  • RUR: Son el nuevo concepto de Oracle en e parcheado, son Release Update Revision , eliminan las mejoras y cambios funcionales del ultimo RU, pero si que aplican los parches.

¿Cual es el cambio mas importante?

Ademas del cambio de nombre que no deja de ser algo anecdotico, el verdadero cambio es que , con el uso de las RU vamos a estar aplicando cada trimestre no solamente los parches sino cualquier fix/mejora que Oracle este introduciendo en el motor.

En caso de que detectemos que este «fix» introduce cambios de comportamiento en el motor ( que la aplicacion va peor), entonces tendremos que añadir el RUR que deshabilita los cambios del RU que hemos aplicado.
En resumen, que Oracle nos esta obligando a subir las funcionalidades de las bases de datos a la ultima version.

Mas informacion en :

Datafiles UNAMED en dataguard

Hoy vamos a ver un a pequeña entrada de un error bastante común en dataguard.

El problema se da cuando la base de datos standby deja de aplicar

DGMGRL> show configuration verbose
Configuration - test
  Protection Mode: MaxPerformance
  Members:
  DBTEST        - Primary database
    DBTEST_STBY   - Physical standby database
      Error: ORA-16810: multiple errors or warnings detected for the database

Ante un error tan genérico como este, lo primero que hemos de hacer es buscar en el alert.log de la base de datos del standby.
En este alert.log ya vemos un error mas claro

Errors in file /u01/app/oracle/diag/rdbms/dbtest_stby/dbtest/trace/dbtest_mrp0_3972.trc:
ORA-01111: name for data file 21 is unknown - rename to correct file
ORA-01110: data file 21: '/u01/app/oracle/product/12.1.0.2/dbhome_1/dbs/UNNAMED0021'
ORA-01157: cannot identify/lock data file 21 - see DBWR trace file
ORA-01111: name for data file 21 is unknown - rename to correct file
ORA-01110: data file 21: '/u01/app/oracle/product/12.1.0.2/dbhome_1/dbs/UNNAMED0021'

Que es ese datafile que aparece en el $ORACLE_HOME/dbs llamado UNNAMED?

La respuesta nos la da oracle en la nota ID 739618.1..
Estos ficheros aparecen en el equipo de standby cuando se ha creado un datafile en el primario y el secundario no ha podido crearlo (por falta de espacio, error de configuración …. )

Como lo solucionamos ?

Lo primero que tenemos que hacer es cambiar el STANDBY_FILE_MANAGEMENT a MANUAL ya que vamos a modificar manualmente la ubicación de ficheros.

ALTER SYSTEM SET STANDBY_FILE_MANAGEMENT=MANUAL;

Tras esto, identificaremos en la base de datos primary cual es la ubicación correcta del fichero, si miramos en el extracto anterior del alert.log, veremos que se trata del datafile 21, así pues, iremos a la base de datos primary y veremos donde esta ubicado .

SQL>   select file_name,tablespace_name,bytes/1024/1024/1024 Gb
  from dba_data_files where file_id=21;

FILE_NAME  		                      TABLESPACE_NAME      GB 
----------------------------------------------------------------
+DATA_01/DBTEST/DATAFILE/testdf.791.968123327   TESTDF           5

Ahora tenemos que ir al standby y mover el fichero UNNAMED a su lugar correcto, para ello no usaremos el MOVE sino el comando CREATE DATAFILE AS

alter database create datafile 
'/u01/app/oracle/product/12.1.0.2/dbhome_1/dbs/UNNAMED0021'
 as '+DATA_01' ;

Como podéis ver, no ha indicado el nombre que debe de tener el datafile, solamente la ruta, esto es por que tenemos definido el parametro db_recovery_file_dest que nos lo dejara con el nombre correcto.

Posible errores

Efectivamente, con el comando anterior no va a funcionar, ya que nos dara el error

ERROR at line 1:
ORA-01136: specified size of file 204 (80 blocks) is less than original size of
655360 blocks
ORA-01111: name for data file 204 is unknown - rename to correct file
ORA-01110: data file 204:
'/u01/app/oracle/product/12.1.0.2/dbhome_1/dbs/UNNAMED0021'

Que hemos echo mal ?

No hemos echo nada mal, lo que ocurre es que cuando la ubicación de destino es dentro el ASM tendremos que indicarle el tamaño exacto del fichero .
En el alert nos ha indicado que el tamaño es de 655360 blocks
Si miramos el tamaño de bloque que tenemos :

SQL> show parameter block_size
NAME               TYPE        VALUE
------ --------------------------------------
db_block_size     integer       8192

Llevando a cabo una pequeña operacion aritmética 655360 *8192=5368709120

Ya podemos ejecutar el comando completo

alter database create datafile 
'/u01/app/oracle/product/12.1.0.2/dbhome_1/dbs/UNNAMED0021' 
as '+DATA_01'size 5368709120;

Con esto tenemos el problema solucionado.

Volvemos a poner el standby en modo management auto

ALTER SYSTEM SET STANDBY_FILE_MANAGEMENT=AUTO;

Y activamos el broker de nuevo desde el primario.

DGMGRL> show configuration verbose
Configuration - test
  Protection Mode: MaxPerformance
  Members:
  DBTEST        - Primary database
    DBTEST_STBY   - Physical standby database
      Error: ORA-16810: multiple errors or warnings detected for the database

DGMGRL> enable database 'DBTEST_STBY'
Disabled.
DGMGRL> enable database 'DBTEST_STBY'
Enabled.
DGMGRL> show configuration verbose
Configuration - test
  Protection Mode: MaxPerformance
  Members:
  DBTEST        - Primary database
    DBTEST_STBY   - Physical standby database
.
.

Configuration Status:
SUCCESS

Como siempre , mas información en las notas de soporte

  • How to resolve ORA-01111 ORA-01110 ORA-01157 in a physical standby database (Doc ID 1416554.1)
  • Background Media Recovery terminated with ORA-1274 after adding a Datafile (Doc ID 739618.1)

Apagando instancias

Hoy vamos aver un pequeño script que nos facilitara el apagar todas las bases de datos de un servidor aunque no esten incluidas en el rac

Si nos fijamos un poco en el script, podemos ver como las funciones de apagado estan comentadas, esto es una mera medida de seguridad para evitar posibles errrores de «copy & paste »

[cc lang=»shell»]
#!/bin/bash
#
#
# Name: stop_oratab_alone.sh
# Desc: Stops all oratab databases (not RAC)

function estado
{
echo » The status of $ORACLE_SID is:»
sqlplus -s «/as sysdba» << EOF 2>>/dev/null
set linesize 400;
column host_name format a30;
column instance_name format a20;
column Started format a25;
column uptime format a60;
select
host_name,
instance_name,
to_char(startup_time,’DD-MON-YYYY HH24:MI:SS’) Started,
‘Uptime : ‘ || floor(sysdate – startup_time) || ‘ days(s) ‘ ||
trunc( 24*((sysdate-startup_time) –
trunc(sysdate-startup_time))) || ‘ hour(s) ‘ ||
mod(trunc(1440*((sysdate-startup_time) –
trunc(sysdate-startup_time))), 60) ||’ minute(s) ‘ ||
mod(trunc(86400*((sysdate-startup_time) –
trunc(sysdate-startup_time))), 60) ||’ seconds’ uptime
from
sys.v_\$instance;
EOF

}

function apagar
{
#srvctl stop database -d ${ORACLE_DB} ${ORACLE_SID} -stopoption IMMEDIATE

}

function test_status
{
srvctl status database -d ${ORACLE_DB} ${ORACLE_SID} RED=’\033[0;31m’
GREEN=’\033[0;32m’
NC=’\033[0m’
COUNT=` ps -ef |grep smon |grep -v grep | grep $ORACLE_SID|wc -l `
if [ ${COUNT} -ne 0 ]; then
printf «${RED}FAIL${NC} There are ${COUNT} smon_${ORACLE_SID} processes\n»
else
printf «${GREEN} OK ${NC} There is not any smon_${ORACLE_SID} process\n»
fi
}

export ORAENV_ASK=NO
export NODO=`hostname -a`
for i in `cat /etc/oratab |tr ‘:’ ‘ ‘ |awk ‘{ print ($1)’}|grep -v «#»|grep -v «+»|grep -v «-» |grep -v [1-9]`
do
clear
ORACLE_DB=$i
ORACLE_SID=$i
. oraenv 2>/dev/null
export ORACLE_SID=`ps -ef|grep pmon|grep $i |tr ‘_’ ‘ ‘|awk ‘{ print ($10)’}`
echo «New oracle SID=$ORACLE_SID»
estado;
#apagar
test_status;

read
echo «[press any key]»
done

[/cc]

Este script tiene una particularidad, y es que no esta pensado para usarse en RAC, para usarse en un RAC solamente habra que modificar la sintaxsis de apagado incluyendo el instance name y el nodo

Exportando las tablas de auditoria

Hoy vamos a volver a las entradas rapidas para dummies.

Una de las tareas que podemos tener que hacer es el respaldar las tablas de auditoria para eliminarlas posteriormente. La primera opción que nos viene a la cabeza es hacer un export (expdp), pero si lo intentamos recibiremos el error:

ORA-39166: Object SYS.AUD$ was not found.
ORA-31655: no data or metadata objects selected for job

¿Que estamos haciendo mal?
Realmente no estamos haciendo nada mal , el problema es que el nuevo expdp no nos va a dejar exportar estas tablas (asi como objetos de los esquemas SYS,SYSTEM … )

¿Como los solucionamos ?

Con un CTAS ( create table as select)

Esta es la opcion mas extendida en los foros de soporte de oracle, los pasos serian

  • CREATE TABLE MIAUDIT AS SELECT * FROM SYS.AUD$
  • TRUNCATE SYS.AUD$
  • EXPDP xxxxx table=MIAUDIT
  • DROP TABLE MIAUDIT

¿Cual es el problema de esta opcion ?
Seguramente, si neceistamos exportar y truncar la tabla de auditoria es por que ya esta ocupando demasiado espacio, por lo que la opción de duplicar este espacio en la base de datos no siempre es viable.

Usar el export clasico

Cuando la opción del CTAS no es valida, nos queda siempre el uso del exp clásico.
La herraienta antigua de exportación no tiene estas limitaciones respecto a os objetos del sistema y si que nos permitira exportar los datos

Mas información como siempre en los foros de soporte de oracle o en la nota :

  • How to Export the AUD$ Table (Doc ID 745540.1)

Uptime de una base de datos Oracle

Hoy vamos a volver con una nueva entrada para muy dummies.

Como averiguamos hace cuanto tiempo esta la base de datos levantada?

Podemo usar alguna de estas consultas

select instance_name,
to_char(startup_time,'mm/dd/yyyy hh24:mi:ss') as startup_time 
from v$instance;

O si asumimos que es cuando arranco el pmon

SELECT database_name, 
TO_CHAR(logon_time, 'DD-MM-YYYY HH24:MI:SS') 
FROM v$session WHERE program LIKE '%PMON%';

O como siempre, podemos buscar que nos dicen en Burleson colsulting

select 
   'Hostname : ' || host_name
   ,'Instance Name : ' || instance_name
   ,'Started At : ' || to_char(startup_time,'DD-MON-YYYY HH24:MI:SS') stime
   ,'Uptime : ' || floor(sysdate - startup_time) || ' days(s) ' ||
   trunc( 24*((sysdate-startup_time) - 
   trunc(sysdate-startup_time))) || ' hour(s) ' ||
   mod(trunc(1440*((sysdate-startup_time) - 
   trunc(sysdate-startup_time))), 60) ||' minute(s) ' ||
   mod(trunc(86400*((sysdate-startup_time) - 
   trunc(sysdate-startup_time))), 60) ||' seconds' uptime
from 
   sys.v_$instance;