sábado, 12 de noviembre de 2011

ORA-28056: Writing audit records to Windows Event Log failed

Si se te presenta este error de oracle "ORA-28056: Writing audit records to Windows Event Log failed" es un problema relacionado al tratar de escribir en el log de eventos de windows.

ORA-28056: Writing audit records to Windows Event Log failed

Este error lo puedes solventar limpiando el log de errores de windows desde la consola administrativa que se encuentra en Herramientas Administrativas / Visor de suscesos o ejecutar el comando eventvwr.msc /s

Luego deberas borrar el log de Sistema y de Aplicación.

lunes, 7 de noviembre de 2011

¿Por qué migrar a BD Oracle 11G?


Como es de esperarse cada nueva versión de Oracle tiene muchas ventajas a la versión anterior, estas mejoras en su mayoría corresponde a mejoras en su núcleo, Administración y seguridades, estas mejoras contribuyen con herramientas, funcionalidades y utilidades para los DBA para mejorar y controlar la administración de nuestras base de datos.
Como mencioné hace un momento "En su mayoría corresponden a mejoras en su núcleo, administración y seguridades" pero esta nueva versión también beneficia a los desarrolladores.

Ahora mencionaré alguna de las nuevas características que tiene la 11g.

Browser-Based Enterprise Manager Integrated Interface for LogMiner
Es una gran utilidad implementada en 11g, que nos permite buscar dentro de los logs (Online y Archive redo log) las transacciones DML o DDL ejecutadas.

Es una buena utilidad que puede ser usada de manera gráfica o con el paquete DBMS_LOGMNR. El LogMiner Viewer forma parte del Enterprise Manager que viene en el Software Oracle Client.

Como les dije, es una excelente utilidad que nos permitirá examinar los Online/Archive redo log que es el repositorio de todos los DML y DDL ejecutados. Con esto podríamos realizar una mejor investigación para: Auditorias post-transaccion, Detectar y revisar los errores de usuarios.

DDL_LOCK_TIMEOUT
Cuando se trata de alterar una tabla esto requiere de un bloqueo exclusivo del objeto para que ninguna otra sesión trate de trabajar con la tabla que estamos modificando. ¿Pero qué pasa si intentamos alterar una tabla que está siendo bloqueada por otra sesión de usuario y no ha confirmado o desecho la transacción DML? La respuesta es simple "ORA-00054: recurso ocupado y obtenido con NOWAIT especificado", esto es lógico por que no nos dejará realizar modificaciones a la estructura si hay otras transacciones, pero el problema es que puede ser que la transacción que genera el bloque solo demore un segundo o 5 segundo, y durante ese lapso simpre nos retornara el error.

Para evitar esto, podemos configurar el DDL_LOCK_TIMEOUT a un tiempo prudente que nuestro DDL deberá esperar para poder realizar el cambio sin que nos retorne el error "ORA-00054: recurso ocupado y obtenido con NOWAIT especificado". Esto quiere decir que si tratamos de alterar la tabla y está bloqueada por otra sesión esta se espera el tiempo configurado hasta poder alterarla.
ALTER SYSTEM SET DDL_LOCK_TIMEOUT=60 SCOPE=BOTH;

En mi caso lo tengo configurado con 60 (en segundos), es decir que mi sesión esperará hasta 60 segundo para poder altera la tabla antes de que mande el error.

Índices invisibles
Con esto puedes definir que índices están o no visibles para el CBO (Optimizador Basado en Costos), con esto quiero decir que el índice sigue en constante actualización si ocurren transacciones DML sobre la tabla, pero este índice no es considerado para realizar análisis de costos al momento de realizar el plan de ejecución.

Cual es el objetivo? El objetivo es ver el rendimiento del nuevo índice con respecto a los anteriores planes de ejecución, pero no queremos que el índice entre en producción (Con esto quiero decir que no sea tomado en cuenta por el CBO).

Creación de índice invisible
CREATE INDEX Indice_01 ON MI_TABLA(CAMPO_1) INVISIBLE;

Como hacer un índice invisible a visible:
ALTER INDEX Indice_o1 VISIBLE;

Como hacer para que en nuestra sesión se consideren índice invisible en un plan de ejecución:
ALTER SESSION SET optimizer_use_invisible_indexes=TRUE;

Tablas de solo lectura (Read Only Tables)
Como su nombre lo dice, esto nos permite cambiar a modo solo lectura las tablas que deseamos (Algo así lo logramos iniciando la base de datos como solo lectura o cambiando el modo del tablespace a solo lectura)

