viernes, 15 de octubre de 2010

Library cache lock

Este post si bien es cortito creo que es de bastante de utilidad.

Con los siguientes querys vamos a ser capaces de identificar las sesiones que están generando el evento “Library cache lock”

SQL> select saddr from v$session where sid in (select sid from v$session_wait where event like 'library cache lock');

Sesión Bloqueante

SQL> SELECT SID,USERNAME,TERMINAL,PROGRAM FROM V$SESSION
2 WHERE SADDR in

3 (SELECT KGLLKSES FROM X$KGLLK LOCK_A

4 WHERE KGLLKREQ = 0
5 AND EXISTS (SELECT LOCK_B.KGLLKHDL FROM X$KGLLK LOCK_B
6 WHERE KGLLKSES =
'el saddr del primer query' /* BLOCKED SESSION */
7 AND LOCK_A.KGLLKHDL = LOCK_B.KGLLKHDL
8 AND KGLLKREQ > 0)
9 );

Sesión Bloqueada

SQL> SELECT SID,USERNAME,TERMINAL,PROGRAM FROM V$SESSION
2 WHERE SADDR in

3 (SELECT KGLLKSES FROM X$KGLLK LOCK_A

4 WHERE KGLLKREQ > 0
5 AND EXISTS (SELECT LOCK_B.KGLLKHDL FROM X$KGLLK LOCK_B
6 WHERE KGLLKSES =
'el saddr del primer query' /* BLOCKING SESSION */
7 AND LOCK_A.KGLLKHDL = LOCK_B.KGLLKHDL
8 AND KGLLKREQ = 0)
9 );

Espero les haya servido.

Saludos!
Gondalf.


lunes, 27 de septiembre de 2010

Insert sobre una columna CLOB

Paso 1) Creamos una tabla modo de prueba (que contenga una columna CLOB)

SQL> CREATE TABLE prueba
2 (titulo VARCHAR2(40),
3 author VARCHAR2(40),
4 texto CLOB);

Table created.


Paso
2) Realizamos el insert que queremos realizar, llamando a la función EMPTY_CLOB() la cual deja un puntero vacio a un objeto CLOB.

SQL> INSERT INTO prueba VALUES ('Hobbit','Tolkien',EMPTY_CLOB());

1 row created.

SQL> commit;


Paso
3) Updeteamos la columna CLOB utilizando PL/SQL

DECLARE
my_text_handle CLOB;
my_buffer VARCHAR2(32767);
my_add_amt NUMBER := 0;
my_offset INTEGER := 1;

BEGIN
my_buffer := 'prueba con clob';
my_add_amt := length(my_buffer);

SELECT text
INTO my_text_handle
FROM prueba
WHERE title = 'Hobbit' FOR UPDATE;

DBMS_LOB.WRITE(my_text_handle, my_add_amt, my_offset, my_buffer);

COMMIT;

END;

PL/SQL procedure successfully completed.

SQL> select texto from prueba;

TEXT
-----------------------
Prueba con clob

Espero les haya servido

Saludos!
Gondalf

jueves, 16 de septiembre de 2010

ORA-16826: apply service state is inconsistent with the DelayMins property

Quería compartir con uds la solución a este particular error que se genera al utilizar Dataguard.

El origen del error está asociado a dos posibles causas:

1- El “Apply service” se levantó con la especificación de la opción “real time apply” o con la opción NODELAY siempre que el parámetro DelayMins es mayor a 0

2- El “Apply service” se levantó sin la especificación de la opción “real time apply” o sin la opción NODELAY siempre que el parámetro DelayMins es 0

Pues bien, sabiendo ahora como se origina el error podemos decir que la solución es bastante sencilla, lo único que necesitamos realizar es poner la configuración del dataguard bróker en el estado disable para luego hacer un reenable del mismo.

A continuación mostraremos los pasos a seguir:

Paso 1: Nos conecatamos al bróker

