Mostrando entradas con la etiqueta performance. Mostrar todas las entradas
Mostrando entradas con la etiqueta performance. Mostrar todas las entradas

24 noviembre 2017

Monitorización de índices en base de datos Oracle: El mal necesario


Para aquellos que no están familiarizados con él, monitorizar índices es la forma de la base de datos Oracle de rastrear si se está usando un índice, lo que le permite saber si es necesario o no. O sea, como vengo a decir normalmete si "el índice se ha ido a Parla"

Dos cosas para tener en cuenta:
  • No siempre marca un índice como se usa, incluso si se usa. Si no se utiliza en un plan de ejecución, pero se utiliza para aplicar una clave externa o una restricción única, no se marcará como se usa.
  • La vista utilizada para ver el uso del índice es específica del esquema. Es posible que esté supervisando índices, pero los índices no se mostrarán en v$object_usage a menos que inicie sesión como propietario del esquema. Es mejor ir directamente a la consulta subyacente para ver todos los índices supervisados (consultar más abajo).
Dado que la monitorización de un índice tiene un costo muy bajo, tiene sentido activarlo para todos los índices candidatos. Los índices de FK e índices únicos funcionan, incluso si no se utilizan en los planes de ejecución, por lo que no son candidatos para descartar. Aquí está la consulta para obtener todos los índices non-unique, non-FK, se asume que no hay PK concatenadas, (Por Tutatis!) si eso ocurre, la consulta se vuelve más complicada:

SELECT 'ALTER INDEX '||ic.index_name||' MONITORING USAGE;'
  FROM all_ind_columns ic, all_indexes i
 WHERE i.uniqueness = 'NONUNIQUE' --no monitoriza índices únicos
   AND i.table_owner = 'NOMBRE_ESQUEMA'
   AND ic.index_owner = i.owner
   AND ic.index_name = i.index_name
   AND ic.position = 1
   AND NOT EXISTS (SELECT 'x' --No monitoriza índices en FK 
                     FROM all_cons_columns cc, all_constraints c
                    WHERE ic.table_name = cc.table_name
                      AND ic.column_name = cc.column_name
                      AND c.constraint_name = cc.constraint_name
                      AND c.constraint_type IN ('R'));

Aquí está la consulta para ver los objetos monitoreados si no se ha iniciado sesión como propietario del esquema:

select d.username, io.name, t.name,
       decode(bitand(i.flags, 65536), 0, 'NO', 'YES'),
       decode(bitand(ou.flags, 1), 0, 'NO', 'YES'),
       ou.start_monitoring,
       ou.end_monitoring 
from sys.obj$ io, sys.obj$ t, sys.ind$ i, sys.object_usage ou,
     dba_users d
where io.owner# = d.user_id
  AND d.username = 'SCHEMA_OWNER_HERE'
  and i.obj# = ou.obj#
  and io.obj# = ou.obj#
  and t.obj# = i.bo#;



Y aquí hay un ejemplo de monitorización de índice en acción, incluido el uso del índice exclusivo que no se marca:

CREATE TABLE test_monitoring AS SELECT level id, dbms_random.value(1,1000) value FROM dual CONNECT BY LEVEL <= 5000;

Table created.

CREATE UNIQUE INDEX test_monitoring_idx ON test_monitoring(id);

Index created.

ALTER INDEX test_monitoring_idx MONITORING USAGE;

Index altered.

Forzamos el índice para la aplicación de PK, este no marca el índice como usado:

INSERT INTO test_monitoring VALUES (100,0);
INSERT INTO test_monitoring VALUES (100,0)
*
ERROR at line 1:
ORA-00001: unique constraint (RAFA.TEST_MONITORING_IDX) violated 

SELECT index_name, used FROM v$object_usage WHERE index_name = UPPER('test_monitoring_idx');

INDEX_NAME                     USE                                              
------------------------------ ---                                              
TEST_MONITORING_IDX            NO                                               

Pero ejecutamos una sentencia "Select" que usará el índice

SELECT * FROM test_monitoring WHERE id = 100;

        ID      VALUE                                                           
---------- ----------                                                           
       100   255.5571                                                           
