ORA-02020: too many database links in use

Hoy vamos a ver otra de esas entradas sencillas que nos pueden ahorra mucho tiempo.

Uno de los errores que podemos encontrarnos cuando trabajamos con DBlinks es

ORA-02020: too many database links in use

Esto puede ser facilmente solucionable con los parámetros del init.ora

open_links=500
open_links_per_instance=500

Como siempre, la informacion la tenemos en oracle :

Parámetro compatible en las bases de datos

Hoy vamos a ver uno de los parámetros mas sencillos que hay pero que puede provocarnos algún que otro quebradero de cabeza. El parámetro «compatible»

Uno de los parámetros del init.ora de nuestras bases de datos es el de la compatibilidad.
Este parámetro afecta al funcionamiento interno de la base de datos afectando no solamente al modo de trabajo del optimizador sino también pudiendo afectar a la manera en la que Oracle maneja físicamente algunas estructuras de datos.

¿Cual es la principal consecuencia de esto?
Que NO es posible la vuelta atrás.
Desde Oracle 9i , la versión de base de datos está compuesta por 5 dígitos cuyo significado es:
Opciones del número

En nuestro afán de tener la base de datos al último nivel de funcionalidad podemos tender a subir siempre el nivel de compatibilidad al máximo.
Esta costumbre no solo la desaconsejamos aquí, sino que es una de los advices que dan desde Oracle «Use only the first 3 digits for the compatible parameter unless there would be some very specific instructions to do otherwise.».

La razón es que, como comentábamos al principio, el parámetro compatible no es algo que pueda deshacerse ya que afecta a la estructura física de la base de datos con lo que, en caso de tener que hacer marcha atrás hacia una versión compatible inferior deberá de hacerse un downgrade completo de la base de datos.

Para mas información, como siempre en soporte de Oracle:

  • About Oracle Database Release Numbers
  • Note 733987.1 How To Change The COMPATIBLE Parameter And What Is The Significance? (Doc ID 733987.1)
  • Note 1563364.1 What is the Relationship between the COMPATIBLE Initialization Parameter and the Optimizer (Doc ID 1563364.1)
  • Note 1458741.1 COMPATIBLE Parameter – Explanation, Usage and Advise (Doc ID 1458741.1)

El equivalente a CONSISTENT=Y con expdp

Hoy vamos a ver otra de esas entradas sumamente sencillas que nos ahorrarán un montón de tiempo.

Si intentamos hacer un exdp de una base de datos grande que hace un uso muy intensivo de secuencias, podemos encontrarnos problemas a la hora de la importación con las claves ajenas, esto es debido a que el export que hemos llevado a cabo no es consistente.

En la versión antigua del export (exp) teníamos una opción llamda CONSISTENT=Y que nos permitía congelar la base de datos en el momento del export de manera que, la exportacion de nuestra base de datos era totalmente consistente. Sin embargo, la nueva funcionalidad expdp no lo tiene ¿hemos dado un paso atrás?

Afortunadamente, la respuesta es no, lo único que pasa, es que (como siempre) Oracle nos ha puesto algo mas dificil acertar con el nombre.

Lo que haremos con el expdp será el hacer un expdp con la opción FLASHBACK_TIME ó FLASHBACK_SCN

La nueva sintaxsis será :

  • Para hacer un export en el momento 15-05-2014 a las 21:00
    expdp user/pass ... FLASHBACK_TIME="TO_TIMESTAMP('15-05-2014 21:00:00', 'DD-MM-YYYY HH24:MI:SS')" ...
    
  • Para hacer un export en el momento que lo lanzas
    expdp user/pass ... FLASHBACK_TIME=systimestamp  ...
    
  • O bien, para lanzar un export en un determinado SCN
    expdp user/pass ... FLASHBACK_SCN=7782903
    

Hay que tener en cuenta dos cosas cuando lanzamos un expdp con FLASHBACK

  • Las dos opciones TIME y SCN son excluyentes: No se pueden poner las dos claúsulas en el mismo script de export
  • Es necesario contar con un UNDO suficiente para albergar los datos durante todo el export: Lo que estamos haciendo con esto, es mantener la base de datos congelada en ese punto, si el export dura 7 horas, deberemos de contar con un UNDO capaz de mantener todos los datos que se llevan a cabo durante estas 7 horas, de lo contrario ,el export fallará con el error típico de UNDO insuficiente

