jueves, 13 de agosto de 2009

Eliminar registros duplicados

Si por algún motivo insertaron registros duplicados de una tabla, ya sea porque han eliminado la clave primaria o ni siquiera la han creado y ahora la consideran necesaria; por aquí les dejo una sentencia que los puede ayudar a eliminar esos registros innecesarios:

delete from tabla
where rowid not in
(select min(rowid)
from tabla
group by (col_pk1, col_pk2, col_pk3...);


Donde tabla indica la tabla en cuestión y las col_pkn son las columnas que forman la primary key.

miércoles, 12 de agosto de 2009

Inicio automático Oracle en Linux

En este post "intentaré" explicar cómo configurar el inicio automático de Oracle 10 en un S.O. Linux (Red Hat en mi caso particular).

Luego de instalado Oracle, debemos editar el archivo /etc/oratab, donde dice algo similar a:

$ORACLE_SID:$ORACLE_HOME:N

Cambiamos la "N" por "Y" -- o sea le decimos que sí! :) --

Quedaría:

$ORACLE_SID:$ORACLE_HOME:Y

En mi caso particular quedó:

orcl10:/u01/app/oracle/product/10.2.0/db_1:Y

Luego creamos el archivo /etc/init.d/dbora con el usuario root, con el siguiente contenido:
(espero que haya quedado bien el copy & paste!)

#!/bin/bash
#
# chkconfig: 35 99 10
# description: Starts and stops Oracle processes
#
# Set ORA_HOME to be equivalent to the $ORACLE_HOME
# from which you wish to execute dbstart and dbshut;
#
# Set ORA_OWNER to the user id of the owner of the
# Oracle database in ORA_HOME.
#
ORA_HOME=/u01/app/oracle/product/10.2.0/db_1ORA_OWNER=oracle
case "$1" in
'start')
su - $ORA_OWNER -c "$ORA_HOME/bin/lsnrctl start"

if [ -f $ORA_HOME/bin/oemctl ]; then
su - $ORA_OWNER -c "$ORA_HOME/bin/emctl start dbconsole"
fi

su - $ORA_OWNER -c $ORA_HOME/bin/dbstart

# Start the Intelligent Agent
#if [ -f $ORA_HOME/bin/agentctl ]; then
# su - $ORA_OWNER -c "$ORA_HOME/bin/agentctl start"
#else
# su - $ORA_OWNER -c "$ORA_HOME/bin/lsnrctl dbsnmp_start"
#fi
# Start Enterprise Management Console
#if [ -f $ORA_HOME/bin/oemctl ]; then
# su - $ORA_OWNER -c "$ORA_HOME/bin/emctl start dbconsole"
#fi
# Start HTTP Server
#if [ -f $ORA_HOME/Apache/Apache/bin/apachectl ]; then
# su - $ORA_OWNER -c "$ORA_HOME/Apache/Apache/bin/apachectl start"
#fi
touch /var/lock/subsys/dbora
;;
'stop')
# Stop HTTP Server
#if [ -f $ORA_HOME/Apache/Apache/bin/apachectl ]; then
# su - $ORA_OWNER -c "$ORA_HOME/Apache/Apache/bin/apachectl stop"
#fi
# Stop Enterprise Management Console
if [ -f $ORA_HOME/bin/oemctl ]; then
su - $ORA_OWNER -c "$ORA_HOME/bin/emctl stop dbconsole"
fi
# Stop the Intelligent Agent
#if [ -f $ORA_HOME/bin/agentctl ]; then
# su - $ORA_OWNER -c "$ORA_HOME/bin/agentctl stop"
#else
# su - $ORA_OWNER -c "$ORA_HOME/bin/lsnrctl dbsnmp_stop"
#fi
# Stop the TNS Listener su - $ORA_OWNER -c "$ORA_HOME/bin/lsnrctl stop"
# Stop the Oracle databases:
# The following command assumes that the oracle login
# will not prompt the user for any values
su - $ORA_OWNER -c $ORA_HOME/bin/dbshut
rm -f /var/lock/subsys/dbora
;;
esac

# End of script dbora

A continuación (seguimos con root) seteamos los privilegios sobre el archivo dbora:

chmod 750 /etc/init.d/dbora

Y asociamos al servicio con los runlevels apropiados:

chkconfig --level 345 dbora on

