Oct 15, 2015

Caída de instancia en 11g ante un problema en escritura de archivo (_datafile_write_errors_crash_instance)


En oracle existe un parámetro oculto llamado _datafile_write_errors_crash_instance el cual permite la bajada automática de la base de datos ante algún problema en alguno de los datafiles o tempfiles. Esto Oracle lo creó para "garantizar" la consistencia de sus archivos ante alguna contingencia o problema con los file systems.  Desde oracle 11g en adelante este parámetro viene con el valor TRUE por defecto. En las versiones anteriores venia en FALSE.

Podría darse el caso de que no queremos que nuestra base de datos se venga abajo ante algún problema. Por ejemplo si tenemos un tempfile o datafile en autoextend ON  y si el disco o filesystem se encuentra al 100%, nuestra base de datos se encontrará con que no existe espacio suficiente para extender el archivo en cuestión y así de esa manera nuestra base de datos puede venirse abajo con en el ejemplo a continuación:

Thu Oct 15 16:26:01 2015
ORA-1652: unable to extend temp segment by 128 in tablespace                 TEMP
Thu Oct 15 16:28:37 2015
KCF: read, write or open error, block=0x198561 online=1
        file=1 '/u02/oradata/PROD/datafile/o1_mf_temp_9g2vcdbr_.tmp'
        error=27063 txt: 'IBM AIX RISC System/6000 Error: 28: No space left on device
Additional information: -1
Additional information: 131072'
Errors in file /u01/app/oracle/diag/rdbms/prod/PROD/trace/PROD_dbw1_12910650.trc:
Errors in file /u01/app/oracle/diag/rdbms/prod/PROD/trace/PROD_dbw1_12910650.trc:
ORA-63999: el archivo de datos ha sufrido un fallo del medio físico
ORA-01114: error de E/S al escribir el bloque en el archivo 201 (bloque número 1672545)
ORA-01110: archivo de datos 201: '/u02/oradata/PROD/datafile/o1_mf_temp_9g2vcdbr_.tmp'
ORA-27063: el número de bytes leídos/escritos es incorrecto
IBM AIX RISC System/6000 Error: 28: No space left on device
Additional information: -1
Additional information: 131072
DBW1 (ospid: 12910650): terminating the instance due to error 63999
Thu Oct 15 16:28:37 2015
System state dump requested by (instance=1, osid=12910650 (DBW1)), summary=[abnormal instance termination].
System State dumped to trace file /u01/app/oracle/diag/rdbms/prod/PROD/trace/PROD_diag_14811368.trc
Instance terminated by DBW1, pid = 12910650

Si alguien quiere evitar un comportamiento de este tipo se debe deshabitar ese parámetro oculto de la siguiente manera (además de eliminar el autoextend de los archivos):
ALTER SYSTEM SET "_datafile_write_errors_crash_instance" = FALSE SCOPE=BOTH;

El parámetro se puede modificar en caliente si es que se está trabajando con SPFILE.

Para más detalle se puede consultar la siguiente nota MOS:

Bug 7691270 - Crash the DB in case of write errors (rather than just offline files) (Doc ID 7691270.8)


Bug 7691270  Crash the DB in case of write errors (rather than just offline files)

 This note gives a brief overview of bug 7691270. 
 The content was last updated on: 15-JUL-2011
 Click here for details of each of the sections below.

Affects:

Product (Component)Oracle Server (Rdbms)
Range of versions believed to be affectedVersions BELOW 11.2.0.2
Versions confirmed as being affected
Platforms affectedGeneric (all / most platforms affected)

 The fix for this bug introduces a notable change in behaviour thus:
   Notable change of behaviour introduced in 11.2.0.2

Fixed:

This issue is fixed in

Symptoms:

Related To:

  • Recovery
  • _DATAFILE_WRITE_ERRORS_CRASH_INSTANCE

Description

This fix introduces a notable change in behaviour in that 
from 11.2.0.2 onwards an I/O write error to a datafile will
now crash the instance.

Before this fix I/O errors to datafiles not in the system tablespace 
offline the respective datafiles when the database is in archivelog mode. 
This behavior is not always desirable. Some customers would prefer 
that the instance crash due to a datafile write error.

This fix introduces a new hidden parameter to control if the instance
should crash on a write error or not:
  _datafile_write_errors_crash_instance 



With this fix:
 If _datafile_write_errors_crash_instance = TRUE (default) then
  any write to a datafile which fails due to an IO error causes 
  an instance crash. 

 If _datafile_write_errors_crash_instance = FALSE then the behaviour
  reverts to the previous behaviour (before this fix) such that
  a write error to a datafile offlines the file (provided the DB is
  in archivelog mode and the file is not in SYSTEM tablespace in 
  which case the instance is aborted)
 