Y ahora el índice aparece como usado:

SELECT index_name, used FROM v$object_usage WHERE index_name = 'TEST_MONITORING_IDX';

INDEX_NAME                     USE                                              
------------------------------ ---                                              

TEST_MONITORING_IDX            YES 

Tener índices sin usar en la base de datos puede quitarnos espacio necesario y reducir el rendimiento en las sentencias  de borrado o actualización, por eso es importante eliminar aquellos que no son utilizados.



29 octubre 2017

DBA WARS: "It's an older code sir, but it checks out."


En esta entrada del blog vamos a dar salida a varios còdigos SQL Y PL/SQL, antiguos pero todavía válidos.

Problemas con de PL / SQL Developer de Allround Automations

Al usar este IDE e su versión 11.X, una consulta interna toma muchos ciclos de CPU en el servidor de la base de datos (100% de una CPU).
¿Es este tu problema?  Por favor, compruebe si hay una consulta al lanzar el editor con el siguiente formato de consulta:
select s.synonym_name object_name, o.object_type
from sys.all_synonyms s, sys.all_objects o where s.owner in ('PUBLIC', user) and o.owner = s.table_owner and o.object_name = s.table_name and o.object_type in ('TABLE', 'VIEW', 'PACKAGE','TYPE', 'PROCEDURE', 'FUNCTION', 'SEQUENCE');
Se debe a la opción Describir contexto del asistente de código. Para deshabilitar:
Mira en: Tools> Preferences> Code Assistant y deshabilitar la opción "Describe Context".
O comprarles la versión 12.X que ya está resuelto.


Depurar papelera de reciclaje anterior a ...


Tiene la papelera de reciclaje de la base de datos llena o su tamaño es considerablemente grande, pero no quiere hacer un "Borrado" completo?
¿Quieres eliminar solo más de x días (como más de 90 días)?

Una buena forma de hacerlo es:

# 90 días
Select 'purge table '||owner||'."'||OBJECT_NAME||'";' from dba_recyclebin where type='TABLE' and to_date(droptime,'YYYY-MM-DD:HH24:MI:SS')<sysdate-90;
# 90 minutos
Select 'purge table '||owner||'."'||OBJECT_NAME||'";' from dba_recyclebin where type='TABLE' and to_date(droptime,'YYYY-MM-DD:HH24:MI:SS')<sysdate-(90/(24*60));

Mirar esta nota de Metalink (Doc ID 1596147.1) por si teneis alguna qe otra duda.


Purga mejorada de la papelera de reciclaje Oracle

Desde que en la versión 10g de la base de datos , se introdujo el 'reciclaje' para segmentos. Si se establece el parámetro recyelebin = on, y se descarta una tabla, en realidad no se descarta; se renombra a un nombre generado por el sistema. Esto realmente puede ayudar en situaciones donde una tabla se cae accidentalmente, ya que se puede recuperar fácilmente. Sin embargo, sin monitorearlo, puede terminar causando problemas de muchos tipos, porque puede terminar hinchando el número total de segmentos en la base de datos a muchas veces más de lo que era antes.
Oracle solo tiene 4 métodos publicados para descartar lotes de objetos reciclados; siendo:

  • El comando SQL> PURGE RECYCLE BIN emitido por un propietario de segmento, que purga todos los segmentos reciclados para ese usuario.,
  • El comando SQL> PURGE DBA_RECYCLEBIN, emitido por un DBA, que purga todos los objetos reciclados en la base de dato.
  • El comando SQL> PURGE TABLESPACE <tablespace_name> USER <schema_name>; que purga objetos propiedad del propietario dado.
  • El comando SQL> PURGE TABLESPACE uwdata USUARIO uwclass; que purga los objetos propiedad del propietario y el espacio de tabla dados.
No hay comandos incorporados que permitan que solo los segmentos de papeleras de reciclaje se realicen antes de cierto tiempo, o que solo reciclen objetos de la papelera con más de un cierto número de versiones recicladas de la misma tabla. Es relativamente fácil crear un procedimiento almacenado para manejar estos casos; esto explica cómo se puede hacer eso.

En PL/SQL, tenemos:


create or replace procedure purge_user_recyclebin(
  p_purge_before_date   in date default=NULL,
  p_purge_keep_versions in number default=NULL,
  p_test_only           in varchar2 := 'Y'
)
is
  cursor c_purge_before_date is
    select object_name
    from  user_recyclebin
    where droptime > p_purge_before_time
    and   can_purge = 'YES'
    order by droptime;

  cursor c_purge_before_version is
     select * from 
       (select original_name,
               type,
               object_name,
               droptime,
               rank() over (partition by original_name,type order by droptime desc) as obj_rank
         from   user_recyclebin
         where  can_purge = 'YES')
       where obj_rank > p_purge_keep_versions
       order by droptime;

  v_sql varchar2(1024);

  exception e_bad_parameters;
  exception e_38302;
  pragma exception_init(e_38302,-38302);  

  procedure runsql(p_object_name in varchar2) 
  is
  begin
    v_sql := 'purge '||p_object_name;
    if (p_test_only = 'N') then
      begin
        execute immediate v_sql;
      exception
         when e_38302 then 
           dbms_output.put_line('Cuidado, el objeto '||p_object_name||' no existe ignóralo');
         when others then
           dbms_output.put_line('Error borrando '||p_object_name);
           dbms_output.put_line(dbms_utility.format_error_backtrace);
      end;
    else
      dbms_output.put_line(v_sql);
    end if;
  end;

begin

  if p_purge_before_date is not null and
     p_purge_keep_versions is null then
     for r in c_purge_before_date loop
       runsql(r.object_name);
     end loop;
  elsif p_purge_before_date is null and
     p_purge_keep_versions is not null then
     for r in c_purge_before_version loop
       runsql(r.object_name);
     end loop;
  else
     raise e_bad_parameters;
  end if;

end purge_user_recylebin;
/

Cómo usarlo

Si desea probar para ver qué haría, sin purgar nada, simplemente pase el parámetro 'p_test' al valor 'Y', y establezca la salida del servidor en el tamaño 1000000. Esto mostrará una lista de los comandos que se ejecutarían. pero en realidad no los ejecuta.

Purgar todos los objetos de la papelera de reciclaje antes de una fecha determinada
Esto purgará todos los objetos de reciclaje reciclados antes del 1 de noviembre, a medianoche.

execute purge_user_recylebin(to_date('20150801 00:00:00','YYYYMMDD HH24:MI:SS'),NULL,'Y');

Esto, cuando se ejecuta como propietario de un esquema, ayuda a mantener la cantidad de objetos reciclados a un nivel razonable, a la vez que se conserva, la capacidad de recuperar segmentos perdidos más recientemente.




25 octubre 2017

ADR: Si el Dr House fuera DBA, usaría esto

House M. D. (Medical diagnostic) era una serie de televisión estadounidense de la cadena FOX. El personaje central es el Dr. Gregory House, un genio médico, irónico, satírico y poco convencional e inconformista, que encabeza un equipo de diagnóstico en el Hospital Universitario Princeton-Plainsboro de Nueva Jersey.

Pero ahora entremos en detalles mas interesantes, en el contexto de este blog:

En la versión 11g, de la base de datos Oracle, se introdujo un nuevo concepto para el repositorio de los archivos de diagnostico de la base de datos, llamado ADR (Automatic Diagnostic Repository por sus siglas en ingles) 

En versiones anteriores (10g, sí, todavía hay bases de datos de esta versión por el mundo ) se utilizaban los parámetros:
  • BACKGROUND_DUMP_DEST
  • CORE_DUMP_DEST
  • USER_DUMP_DEST 

en estos lugares podíamos ver los archivos que nos ayudaban a hacer un diagnostico de errores de la base de datos. A partir de la versión 11g, se introdujo la variable DIAGNOSTIC_DEST, en donde Oracle esta tratando de estandarizar la estructura de directorios para manejar los archivos relacionados a fallas y alertas. La estructura del repositorio ADR para la base de datos, tanto en servidor como en el cliente, en la versión 12.1.0.2, es de la siguiente manera:

Estructura de directorios en servidor:


Estructura de directorios en cliente:



Un cambio muy importante que se da en 11g es que el formato del archivo de alertas de la base de datos es en formato .xml, ya que lo puedes ahora visualizar de una mejor manera en OEM, pero tambien lo puedes encontrar en su formato anterior. Si quieres ver como tienes la estructura en tu base de datos, lo puedes hacer con el siguiente query:

DBATEST> SELECT * FROM V$DIAG_INFO;

INST_ID NAME VALUE

1 Diag Enabled TRUE
1 ADR Base /mount/dump01/oracle/DBATEST
1 ADR Home /mount/dump01/oracle/DBATEST/diag/rdbms/dbatest/DBATEST
1 Diag Trace /mount/dump01/oracle/DBATEST/diag/rdbms/dbatest/DBATEST/trace
1 Diag Alert /mount/dump01/oracle/DBATEST/diag/rdbms/dbatest/DBATEST/alert
1 Diag Incident /mount/dump01/oracle/DBATEST/diag/rdbms/dbatest/DBATEST/incident
1 Diag Cdump /mount/dump01/oracle/DBATEST/diag/rdbms/dbatest/DBATEST/cdump
1 Health Monitor /mount/dump01/oracle/DBATEST/diag/rdbms/dbatest/DBATEST/hm
1 Default Trace File /mount/dump01/oracle/DBATEST/diag/rdbms/dbatest/DBATEST/trace/DBATEST_ora_18035.trc
1 Active Problem Count 1

1 Active Incident Count 75

De la misma manera, Oracle trae ahora una herramienta muy util llamada adrci, esta herramienta te permite manejar el repositorio ADR,muy importante, es que antes de mandar a llamar a la herramienta, las variables de entorno ORACLE_HOME,PATH y ADR_HOME estén bien iniciadas. Puedes ver el archivo de alertas de la base de datos de la siguiente manera:


adrci> SHOW ALERT -TAIL 5
2011-07-17 18:04:41.207000 -04:00
Archived Log entry 4735 added for thread 1 sequence 4735 ID 0xffffffffb7363f82 dest 1:
2011-07-17 21:00:49.339000 -04:00
Thread 1 advanced to log sequence 4737 (LGWR switch)
Current log# 3 seq# 4737 mem# 0: /mount/u01/oracle/DBATEST/log/redo03a.log
Current log# 3 seq# 4737 mem# 1: /mount/u01/oracle/DBATEST/log/redo03b.log
Archived Log entry 4736 added for thread 1 sequence 4736 ID 0xffffffffb7363f82 dest 1:

También podemos ver un incidente de la siguiente manera, usando ADR:


adrci> show incident

ADR Home = /mount/dump01/oracle/DBATEST/diag/rdbms/dbatest/DBATEST:
*************************************************************************
INCIDENT_ID PROBLEM_KEY CREATE_TIME
-------------------- ----------------------------------------------------------- ----------------------------------------
2041 ORA 4031 2016-11-14 05:58:35.042000 -05:00
2105 ORA 4031 2016-11-14 05:58:35.272000 -05:00
2017 ORA 4031 2016-11-14 05:58:35.272000 -05:00
1873 ORA 4031 2016-11-14 05:58:35.279000 -05:00
2153 ORA 4031 2016-11-14 05:58:35.280000 -05:00
37051 ORA 4031 2017-10-16 21:51:03.983000 -04:00
37027 ORA 4031 2017-10-16 21:51:04.239000 -04:00
36707 ORA 4031 2017-10-16 21:51:18.575000 -04:00
37019 ORA 4031 2017-106-16 21:51:22.650000 -04:00
37052 ORA 4031 2017-10-16 21:51:29.050000 -04:00
10 rows fetched

Una vez que visualizas los errores, puedes ver el detalle de ellos, así como la traza generada:


adrci> SHOW INCIDENT -MODE DETAIL -P "INCIDENT_ID=57052"

ADR Home = /mount/dump01/oracle/DBATEST/diag/rdbms/dbatest/DBATEST:
*************************************************************************