testbd@serverTEST ] dgmgrl

DGMGRL for HPUX: Version 10.2.0.4.0 - 64bit Production

Copyright (c) 2000, 2005, Oracle. All rights reserved.

Welcome to DGMGRL, type "help" for information.

DGMGRL> connect sys
Password:
Connected.
DGMGRL>

Paso 2: Ponemos en disable la configuración

DGMGRL> disable configuration
Disabled.

Paso 3: Ponemos en enable nuevamente la configuracion y el error desaparecerá

DGMGRL> enable configuration
Enabled.


En este momento cuando hagan un “show configuration” verán que el estado de la misma es SUCCESS.

Espero les haya servido

Saludos!
Gondalf

viernes, 20 de agosto de 2010

Creación de un SQL Tuning Advisor

==================================
= Eliminamos la tarea de tuning
==================================

exec dbms_sqltune.drop_tuning_task('task1');


==================================
= Creamos la tarea de tuning
==================================

DECLARE
tarea_tuning VARCHAR2(30);
sql CLOB;
BEGIN
sql := 'SELECT * from dual';
tarea_tuning := DBMS_SQLTUNE.CREATE_TUNING_TASK(
sql_text => sql,
user_name => USER,
scope => 'COMPREHENSIVE',
time_limit => 60,
task_name => 'task1',
description => 'prueba de tarea de tuning');
END;
/

/* hay un parametro mas de bind_list */


==================================
= Verificamos que la tarea este creada
==================================

SELECT task_name FROM DBA_ADVISOR_LOG WHERE owner = USER;


======================================
= Ejecutamos la tarea
======================================

BEGIN
DBMS_SQLTUNE.EXECUTE_TUNING_TASK( task_name => 'task1' );
END;
/


===================================
= Controlamos el estado de la tarea
===================================

SELECT task_id, status FROM USER_ADVISOR_TASKS WHERE task_name = 'task1';


======================================
= Controlamos el progreso del SQL Tuning Advisor
======================================

SELECT sofar, totalwork
FROM V$ADVISOR_PROGRESS
WHERE task_id = (SELECT task_id FROM USER_ADVISOR_TASKS WHERE task_name = 'task1');


=====================================
= Mostramos el resultado del SQL Tuning Advisor
=====================================

SELECT DBMS_SQLTUNE.REPORT_TUNING_TASK( 'task1') FROM DUAL;

Numero del día

A muchos les habrá pasado que de acuerdo a como se conecten a la base de datos, sea desde una terminal, desde el server, a través de un ODBC cambia la manera en que Oracle les devuelve el numero de día de una fecha en particular.

Esto sucede ya que una terminal puede tomar otro NLS_LANG distinto al del servidor.

A continuación vamos a ver como cambia el numero de día (por lo general se utiliza el domingo o el lunes como 1) de acuerdo al cambio de parámetro en el NLS_LANG


ora1@test ] export NLS_LANG='AMERICAN';
ora1@test ] sqlplus / as sysdba

SQL*Plus: Release 10.2.0.4.0 - Production on Mon Aug 20 10:35:15 2005
Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.

Connected to:
Oracle9i Enterprise Edition Release 10.2.0.4.0 - Production
With the Partitioning, Oracle Label Security, OLAP and Oracle Data Mining options
JServer Release 10.2.0.4.0 - Production

SQL> select to_char(sysdate, 'D') from dual;

T
-
2


ora1@test ] export NLS_LANG='ENGLISH'
ora1@test ] sqlplus / as sysdba

SQL*Plus: Release 10.2.0.4.0 - Production on Mon Aug 20 10:40:43 2010
Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.

Connected to:
Oracle10g Enterprise Edition Release 10.2.0.4.0 - Production
With the Partitioning, Oracle Label Security, OLAP and Oracle Data Mining options
JServer Release 10.2.0.4.0 - Production

SQL> select to_char(sysdate, 'D') from dual;