Please note: The above is a summary description only. Actual symptoms can vary. Matching to any symptoms here does not confirm that you are encountering this problem. For questions about this bug please consult Oracle Support.

References

Bug:7691270 (This link will only work for PUBLISHED bugs)
Note:245840.1 Information on the sections in this article

Espero que sea de utilidad.
Saludos, Felipon.

Jun 2, 2015

¿Problemas con el workflow notification service de E-business Suite de Oracle?

¿Problemas con el workflow notification service de E-business Suite de Oracle?

Quizás alguien más ya haya tenido alguna dificultad con este componente de la plataforma de E-business de Oracle. Bueno si alguien ya ha tenido algún problema les comento un tips para encontrar rápidamente  cual puede ser la causa del inconveniente.

Será necesario primero averiguar en que status se encuentra el workflow con la siguiente consulta que debe ser ejecutada en la base de datos que utiliza el E-business:

set pagesize 999
set lines 400
col component_name format a70
select component_name,upper(component_status) as component_status from apps.fnd_svc_components --where component_name = 'Workflow Notification Mailer'
La anterior consulta muestra cual es el status de los servicios, si alguno de ellos tiene algún problema puede ser revisado en el archivo log que entrega la siguiente consulta (este archivo se debe encontrar en el servidor aplicativo del e-business suite)
SELECT fcp.logfile_name
FROM apps.fnd_concurrent_queues fcq, apps.fnd_concurrent_processes fcp, apps.fnd_lookups flkup
WHERE concurrent_queue_name in ('WFMLRSVC')
AND fcq.concurrent_queue_id = fcp.concurrent_queue_id
AND fcq.application_id = fcp.queue_application_id
AND flkup.lookup_code=fcp.process_status_code
AND lookup_type ='CP_PROCESS_STATUS_CODE'AND meaning='Active';

Este archivo contiene información importante de todo el comportamiento del workflow de la plataforma.

Como tips adicional adjunto la consulta con la cual el componente afectado puede ser levantado:

-- aqui definimos el nombre del esquema de E-business deberia ser APPS
alter session set current_schema=apps;
 declare
      p_retcode number;
      p_errbuf varchar2(100);
      m_mailerid apps.fnd_svc_components.component_id%TYPE;
 begin
      select component_id
        into m_mailerid
        from apps.fnd_svc_components
-- aqui va el nombre del componente tal cual como aparece en la primera imágen
-- se trata de los nombres que se observan en la columna COMPONENT_NAME
       where component_name = 'NOMBRE_DEL_COMPONENTE_AFECTADO';
      apps.fnd_svc_component.start_component(m_mailerid, p_retcode, p_errbuf);
      commit;
 end;
/
exit;

Aquí un segundo tips para reiniciar el workflow pero esta vez con salida por pantalla de posibles errores:
set serveroutput on size 1000000
declare
n_component_id number;
v_component_status varchar2(40);
l_errcode number;
l_errstr varchar2(4000);
v_time varchar2(60);
begin
select component_id,component_status into n_component_id,v_component_status from fnd_svc_components
where component_name='Workflow Notification Mailer';
dbms_output.put_line(n_component_id||' '||v_component_status);
select to_char(sysdate,'DD-MON-YYYY HH24:MI:SS') into v_time from dual;
dbms_output.put_line(v_time);
dbms_output.put_line('Stopping Notification Mailer');
FND_SVC_COMPONENT.stop_Component(n_Component_Id, l_errcode, l_errstr);
commit;
dbms_output.put_line(n_component_id||' '||l_errcode||l_errstr);
dbms_lock.sleep(90);
dbms_output.put_line(n_component_id||' '||v_component_status);
select to_char(sysdate,'DD-MON-YYYY HH24:MI:SS') into v_time from dual;
dbms_output.put_line(v_time);
dbms_output.put_line('Starting Notification Mailer');
FND_SVC_COMPONENT.start_Component(n_Component_Id, l_errcode, l_errstr);
commit;
dbms_output.put_line(n_component_id||' '||l_errcode||l_errstr);
dbms_lock.sleep(65);
dbms_output.put_line(n_component_id||' '||v_component_status);
select to_char(sysdate,'DD-MON-YYYY HH24:MI:SS') into v_time from dual;
dbms_output.put_line(v_time);
end;
/

Espero haya sido de utilidad estos scripts.


Feb 18, 2015

Cómo configurar DBLink de Oracle Hacia SQLServer y evitar típicos errores tal como: ORA-28545: error diagnosed by Net8 when connecting to an agent