**********************************************************
INCIDENT INFO RECORD 1
**********************************************************
INCIDENT_ID 37051
STATUS ready
CREATE_TIME 2017-10-16 21:51:03.9830000 -04:00
.
.
.
KEY_NAME Client ProcId
KEY_VALUE oracle@localhost.33449_1
KEY_NAME SID
KEY_VALUE 151.3
OWNER_ID 1
INCIDENT_FILE /mount/dump01/oracle/DBATEST/diag/rdbms/dbatest/DBATEST/incident/incdir_57051/DBATEST_dw03_13299_i57052.trc
OWNER_ID 1
INCIDENT_FILE /mount/dump01/oracle/DBATEST/diag/rdbms/dbatest/DBATEST/trace/DBATEST_dw03_66699.trc
1 rows fetched


Esta herramienta te permite crear un paquete y si así lo necesitas lo envias a Oracle, 
esto te evita el trabajo de andar buscando los archivos que necesitas enviar a Oracle Metalink, perdón  MOS.
Una vez, explicado el mecanismo y el uso de esta utilidad, espero que nos sirva para solucionar, 
alguno de esos errores terribles, que de vez en cuando aparecen en nuestras vidas  como DBA.

08 octubre 2017

Qué hacer cuando tenemos una alerta de aumento de registros espectacular en el tablespace SYSAUX

Este artículo vamos a mostrar diferentes casuísticas que puedes tener cuando tienes un aumento espectacular de ocupación de tablespace SYSAUX.
A partir de Oracle 10g en adelante, hay lo que Yo llamaría un error grave (para Oracle, es una característica 💀), debido a que el tablespace SYSAUX crecerá continuamente. Sólo hay forma de limitar este crecimiento y no está claramente documentado en ninguna parte

¿Para que demonios vale ese tablespace?

El espacio de tablas SYSAUX se instaló como un tablespace auxiliar en el tablespace SYSTEM cuando creó la base de datos, apareció a partir de la versión 10g. Algunos componentes de base de datos que anteriormente creaban y utilizaban espacios de tabla independientes ahora ocupan el espacio de tablas SYSAUX.

Si el espacio de tablas de SYSAUX no está disponible, la funcionalidad de la base de datos central permanecerá operativa. Las funciones de base de datos que utilizan el espacio de tablas SYSAUX podrían fallar o funcionar con capacidad limitada.


Estos componentes pueden utilizar el espacio de tablas SYSAUX y su instalación proporciona los medios para establecer su ocupación del espacio de tablas SYSAUX. Puede controlar los ocupantes del espacio de tablas SYSAUX mediante la vista V $ SYSAUX_OCCUPANTS. Esta vista enumera la siguiente información sobre los ocupantes del espacio de tablas SYSAUX:
  • Nombre del ocupante
  • Descripción del ocupante
  • Nombre del esquema
Configuración básica del tablespace SYSAUX

CASO #1: Uno de los ocupantes de SYSAUX, el optimizador de estadísticas, crece exponencialmente.


Tengo una base de datos de Oracle 11g R2 (11.2.0.1) donde advertí que el tablespace de SYSAUX crecía cada día más y más grande. Busqué en Metalink (perdón, Oracle My Support) y encuentro dos notas:
  • Doc ID 1292724.1
  • Doc ID 552880.1 
que fueron útiles.

Después de ejecutar el script awrinfo.sql, localizado en $ORACLE_HOME/rdbms/admin/, encontré que el consumidor más grande era SM / OPTSTAT en 3 GB que es más grande y no típico en comparación con mis otras bases de datos Oracle 10g R2 y Oracle 11g R1.

Investigando por la documentación encuentro lo siguiente:
"Siempre que se modifiquen las estadísticas del diccionario, las versiones antiguas de estadísticas se guardan automáticamente para futuras restauraciones. Las estadísticas antiguas se depuran automáticamente a intervalos regulares en función de la configuración de retención de historial de estadísticas y de la hora de la recopilación de estadísticas recientes realizada en el sistema. La retención se puede configurar mediante el procedimiento ALTER_STATS_HISTORY_RETENTION. El valor predeterminado es 31 días."
Para ayudar a reducir la cantidad de espacio causada por datos históricos, fijé la retención de las viejas estadísticas a 14 días.