Cambiar a solo lectura la tabla
ALTER TABLE Nombre_Tabla READ ONLY;

Cambiar a modulo lectura y escritura
ALTER TABLE Nombre_Tabla READ WRITE;

Dependencia de objetos más finas (Finer Grained Dependencies)
En versiones anteriores la 11g cuando se realizan cambios a la metadata los objetos que tienen dependencia, estos objetos dependientes son invalidados. Supongamos que tenemos la tabla Persona con el campo Nombre y Apellido, luego creamos una vista V_Persona con los campos nombre y apellido solamente, ahora si realizamos un cambio a la tabla Persona agregándole el campo edad esto causa que la vista V_Persona sea invalidad, pero si revisamos la composición de la vista esta solo tiene los campos Nombre y Apellido. Ya en 11g esto no ocurre, ya que la relación es mas fina, es decir no incluye todo el objeto, si no los campos que involucran la relación.

Mejoras al agregar columnas (Enhanced ADD COLUMN Functionality)
Todos sabemos que es un dolor de cabezas agregar un valor default a un campo y sobre todo si esta tabla tiene millones y millones de registros ya que el valor por default deberá actualizarse en todos los registros causando un problema de rendimiento.

Para evitar estos maltrechos incidentes, en la versión 11g los valores por default para campos NOT NULL se almacenaran en la metadata y no en la fila del dato. Esto mejora el rendimiento al momento de alterar el campo de una tabla indicándole el valor por defecto y no ocupará espacio en disco.

Compresión de archivos DUMP.
Ahora podemos generar archivos DUMP de metadata o datos con una compresión del 10 al 15% del lo que originalmente se generaba. Tu puedes indicar que es lo que deseas comprimir: Metadata, Datos o Ambos.

Encriptación de los archivos DUMP
Para mayor seguridad, ahora podemos generar archivos DUMP con encriptación de datos, metadatos o ambos. Esto viene incluido en esta versión 11g.

SQL PIVOT.
En esta versión 11g podremos pivotear el resultado de una consulta sobre un campo específico.

Supongamos que deseamos obtener las ventas del 09-2011 al 12-2011 para todos los clientes, pero los totales mensuales los queremos por columnas. Lo que tendríamos que hacer es utilizar combinación de SUM y DECODE / CASE WHEN para obtener los totales por mes.
SELECT CLIENTE,
SUM(case when FECHA BETWEEN TO_DATE('01-10-2011') and TO_DATE('31-10-2011') then VALOR_VENTA else 0 end) OCT,
SUM(case when FECHA BETWEEN TO_DATE('01-11-2011') and TO_DATE('30-11-2011') then VALOR_VENTA else 0 end) NOV,
SUM(case when FECHA BETWEEN TO_DATE('01-12-2011') and TO_DATE('31-12-2011') then VALOR_VENTA else 0 end) DIC
FROM VENTAS
GROUP BY CLIENTE

En 11g es mas sencillo realizar esto:
SELECT *
FROM
(    
    SELECT TO_CHAR(FECHA,'MON')MES,VALOR_VENTA
    FROM Ventas
    WHERE FECHA BETWEEN TO_DATE('01-10-2011') and TO_DATE('31-12-2011')
)
PIVOT (SUM(VALOR_VENTA) FOR MES)

Columnas Virtuales
Columnas virtuales, son columnas que depende de una expresión o formula, es decir son campos calculados con otros campos, estos datos pueden quedar solo en la definición de la metadata y no en el espacio de datos de la tabla. Imagine que tenemos la tabla Empleados don tenemos el campos Salario y Bono, el ingreso total es la suma de Salario y Bono, esto quedaría definido así:
CREATE TABLE Empleados(
identificacion     VARCHAR2(15),
nombre        VARCHAR2(30),
apellido        VARCHAR2(30),
salario        NUMBER(9,2),
bono            NUMBER(9,2),
ingreso_total AS (salario + bono)
)

Como vemos la definición de una columna virtual es sencilla, solo hay que tener en cuenta que una columna virtual tiene sus restricciones:
 Una columna virtual no puede se compuesta por otra columna virtual.
Los campos de la columna virtual deben de pertenecer a la tabla.

Asignación a una variable del nextval de una secuencia sin usar el método select into from dual
Esto nos quita la tediosa tarea de asignar a una variable el nextval de una sequencia, ahora podemos asignar directamente a una variable

Declare
  nValor number(5);
Begin
 nValor:=secuencia_empleado.nextval.nexval;
End;