Cómo configurar DBLink de Oracle Hacia SQLServer y evitar típicos errores tal como: ORA-28545: error diagnosed by Net8 when connecting to an agent
Quizás a muchos les ha sucedido que les aparece el error  ORA-28545: error diagnosed by Net8 when connecting to an agent, cuando consultan una tabla desde Oracle hacia un dblink en sqlserver, luego de haberlo configurado después de muchas batallas.
Ese error se produce por tres cosas:
1.- Mal configuración del DNS u ODBC. Es decir se definió mal el nombre, servidor o ip del servidor sql de destino.
2.- Se está ocupando un driver ODBC DNS de 32 Bits para conectarse desde un servidor Oracle 64 bits hacia el dblink sqlserver. Lamentablemente no tengo el link Oracle en este minuto en donde comentan que para conectarse desde un motor oracle 64 bits se necesitan los drivers ODBC para sqlserver de 64 Bits, yo en lo personal he probado con uno de 32 Bits y me dio problemas.
3.- La configuración de los archivos init[ODBC_NAME].ora, tnsnames o listener.ora tienen problemas de configuración
Para evitar tales problemas revisemos cómo se realiza correctamente la configuración de un dblink desde oracle hacia sqlserver. En este ejemplo he utilizado Oracle 11gR2 sobre windows 2008 R2 y como destino SQL Server 2012.
Como  primer paso debemos configurar el ODBC hacia el ambiente sqlserver que deseamos, no detallare esto pues muchos han realizado este paso y para no retrasar más esto, les pongo el ejemplo del ODBC que he creado, le puse por nombre hsodbc, el cual se conecta a una base de datos sqlserver en un servidor llamado TEST, la base de datos sqlserver a la cual nos conectaremos lleva por nombre también hsodbc:


Esto es importante: este alias en la fotografía anterior llamado hsodbc debe ser del tipo System DNS, no User DNS. Además es importante utilizar un driver ODBC adecuado para los ambientes. Como me estoy conectando desde un ambiente Oracle de 64 bits hacia un ambiente sql también de 64 Bits deben instalar los drivers de 64 Bits del ODBC para sqlserver. Estos pueden ser descargados desde la siguiente página:: https://www.microsoft.com/en-us/download/confirmation.aspx?id=36434
(recordar solo bajar los de 64 Bits) luego de instalarlo podrán ver que aparecerá un nuevo registro en la pestaña drivers. Al crear el alias deben usar este driver instalado:


Bueno luego que ya han configurado el driver ODBC es necesario que ingresen a la carpeta %ORACLE_HOME%\hs\admin (Oracle_home) en dicha carpeta deberian ver los siguientes archivos:
De estos archivos copiaran el primero de ellos el archivo initdg4odbc.ora y le pondrán por nombre: inithsodbc.ora. Este archivo con extensión *.ora  es el archivo de configuración para conectarse al ODBC creado anteriormente y debe llevar por nombre init[NOMBRE_ODBC_CREADO].ora es decir inithsodbc.ora
Este archivo debería contener las siguientes líneas (puede contener muchas más pero para este ejemplo sólo bastará lo siguiente):
HS_FDS_CONNECT_INFO = hsodbc
HS_FDS_TRACE_LEVEL = 0


El parámetro HS_FDS_CONNECT_INFO llevará como valor el ODBC creado anteriormente: Ejemplo;




Como se podrán dar cuenta hasta aquí con esta configuración estaremos usando una excelente tecnología de Oracle llamada Heterogeneous Agent  el cual es parte del software Oracle Database Gateway for ODBC (en realidad ese era el nombre que tenia antes esta herramienta Heterogeneus Agent ahora llamada asi a secas Database Gateway). De hecho si ejecutan el binario dg4odbc podrán ver la versión del gateway instalada en vuestro servidor:


Bueno realizado esto sobre el archivo init nuestro, nos queda configurar el listener.ora y tnsnames.ora. Para esto bueno nos vamos a la carpeta ORACLE_HOME/network/admin y antes de editar esos archivos sugiero respaldarlos. Ojo que dentro de la carpeta ORACLE_HOME\hs\admin existen ya unos archivos ejemplo para tnsnames y listener que pueden utilizar. Eso se los doy como un tips.


Partamos por la configuración del listener.ora Para ese archivo debemos agregar las siguientes líneas al registro SID_LIST_LISTENER nuestro configurado (si desean incluso pueden generar un nuevo listener como ustedes deseen):
  (SID_DESC=
        (SID_NAME=hsodbc)
        (ORACLE_HOME = D:\oracle\product\11.2.0\dbhome_1)
        (PROGRAM=dg4odbc)
      )
Es muy importante utilizar el PROGRAM=dg4odbc siempre debe estar con ese valor independiente del nombre ODBC que ocupemos, si en este ejemplo usamos un valor tal como: PROGRAM=hsodbc al momento de invocar el dblink desde el ambiente Oracle aparecerá el error: ORA-28545: error diagnosed by Net8 when connecting to an agent. Así que no olvidar aquello.  Esto es porque en las versiones 10g o más antiguas se ocupaba el hsodbc, pero para este caso que es un oracle 11g debemos usar dg4odbc.
Para que no queden dudas Heteregoneous Services es un producto que fue reemplazado en 11g por Database Gateway, en este caso la versión de DG que estamos ocupando no requiere pago de licencia adicional, ver la nota Oracle Support ID 232482.1 en dónde explican y detallan esto.
Bueno aclarando lo anterior y siguiendo con nuestra configuración lo anterior es la única configuración que he hecho pues ese nuevo nombre de servicio lo sacaré por el mismo  listener con el cual contaba anteriormente.


