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

jueves, 28 de mayo de 2009

V$RMAN_STATUS lento

Hola a todos,

El segundo tema de hoy (impresionante 2 en un día después de 6 meses) fue que la gente de BACKUP me comentó que fallaron unos backups de archive logs, y cuando me envían el fichero de log del error, era un timeout, así que ni idea.
Así que bien, como no tengo idea de DATA PROTECTOR, ni de lo que hace por dentro, le pedí a uno de los que administran DATA PROTECTOR que me explicaran un poco la arquitectura y lo que estaba haciendo. Al final deducimos que se quedaba en la ejecución de RMAN.
Después el impresionante seminario con Tanel Poder (Oracle Advance Troubleshooting), del cual comentaré otro día, me dí cuenta que esto le venía bien a su método. Tanel se basa en la sesiones, porque al final ella te va a reportar el error y efectivamente así pasó. Pero fue más "sencillo" de lo normal.
Le pedí a los de BAKCUP que lanzaran de nuevo el BACKUP, después de un rato salió el problema, 2 sesiones estaban consumiendo al 100% una core cada una, con el comando "top" (HP-UX) verifiqué, que el "pid", y lancé la siguiente consulta para ver que estaba ejecutando:

set lines 125 pages 50000 long 200000000
select s.username, s.program, a.sql_id,
p.spid, s.sid, s.status,
s.event, a.sql_fulltext
from v$session s, v$sqlstats a, v$process p
where s.sql_id= a.sql_id
and s.paddr = p.addr
and s.sql_hash_value <> 0
order by 5
/

En mi caso la base de datos desocupada en ese momento, y estaba bastante libre, por tanto no tenía muchas salidas y pude ver fácilmente el pid del server proces que es el spid.v$process. Y la magnifica consulta que tardaba mil años y que consumía muchísima CPU era la siguiente:

select round(sum(MBYTES_PROCESSED)) ,
round(sum(INPUT_BYTES)) ,
round(sum(OUTPUT_BYTES))
from V$RMAN_STATUS
start with (RECID=:b1 and STAMP=:b2)
connect by prior RECID=parent_recid

Obtuve el sql_id, por tanto también tenía el plan de ejecución (dbms_xplan) para comprobar que estaba teniendo problemas, y la verdad es que estaba un poco mal. Entonces hice una consulta sencilla para empezar:

select count(8)
from v$rman_status;

Y efectivamente me tocó “cortarla” (Ctrl+C). Después intenté ver lo que pasaba en otra base de datos, y me dió que era inmediata la consulta, fui a otra base de datos y lo mismo, era inmediata. Así bien tenía problemas en esa consulta y solo en esa base de datos. Dos magnificas vistas que consulto para ver que hace Oracle por dentro son:

v$fixed_view_definition
v$fixed_table

En la primera en el campo view_definition te describe las vistas V$. Pues bien al final del todo eran solo tres tablas X$:

X$KSFQP
X$KCCRSR
X$KRBMRST

Empecé con una prueba sencillita:

select /*+ RULE */ count(8)
from v$rman_status;

Y “voila” tardó milésimas de segundo en ejecutarme la consulta, igual que en la otras base de datos. Hablé con el personal de BACKUP y recomendé que dentro del bloque de comandos agregaran lo siguiente:

RUN
{
SQL “ALTER SESION SET OPTIMIZER_MODE=RULE”
……
}

Pues no se pudo, al final no, preferí hacer esto porque no quise entrar en obtener estadísticas de estas tablas, ya que hasta ese momento no sabía a que otras cosas afectaba el tocar estas tablas. Al final consulté todas las vistas (v$fixed_view_defintion) V$ que utilizan estas X$ y era SOLO esa, así que bien, ¿Cómo se hace para no usar el CBO sino RBO? Si las tablas no tienen estadísticas no le queda otra que usar RBO, así que decidí borrar las estadísticas de esas tablas con lo siguiente:

exec dbms_stats.delete_table_stats(ownname=>'SYS',tabname => 'X$KSFQP' );
exec dbms_stats.delete_table_stats(ownname=>'SYS',tabname => 'X$KCCRSR' );
exec dbms_stats.delete_table_stats(ownname=>'SYS',tabname => 'X$KRBMRST');

Y todavía no servía, sin que sirva de precedente, estas alguna de estas tablas hace referencia al control file, pero recrearlo era mi última opción. Siguiente:

exec dbms_stats.gather_table_stats(ownname=>'SYS',tabname => 'X$KSFQP' );
exec dbms_stats.gather_table_stats(ownname=>'SYS',tabname => 'X$KCCRSR' );
exec dbms_stats.gather_table_stats(ownname=>'SYS',tabname => 'X$KRBMRST');