exec dbms_stats.alter_stats_history_retention (14);

Para verificar la nueva configuración, ejecuté la siguiente declaración.

select dbms_stats.get_stats_history_retention from dual;

Procedí a depurar incrementalmente las estadísticas de 31 días a 14 días. Comenzó con 28 días, luego se trasladó a 21 días.

exec dbms_stats.purge_stats (sysdate-28);

Entonces intenté 14 días, sin embargo encontré un error del espacio de la UNDO que requiere que cambie mis incrementos usando 18, 16, y finalmente 14 para terminar la tarea de la purga.

Ahora, para recuperar el espacio utilizado por los objetos mostrados en la sección 4 del informe AWRINFO, usé el comando ALTER TABLE MOVE.

CASO #2: Otra forma de resolver el crecimiento desmesurado del optimizador de estadísticas.

A partir de 10gR1 en adelante, Oracle mantendrá la copia de seguridad de las estadísticas del optimizador automáticamente, incluso si no le pide que lo haga.

Esta información de copia de seguridad se almacena en el tablespace SYSAUX y las tablas implicadas en esto son las siguientes:
  • WRI$_OPTSTAT_OPR                         
  • WRI$_OPTSTAT_AUX_HISTORY                 
  • WRI$_OPTSTAT_TAB_HISTORY                 
  • WRI$_OPTSTAT_IND_HISTORY                 
  • WRI$_OPTSTAT_HISTGRM_HISTORY             
  • WRI$_OPTSTAT_HISTHEAD_HISTORY  

La retención predeterminada de esta información se obtiene con el siguiente comando:

NO se escribirá ningún mensaje en el registro de alertas ni en ningún otro lugar para indicar que no se ha producido la purga. Con cada día que pasa, la probabilidad de falla aumenta y alcanzará una etapa, donde la purga automática nunca será completada por MMON con éxito.

Alternate proporcionado por Oracle para esto es ejecutar, programa DBMS_STATS.PURGE_STATS para purgar esta información de estadísticas. Esto se puede hacer manualmente y es seguro. No hay tiempos muertos involucrados aquí. sólo una terminación manual o un fallo anormal detendrá la purga.

¿Qué más me falta aquí?

A pesar de que publicamos la retención, puede suceder que debido a la falta de purga, vamos a acumular gran cantidad de historial de estadísticas en SYSAUX, haciendo que crezca continuamente.

Como el fallo de purga no está escrito en ninguna parte, podemos perder el hecho de que hay un proceso que consume el espacio con regularidad.

El proceso PURGE_STATS suprimirá estas tablas. Por lo tanto, el espacio libre no se devuelve al espacio de tablas, lo que resulta en una fragmentación de espacio libre dentro de esta tabla.

¿Cómo sé que tengo este problema?

Compruebe su valor de retención actual utilizando la siguiente sentencia
select dbms_stats.get_stats_history_retention from dual;

Vea el historial de estadísticas más antiguo usando la siguiente declaración:

select dbms_stats.get_stats_history_available from dual;
Comparar los dos anteriores y y deberías saber qué hacer

¿Qué debería hacer ahora?

Identifique la retención del sistema tan pronto como sea posible y cambie a un valor apropiado. 30 días es el valor predeterminado. Sin embargo, los valores más pequeños no harían mucho daño.

Deshabilite el Autoextend en SYSAUX tan pronto como sea posible para asegurarse de que el espacio de tablas no crece fuera de límites y, finalmente, se convierte en inmanejable.

Comience a programar el PURGE_STATS tan pronto como sea posible y mantenga el tamaño del espacio de tablas SYSAUX en control.

Realice la reorganización de tablas relacionadas para recuperar el espacio.

¿Por qué debería importarme?

Con cada día que pasa, el tamaño de la tabla crece más grande y más grande, finalmente convirtiéndose en un consumidor superior del espacio. Los esfuerzos que se harán para la limpieza aumentará exponencialmente. HACERLO diariamente en 1hr o hacerlo en 5hr mañana.

El procedimiento PURGE_STATS realiza una supresión de comando simple con una cláusula where específica. Esto deja mucho desorden a medida que el proceso se completa completamente o no hace nada en absoluto. No se engancha a intervalos regulares en este código.