Ahora es necesario configurar el tnsnames.ora agregando un nuevo registro como el siguiente:
hsodbc =
 (DESCRIPTION=
   (ADDRESS=(PROTOCOL=tcp)(HOST=localhost)(PORT=1532))
   (CONNECT_DATA=(SID=hsodbc))
   (HS=OK)
 )


En el PORT usamos bueno el puerto del listener actual. El SID debemos usar el nombre del init creado o del ODBC creado en un comienzo. Lo que no debe olvidarse es usar el (HS=OK) Si no esto no nos funcionará. De ahi el nombre de dicha keyword HS -> Heterogeneous Services.


Bueno a continuación les dejo como ejemplo mis dos archivos listener.ora y tnsnames.ora configurados:
# listener.ora Network Configuration File: D:\oracle\product\11.2.0\dbhome_1\NETWORK\ADMIN\listener.ora
# Generated by Oracle configuration tools.


listener.ora
SID_LIST_LISTENER =
 (SID_LIST =
   (SID_DESC =
     (GLOBAL_DBNAME = test1)
     (ORACLE_HOME = D:\oracle\product\11.2.0\dbhome_1)
     (SID_NAME = test1)
   )
   (SID_DESC =
     (PROGRAM = extproc)
     (SID_NAME = CLRExtProc)
     (ORACLE_HOME = D:\oracle\product\11.2.0\dbhome_1)
   )
   (SID_DESC=
        (SID_NAME=hsodbc)
        (ORACLE_HOME = D:\oracle\product\11.2.0\dbhome_1)
        (PROGRAM=dg4odbc)
      )
 )


LISTENER =
 (DESCRIPTION =
   (ADDRESS = (PROTOCOL = TCP)(HOST =localhost)(PORT = 1532))
 )


ADR_BASE_LISTENER = D:\oracle


TNSNAMES.ORA
hsodbc =
 (DESCRIPTION=
   (ADDRESS=(PROTOCOL=tcp)(HOST=localhost)(PORT=1532))
   (CONNECT_DATA=(SID=hsodbc))
   (HS=OK)
 )


Luego de configurado estos dos archivos deben recargar la configuración del listener con el comando lsnrctl reload y si gustan pueden hacer alguna prueba con el comando tnsping hsodbc 3 el cual no debería darles problemas:


Y bueno ya hecho eso sólo nos queda configurar el dblink desde el ambiente SQLSERVER:


SQL> create database link "TEST" connect to "USUARIO" identified by "PASSWORD" using 'hsodbc';


Database link created.


De lo anterior TEST es el nombre del dblink, USUARIO y PASSWORD son los datos de conexión hacia el ambiente sqlserver. No olividar que el usuario y password DEBEN ir en comillas dobles sino tendrán el error ORA-28545. Por último dentro del comando using debemos poner el nombre de nuestro ODBC configurado.


Luego de esto deberíamos estar en condiciones de probar nuestro dblink el cual no debería dar problemas: En este ejemplo consultaré una tabla que tengo en mi servidor sqlserver llamada tabla_test:


SQL> select * from tabla_test@TEST;


CAMPO_XXXX  CAMPO_YYYY
---------- --------------------------------------------------
1111111111 Oracle
2222222222 SQL Server


SQL>


y sería absolutamente todo. Eso es todo lo que deben configurar nada más. Por lo menos para lo básico. Espero que haya sido algo de utilidad este tutorial cualquier consulta me la pueden enviar a felipe@felipedonoso.cl o dba@felipedonoso.cl


PD:  Este tutorial nación de un problema que tuve al crear un dblink en un cliente. A pesar que había configurado bastantes veces este dblink me estaba topando con un problema que no podía resolver, obtenía el error: ORA-28545: error diagnosed by Net8 when connecting to an agent y no podía arreglarlo. Finalmente la causa de todo este problema radicaba en que en el registro del listener.ora estaba usando (PROGRAM=hsodbc) en vez de usar el correcto (PROGRAM=dg4odbc). Recuerden que estamos haciendo la prueba para un Oracle11g si fuese 10g o más antiguo se debe ocupar (PROGRAM=hsodbc). Es lo que les comentaba anteriormente, por simples detalles pueden perder bastante tiempo, cuando lo arreglé me sentí asi de glorioso y victorioso:



Saludos :p que estén bien.