Y efectivamente mi consulta sin el HINT tardó milésimas de segundo, BIEN!!!. Esto es una forma rápida, para solucionar el problema, realmente, lo que debí hacer es verificar donde se estaba quedando la consulta verificar que tienen estas X$ y lanzar las estadísticas de una forma conciente y correcta, ¿Por qué? Hay un buen documento de Jonathan Lewis que explica bastante bien la cantidad de estadísticas necesarias. Además de este documento, debemos saber que el valor del parámetro de DBMS_STAT en el METHOD_OPT por defecto es “FOR ALL COLUMNS SIZE AUTO” y esto es “MONSTRUOSO” y sino que se lo pregunten a mi compi y amigo Ricardo, y él con documentación Oracle de metalink se los explica bien, o yo lo haré pero en otro post.

El caso es que en ese momento, decidí tirar por la vía rápida (mil disculpas Ricardo) pero funcionó, recolectó estadísticas de esas tablas y la consulta iba bien, por tanto el RMAN función y pudo realizarse el BACKUP de los ARCHIVE LOGs correctamente.

Al final las V$ que la mayoría son las GV$ sin la columna INST_ID, son consultas, así bien, algunos de los problemas que puedas tener viene provocados por la consulta a tablas X$, que estas pueden ser tablas ó estructuras en memoria. Por favor, NO RECOLETAR estadísticas por LEY, NO!!!, hay que pensar que pasa en la consulta, para este caso en concreto decidí hacerlo así prque me iba a quedar sin espacio en el filesystem donde están almacenados los ARCHIVE LOGs, pero si tiene que ver con V$ revisar mil veces antes, estas NO se pueden cambiar, por tanto hice lo rápido.

Más tormentoso, pero que también podría funcionar es lanzar:

exec dbms_stats.gather_dictionary_stats();

Y así recopilar las estadísticas de todo el diccionario, pero esto es muy peligroso, al igual que para nuestro caso pude también ejecutar:

exec dbms_stats.delete_dictionary_stats();

Que al final me iba a borrar estadísticas y mi consulta iba a hacer lo mismo que con el HINT RULE.

Pero como siempre intento decirle a todos DEPENDE, en este caso al mejor solución si deseas estabilidad es centrar todo en esa consulta, así bien son solo el “ALTER SESSION” hubiese estado genial, pero como no se pudo pues tocaron más cosas, pero en serio, si desean estabilidad y no desea errores inesperados, no lancen estadísticas sin saber que se hace por dentro.

Ah, puedes buscar en METALINK y aparece un par de entradas, pero le aseguro que después de solucionarlo, empecé a buscar en METALINK y tardé más en buscar que en ejecutar mis dos o tres consultas, además esto es más divertido que estar solucionando cosas con solo buscar y hacer lo que dice METALINK, por lo menos se aprende un poco más.

martes, 17 de febrero de 2009

Oracle en Español...INCREMENTAL FROM SCN...Refrescando un standby

Entre los más de 400 millones de hispano parlantes, unos miles puede que sean DBA de Oracle, y en ocasiones algunos se sienten muy cómodos leyendo en ingles, pero otros no. Para todos aquellos que no se sienten cómodos leyendo en ingles y prefieren que las explicaciones se den en español, empiezo hoy a escribir en español documentos, pruebas, mejoras de rendimiento, etc.

Como le escribió Jonathan Lewis a un amigo mío en su libro "No porque esté escrito significa que sea cierto", y a lo que yo digo:”no porque lo escriba en este blog implique que sea verdad”, pero seguro que si que lo he probado, y además puede que no te solucione tu problema en el trabajo.

Empecemos con algo sencillo, del capitulo 13 "Using RMAN for Database Transport, Duplication and Migration" del libro "Backup and Recovery Advance User's guide"(B14191-02), en el que describen como realizar una actualización de la base de datos Standby desde un backup incremental.

Primero describamos la situación, tienes un GAP (muchos archivelogs sin estar aplicados) y han sido llevados a cinta y borrados del disco, para este caso pensemos que son un par de gigas que serían varios días sin recuperar, tardaría horas en traer a disco estos archivelogs y después aplicarlos depende de la maquina y tu configuración. Ahora en la 10g tienes BACKUP INCREMENTAL FROM SCN, que te crea un backupset que no se registra en tu repositorio de RMAN y que además es fácil de aplicar en tu standby. Situación:

- Standby con retraso de aplicación de 1 día.
- Tienes 4 días sin aplicar archivelogs.
- Has perdido los backup desde hace 4 diás hasta 2 días antes.
- Tus archivelogs se borran cada 12 horas después de copiarlos a cinta.