La instancia ahora debería iniciarse automáticamente al reinicio de nuestro servidor Oracle. Hay un bug conocido que nos puede complicar al reinicio, pero no preocuparse, porque por suerte "es conocido" y tiene solución!

Si nos encontramos con este error:

Failed to auto-start Oracle Net Listener
using /ade/vikrkuma_new/bin/tnslsnr

Se debe a un path hard-coded en el script dbstart. Para solucionarlo editamos el archivo $ORACLE_HOME/bin/dbstart y reemplazamos la siguiente línea (línea 78 aprox.):

ORACLE_HOME_LISTENER=/ade/vikrkuma_new/oracle

Con ésto:

ORACLE_HOME_LISTENER=$ORACLE_HOME

Ahora sí, con esta modificación el listener debería iniciar automáticamente sin problema alguno.

Espero que este post les sea de utilidad!

lunes, 10 de agosto de 2009

Habilitar ARCHIVELOG

La mayoría de las características de Alta Disponibilidad de Oracle requieren el modo ARCHIVELOG activado. Una vez habilitada esta característica, los archivos redo logs, serán guardados antes de ser sobreescritos.

Habilitar ARCHIVELOG a partir de la versión 10, resulta más sencillo que en versiones anteriores, debido a que no debemos especificar siquiera parámetro de inicio en el spfile (como el "LOG_ARCHIVE_START=true" en la versión 9).

Como chequeamos si está habilitado el modo ARCHIVELOG?

SQL> archive log list;
Database log mode No Archive Mode
Automatica archival Disabled
Archive destination USE_DB_RECOVERY_FILE_DES
Oldest online log sequence 42541
Current log sequence 42543

El "No Archive Mode" evidentemente nos indica que esta base no esta guardando los online archive logs, es decir, no está en modo ARCHIVELOG.

Cómo hacemos para habilitarlo?

sqlplus sys/pass as sysdba -- nos conectamos a la consola de SQLPlus --
SQL> shutdown immediate; -- si la BD está levantada, la bajamos; de lo contrario obviamos este paso --
SQL> startup mount; -- montamos la BD --
SQL> alter database archivelog; -- activamos ARCHIVELOG --
SQL> alter database open; -- levantamos la BD --

Nuestra BD finalmente quedó en modo ARCHIVELOG!

Los archivos generados por el archivado de logs, por default, quedarán ubicados en la FRA (Flash Recovery Area).

Esta sentencia nos indicará la ubicación de los archive logs y el tamaño asignado para esta área:
select * from v$parameter where name in ('db_recovery_file_dest','db_recovery_file_dest_size');

Hasta aquí este artículo sobre ARCHIVELOG!

martes, 4 de agosto de 2009

ORA-12518

Cuando me encontré con este ORA error, que rezaba un lindo mensaje "TNS:listener could not hand off client connection", me quería volver loco!!! No sabía por donde empezar...

Las características del Server con el que estaba piloteando eran:
Intel Quad Core
4Gb RAM
Windows 2003 (32 bits)
Oracle 10.2.0.3
SGA >1.6Gb
320Mb PGA
...

Googleando en la vuelta, no encontré nada preciso que me ayudara rápidamente a solucionar el error, hasta que en metalink (metalink.oracle.com) hallé el DOC ID 556428.1 que me dió algunas sugerencias interesantes.

Un primer intento, aumentar el nro. de processes, pero los resultados no fueron los esperados; en realidad tampoco esperaba que diera resultado, pero... en fin... fue un intento no más!
Luego, viendo que la memoria que tenía asignada la SGA+PGA estaban "CASI" en los 2Gb y que mi S.O. era de 32 bits... Ups! se supone que un sistema de 32bits. no puede redireccionar más de 2Gb a un solo proceso, y yo estaba caminando por la corniza... máxime que ese día la carga de usuarios en el sistema se veía algo incrementada comparada con los demás días. Ahí lo que me quedaba era disminuir la memoria asignada a la SGA o probar con el parámetro /3GB en el boot.ini; ésto último fue lo que terminé configurando y por suerte salimos a flote.

Configurando el parámetro /3GB logramos que un sistema Win 32 bits redireccione arriba de los 2Gb de memoria por proceso.

Cómo setear este parámetro?

Contenido archivo boot.ini

[boot loader]
timeout=30
default=multi(0)disk(0)rdisk(0)partition(1)\WINDOWS
[operating systems]
multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Windows Server 2003, Standard" /3Gb /fastdetect /NoExecute=OptOut