T
-
1


Espero les haya servido

Saludos!
Gondalf.

jueves, 10 de junio de 2010

Resultado de un query de varias filas concatenadas en una

La idea de este post es acercarles una función que quizás en algún momento les sea de utilidad.

El propósito de la función es concatenar el resultado de un query que devolvió varias filas en solo 1,
la función es la siguiente:

CREATE OR REPLACE FUNCTION concatfilas(qry IN VARCHAR2) RETURN VARCHAR2 IS
filaFinal VARCHAR2(4000);
result VARCHAR2(4000);
cur sys_refcursor;
BEGIN OPEN cur FOR qry;
LOOP
FETCH cur INTO result;
EXIT WHEN cur%NOTFOUND;
IF filaFinal IS NULL THEN
filaFinal := resul;
ELSE
filaFinal := filaFinal ',' result;
END IF;
END LOOP;
RETURN filaFinal;
END;
/

Ejemplo

SQL> create table prueba (nombre varchar2(30));

Table created.

SQL> insert into prueba values(‘Luis’);

1 row created.

SQL> insert into prueba values(‘Bruno’);

1 row created.

SQL> insert into prueba values(‘Matias’);

1 row created.

SQL> insert into prueba values(‘Gonzalo’);

1 row created.

SQL> commit;

1 row created.

SQL> select concatfilas('SELECT nombre FROM prueba') as nombres
2 FROM dual;


NOMBRES
------------------------------------------------------------------
Luis, Bruno, Matias, Gonzalo


Espero les haya servido

Saludos!
Gondalf.

miércoles, 9 de junio de 2010

Perdida de un Control File

Lo que primero tenemos que tener en claro que la pérdida de un control file multiplexado inmediatamente realiza un abort a la instancia. Como nosotros tenemos multiplexado nuestro control file (de no tenerlo, hacerlo!), realizar una recuperación de la instancia no es nada complicado.

Para el siguiente ejemplo supongamos que tenemos 3 control files:
/u02/oradata/test/control01.ctl
/u03/oradata/test/control02.ctl
/u04/oradata/test/control03.ctl

Por un fallo en el /u04 perdemos el control03.ctl, por ende la instancia cae dada esta perdida.
Para poder hacer el recover de la instancia lo que hacemos es modificar el parámetro CONTROL_FILES dentro del SPFILE suprimiendo el control03.ctl.

Los pasos a seguir son:

- Levantamos la base en NOMOUNT, lo hacemos en este modo dado que en MOUNT la base ya realiza un chequeo de los control files.

SQL> startup nomount
ORACLE instance started.
Total System Global Area     188743680 bytes
Fixed Size     778036 bytes
Variable Size     162537676 bytes
Database Buffers     25165824 bytes
Redo Buffers     262144 bytes


- Con la instancia en NOMOUNT podemos modificar el paramentro CONTROL_FILE dentro del spfile:

SQL> alter system set control_files =
2 '/u02/oradata/test/control01.ctl',
3 '/u03/oradata/test/control02.ctl'
4 scope = spfile;

System altered.

- Bajamos la instancia

SQL> shutdown immediate

ORA-01507: database not mounted
ORACLE instance shut down.


- Levantamos la instancia con el nuevo parametro aplicado

SQL> startup
ORACLE instance started.
Total System Global Area       188743680 bytes
Fixed Size       778036 bytes
Variable Size       162537676 bytes
Database Buffers       25165824 bytes
Redo Buffers       262144 bytes
Database mounted.
Database opened.


- Por último lo que podemos hacer es checkear que el parametro haya quedado correcto para lo cual hacemos la siguiente consulta

SQL> select name, value
2 from v$spparameter
3 where name = 'control_files';

NAME VALUE
--------------- --------------------------------------
control_files /u02/oradata/test/control01.ctl
control_files /u03/oradata/test/control02.ctl



Espero les haya servido

Saludos!
Gondalf