Para una base de datos promedio de 150G, en 6 meses, puede terminar con 100M filas en esta tabla. La limpieza de estos datos es siempre un dolor.

¿Algún consejo?

Identifique la información más antigua que tenga en el historial de estadísticas usando el siguiente comando.

select dbms_stats.get_stats_history_availability from dual;

Si la información es demasiado antigua, comience a purgar la información en trozos más pequeños. recuerde que si cancela el proceso en el medio, usted hará una reversión completa antes de salir.

Utilice el siguiente comando para saber en qué fechas había generación de estadísticas enormes.
select trunc(SAVTIME),count(1) from WRI$_OPTSTAT_HISTHEAD_HISTORY group by  trunc(SAVTIME) order by 1;

Comienza con la fecha más antigua y se invoca bajo el comando
exec dbms_stats.purge_stats (to_date ('01 -JAN-2010 ',' DD-MON-YYYY '));

Una vez que la cantidad de datos se reduce a un límite de tiempo razonable en las horas punta, como una actividad de mantenimiento regular.

NOTA: Tenga en cuenta que este proceso requiere muchos recursos. No lo hagas durante horas de oficina.


03 octubre 2017

Optimización de los Parámetros de UNDO


A Partir de Oracle 9i, los segmentos de rollback pasan a llamarse Undo Logs. Tradicionalmente, la información de transacciones (UNDO) se almacenaba en Rollback segments hasta el COMMIT o ROLLBACK. Oracle9i permite la gestión automática de UNDO. El DBA para especificar cuánto tiempo debe mantenerse la información de UNDO, para prevenir los errores "snapshot too old" en consultas largas. Esto se hace mediante el parámetro UNDO_RETENTION. 
El valor por defecto es de 900 segundos (15 minutos), Y puedes cambiar este parámetro para garantizar que Oracle mantiene los registros de UNDO largos períodos de tiempo. En lugar de tener que definir y gestionar los segmentos de rollback, puedes simplemente definir un tablespace UNDO y dejar que se ORACLE se encargue de lo demás. En cuanto a la gestión automática de Undo es fácil. Todo lo que necesitas es crear un Tbs UNDO y poner el UNDO_MANAGEMENT = AUTO. Sin embargo vale la pena para ajustar los siguientes parámetros: 

  • El tamaño del Tbs UNDO. 
  • El Parámetro UNDO_RETENTION. 
  • Calcular el UNDO_RETENTION para el Undo Tablespace. 


Puedes optar por asignar un determinado tamaño del tablespace UNDO y, a continuación, establecer el UNDO_RETENTION a un valor óptimo de acuerdo con el tamaño de UNDO y la actividad de la base de datos. Si su espacio en el disco es limitado y no quiere asignar más espacio del necesario para el Tbs Undo, esta es la forma de proceder. 
 La siguiente consulta le ayudará a optimizar el 
UNDO_RETENTION (Optimo) = UNDO SIZE Actual / DB_BLOCK_SIZE * UNDO_BLOCK_PER_SEQ 

Dado que estas consultas usan las estadísticas V$UNDOSTAT, ejecute las consultas sólo después de que la Base de datos lleve funcionando con UNDO para un importante y representativo periodo de tiempo.


Actual Undo Size

SELECT SUM(a.bytes) "UNDO_SIZE"
  FROM v$datafile a,
       v$tablespace b,
       dba_tablespaces c
 WHERE c.contents = 'UNDO'
   AND c.STATUS = 'ONLINE'
   AND b.name = c.tablespace_name
   AND a.ts# = b.ts#; 

Undo Blocks per Second

SELECT MAX(undoblks/((end_time-begin_time)*3600*24))
      "UNDO_BLOCK_PER_SEC"
  FROM v$undostat; 
DB Block Size
SELECT TO_NUMBER(value) "DB_BLOCK_SIZE [KByte]"
 FROM v$parameter
WHERE name = 'db_block_size'; 

Optimal Undo Retention