Como siempre, la información completa en la Documentación de oracle

Rotar el listener sin pararlo

Hoy vamos a ver una entrada de dummy pero de mucha utilidad.

Habitualmente, el log del listener crece de manera descontrolada y solemos tener problemas a la hora de borrarlo. No podemos detener el listener,por que cortaríamos el servicio, y tampoco podemos borrar el fichero del log por que está en uso.
¿Que hacemos entonces?

La solución es bien sencilla, simplemente dejamos de logar, vaciamos y volveos a logar.
Lo primero que hemos de hacer es conectarnos desde linea de comandos al listener, lo que vamos ha hacer es:

  • Comprobar si estamos logando
  • Mirar cual es el log
  • Mirar cual es el directorio de trazas

La salida de los comandos será:

oracle@server : lsnrctl
LSNRCTL> show log_status
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC_FOR_XE)))
LISTENER parameter "log_status" set to ON
The command completed successfully
LSNRCTL> show log_file
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC_FOR_XE)))
LISTENER parameter "log_file" set to /u01/app/oracle/diag/tnslsnr/server/listener/alert/log.xml
The command completed successfully
LSNRCTL> show trc_directory
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC_FOR_XE)))
LISTENER parameter "trc_directory" set to /u01/app/oracle/diag/tnslsnr/server/listener/trace
The command completed successfully
LSNRCTL> set log_status off

En otra ventana, iremos al directorio de tazas y borraremos o moveremos las trazas que nos molestan
Una vez eliminados, solamente hemos de volver a activar el log

LSNRCTL> set log_status on;
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC_FOR_XE)))
LISTENER parameter "log_status" set to ON
The command completed successfully
LSNRCTL> show log_status
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC_FOR_XE)))
LISTENER parameter "log_status" set to ON
The command completed successfully
LSNRCTL>

Mover tablas con subparticiones

Supongamos que tenemos una tabla llamada AGENTE , esta tabla agente está particionada por número de agente, y a su vez, particionada por trimestre.
Así pues tendremos que la estructura es mas o menos
PARTICIONADO

Y queremos mover estas particiones a un nuevo tablespace (TS_NEW). Lo primero que se nos pasa por la cabeza es el ejecutar:

alter table PROPIETARIO.AGENTE move partition  AG1  tablespace TS_NEW;

Pero Oracle nos devolverá el error

Error at line 1
ORA-14257: no se puede mover una partición que no sea de Rango, Lista, Sistema o Hash

Lo primero que nos viene a la cabeza es el preguntarnos donde está el error e ir a comprobar que tipo de partición tenemos, sin embargo, si aplicamos un poco el sentido común, veremos que lo que nos está indicando este error es que debemos de mover nuestra tabla subparticion a subparticion .
La sintaxsis correcta será:

alter table PROPIETARIO.AGENTE 
	move subpartition  PRIMER1
			tablespace TS_NEW;
alter table PROPIETARIO.AGENTE 
	move subpartition  PRIMER2 
				tablespace TS_NEW;
alter table PROPIETARIO.AGENTE
		move subpartition
			PRIMER3 tablespace TS_NEW;

Esta tarea puede ser realmente tediosa si nuestra tabla tiene un gran número de particiones y subparticiones, con lo que, lo mejor será hacer un script para moverla.
Lo primero que ha de hacerse en estos casos, es guardar la manera de volver a la situacion actual, esto lo conseguiremos con la salida del comando

select 'alter table'||
	    table_owner||
		'.'||
		table_name||
		' move subpartition '
		||subpartition_name||
		' tablespace '
		|| tablespace_name||
		' ;'
     		from  DBA_TAB_SUBPARTITIONS
   			where table_name='TABLA'

Una vez hemos guardado esta salida, podemos pasar a generar el script que nos moverá todas las subparticiones al nuevo tablespace TS_NEW

select 'alter table '
		||table_owner||
		'.'
		||table_name||
		' move subpartition '
		||subpartition_name||
		' tablespace 
		TS_NEW;' 
		    from  DBA_TAB_SUBPARTITIONS 
			 where table_name='TABLA'

Como siempre, mas información en la documentación de Oracle