Sencillo, y cuando digo sencillo es porque lo es. No son solo los 4 pasos que salen en el manual, aunque tampoco mucho más y realmente estos son bastante importantes. Pero los pasos para hacer el proceso completo realmente son los siguientes:

Recuperas los números de los últimos cambios (SCNs) de los últimos archivelogs aplicados.
Con RMAN creas el backup incremental dependiendo basándote en el número de cambio (SCN) que deduces del punto 1.
Crear un controlfile para la standby con RMAN.
Copiar los ficheros en un directorio en la maquina donde está la standby ó en su defecto que se puedan ver por está maquina.
Catalogar los backupset generados.
Recuperar
Bajar y restaurar desde el nuevo standby controlfile
Y volver a montarla para iniciar la recuperación automática.

Y eso es todo, son 8 pasos, que a diferencia de los 4 que nos indica el manual sin importantes. Ahora bien lo bueno son las consultas y comandos, porque mucho hablar pero con poca idea esto no sale, y al final lo que siempre se quiere son los comandos, y yo he ejecutado los siguientes:

Desde la standby, en el sqlplus:

Select max(first_change#)
From v$log_history;

O también vale

Select max(first_change#)
From v$archived_log
Where applied ='YES';

Con esto sacas el último número de cambio (SCN) yo recomiendo hacer el backup desde el penúltimo aplicado. Después de esto apagas la recuperación automática, si no se ha hecho antes:

alter database recover managed standby database cancel;

Después de esto te conectas a la primaria con RMAN para hacer el backup incremental y crear el fichero de control para la standby.

backup incremental from scn format ' ruta y nombre y%U';

backup current controlfile for standby format 'ruta y nombre';

Dependiendo de tu configuración el va a crear más o menos ficheros, por razones como que tienes un AUTOBACKUP CONTROLFILE, por ejemplo.
Copias los ficheros a un directorio en la maquina de la standby, ya sea scp ó ftp, esto es a gusto del consumidor.
Después en la maquina donde está la standby te conectas a RMAN, y catalogas los nuevos backusets que acabas de traer de la maquina donde está la primaria:

catalog start with 'ruta donde tienes los backupsets'

Después de esto tienes que hacer la recuperación, con un sencillo:

recover database noredo;

Después de esto, que es lo ultimo que sale en el manual, y falta un paso importante, hay que poner a que sea una standby, y lo haces con el fichero de control que acabas de generar con RMAN desde la primaria. Y se debe hacer esto desde RMAN, por lo menos el "restore" del standby controlfile

shutdown
startup nomount

restore standby controlfile from 'ruta y nombre';

shutdown

startup mount

Y por ultimo volver a que se realice la recuperación automática con:

alter database recover managed standby database disconnect from session;

Para algunos que hacen recuperaciones nocturnas, y que levantan su standby por la noche para aplicar sus archivelogs, les vale hasta la bajada de la base de datos después de la recuperación de su standby controlfile, porque el script que realice la carga haría justo lo siguiente iniciar y montar.
Cuando solo haces los 4 del manual, el fichero de control de la standby queda con la última secuencia aplicada, pero las cabeceras de los datafiles con los SCNs de actuliazadas a los backupstes aplicados. Cuando restauras el fichero de control a partir del controlfile standby creado con RMAN en la primaria, quedan sincronizados, y aquí tengo que hacer un mención especial, cuando haces una recuperación hasta una fecha determinada y después restauras el fichero de control hasta una fecha determinada, el debería saber que además de ser un fichero de standby la base de datos, justo en el momento de activar la recuperación automática como no tiene realmente aplicado los arhicvelogs los debe aplicar. Si alguno se encuentra con que esto no pasa, por favor enviarme el error, pero no debería pasar, sino que simplemente empiece a recuperar desde la última secuencia con respecto a la recuperación con NOREDO realizada.

Espero que les sirva, y que si tiene algún problemilla me lo puedan comentar, así aprendemos todos.

Como les digo voy a ir escribiendo cosillas que me encuentro y que hago en el trabajo que están en ingles, y que se que es más fácil para muchos leer en español que en ingles, teniendo en cuenta no solo explicar sino también los comandos, y el porque de las cosas. Pero no es de un nivel extremadamente alto este blog, solo son pequeñas soluciones, detalles ó momentos que buscas y mejor leerlo en español.

Si alguno tiene un problema no dude en consultarme, yo no soy un mega expertos de Oracle, pero si que soy muy curioso :) . Sería bueno que al igual que Tom Kyte poder leer en español preguntas y respuestas que pueda publicar, con todo el respeto que se merece este “evangelista” mega-gurú de Oracle. Tienen mi correo así que estoy a la entera disposición siempre que lo sepa, tengo tiempo a responder.

John Ospino Rivas