SELECT d.undo_size/(1024*1024) "ACTUAL UNDO SIZE [MByte]",
       SUBSTR(e.value,1,25) "UNDO RETENTION [Sec]",
       ROUND((d.undo_size / (to_number(f.value) *
       g.undo_block_per_sec))) "OPTIMAL UNDO RETENTION [Sec]"
  FROM (
       SELECT SUM(a.bytes) undo_size
          FROM v$datafile a,
               v$tablespace b,
               dba_tablespaces c
         WHERE c.contents = 'UNDO'
           AND c.STATUS = 'ONLINE'
           AND b.name = c.tablespace_name
           AND a.ts# = b.ts#
       ) d,
       v$parameter e,
       v$parameter f,
       (
       SELECT MAX(undoblks/((end_time-begin_time)*3600*24))
              undo_block_per_sec
         FROM v$undostat
       ) g
WHERE e.name = 'undo_retention'
  AND f.name = 'db_block_size'
/ 

Calcular el UNDO necesario para la actividad de la BBDD

SELECT d.undo_size/(1024*1024) "ACTUAL UNDO SIZE [MByte]",
       SUBSTR(e.value,1,25) "UNDO RETENTION [Sec]",
       (TO_NUMBER(e.value) * TO_NUMBER(f.value) *
       g.undo_block_per_sec) / (1024*1024) 
      "NEEDED UNDO SIZE [MByte]"
  FROM (
       SELECT SUM(a.bytes) undo_size
         FROM v$datafile a,
              v$tablespace b,
              dba_tablespaces c
        WHERE c.contents = 'UNDO'
          AND c.STATUS = 'ONLINE'
          AND b.name = c.tablespace_name
          AND a.ts# = b.ts#
       ) d,
      v$parameter e,
       v$parameter f,
       (
       SELECT MAX(undoblks/((end_time-begin_time)*3600*24))
         undo_block_per_sec
         FROM v$undostat
       ) g
 WHERE e.name = 'undo_retention'
  AND f.name = 'db_block_size'
/

08 julio 2014

Monitorización en tiempo Real de SQL utilizando DBMS_SQLTUNE


Los informes de Real-Time SQL Monitoring se pueden encontrar dentro de las herramientas de Oracle en:
  • Enterprise Manager – Haz Click en la pestaña "Performance", entonces aparece el link  "SQL Monitoring" en la parte inferior derecho  de la página para dar paso a la ventana "Monitored SQL Executions". Haz click en las SQL_ID que te interesen para mostrar los informes de monitorización de SQL.
  • SQL Developer – disponible en el menu de  "Tools > Monitor SQL".
  • El paquete DBMS_SQLTUNE.

En este pequeño artículo voy a demostrar el uso del paquete DBMS_SQLTUNE para mostrar los informes de seguimiento de SQL sin utilizar las herramientas Enterprise Manager o SQL Developer. Este artículo ha incluido la funcionalidad adicional introducida en Oracle 12c.

SQL monitoring require que
  • El parámetro STATISTICS_LEVEL esté inicializado a 'TYPICAL' o 'ALL'
  • El parámetro CONTROL_MANAGEMENT_PACK_ACCESS esté inicializado a 'DIAGNOSTIC+TUNING'.


SQL> CONN / AS SYSDBA
Connected.
SQL> SHOW PARAMETER statistics_level

NAME                                                                      TYPE       VALUE
------------------------------------                                         -----------    ------------------------------
statistics_level                                                         string     TYPICAL

SQL> SHOW PARAMETER control_management_pack_access

NAME                                                                      TYPE       VALUE
------------------------------------                                          ----------- ------------------------------
control_management_pack_access                              string     DIAGNOSTIC+TUNING

SQL>


MONITOR Hint
El hint MONITOR habilita la monitorización SQL para sentencias, que de otra manera no las iniciaría.

SELECT /*+ MONITOR */ d.dname, WM_CONCAT(e.ename) AS employees
FROM   emp e JOIN dept d 
ON e.deptno = d.deptno
GROUP BY d.dname
ORDER BY d.dname;


REPORT_SQL_MONITOR


La función puede aceptar muchos parámetros opcionales, aquí puedes revisarlos, pero la mayoría que vas a usar están descritos como sigue: