jueves, 31 de marzo de 2011

Instancia es igual a Procesos y Estructuras de memoria

La definicion de una instancia es sencilla y basica, es un conjunto de estructuras de memoria que manejan los archivos de la base de datos, cuando inicia la instancia, con ella inician procesos de fondo (Background Process), como el LGWR, PMON, etc.

Importante saber que al menos una base de datos activa o mejor dicho que esta corriendo, debe de tener una instancia asociada. De la misma manera, como la instancia existe en memoria y la base de datos existe en disco, una instancia puede existir sin una base de datos y una base de datos puede existir sin una instancia, si no me crees esto, haz la prueba, arranca la instancia en modo nomount y veras que sin existir los datafiles,controlfiles y redo logs puedes iniciar la instancia


TESTDB >startup nomount

ORACLE instance started.
Total System Global Area 1369989120 bytes
Fixed Size 2158184 bytes
Variable Size 268439960 bytes
Database Buffers 1090519040 bytes
Redo Buffers 8871936 bytes

oracle@localhost [TESTDB] /mount/dba01/oracle/TESTDB/admin
oracle $ ps -eaf | grep TESTDB

oracle 27411 1 0 01:21:35 ? 0:00 ora_pmon_TESTDB

oracle 27448 1 0 01:21:37 ? 0:00 ora_ckpt_TESTDB

oracle 27435 1 0 01:21:37 ? 0:00 ora_dia0_TESTDB

oracle 27439 1 0 01:21:37 ? 0:00 ora_dbw0_TESTDB

oracle 27454 1 0 01:21:37 ? 0:00 ora_mmon_TESTDB

oracle 27415 1 0 01:21:35 ? 0:00 ora_psp0_TESTDB

oracle 27444 1 0 01:21:37 ? 0:00 ora_dbw1_TESTDB

oracle 27431 1 0 01:21:37 ? 0:00 ora_diag_TESTDB

oracle 27446 1 0 01:21:37 ? 0:00 ora_lgwr_TESTDB

oracle 27452 1 0 01:21:37 ? 0:00 ora_reco_TESTDB

oracle 27450 1 0 01:21:37 ? 0:00 ora_smon_TESTDB

Aqui abajo esta una pequeña grafica de como se conforma una instancia:


Y debido a lo que platicamos arriba, es lo que permite la configuracion para RAC (Real Application Cluster), asi tambien es importante saber que una instancia no puede tener asociada una sola base de datos a la vez, o sea que no puedes montar dos base de datos en una instancia.

Memoria
La memoria SGA tiene 3 estructuras básicas:

Database buffer cache.- Es el área de memoria que almacena copias de los bloques de datos leídos de los data files.Tambien a esta área se le conoce nada mas como Buffer Cache. Esta seccion de la memoria tiene tres estados.
  • Sin Usar (Unused).-El buffer esta disponible por que nunca se ha usado o actualmente esta sin usar.
  • Limpia (Clean).-Este buffer fue usado previamente, y ahora contiene una version consistente del bloque de datos en un punto en tiempo. El bloque contiene datos, pero este se puede decir que esta limpio, ya que no se le necesita hacer un checkpoint a los datos.
  • Sucia (Dirty).-El buffer contiene datos que no han sido escrito a disco, Oracle necesita hacer un checkpoint del bloque de datos antes de reusarlo.
  • Para manejar estos estados, Oracle tiene un algortimo llamado LRU (Least Recently Used), lo que hace este algoritmo es sacar del buffer a los bloques de datos menos usados y que ya se le hayan hecho un checkpoint para asi poder subir al Buffer Cache nuevos datos y evitar sacar del Buffer Cache los datos que se usan con frecuencia.

Shared Pool .- Esta área de memoria guarda SQL analizado (Parsed),parámetros del sistema y el diccionario de datos (Data Dictionary Cache y Library Cache).

Redo Log Buffer.- Esta estructura de memoria en el SGA, que guarda los registros de Redo, estos contienen la información necesaria para reconstruir los cambios hechos por DDLs o DMLs a la base de datos.

Procesos
Existen varios que son obligatorios, como los mencionados aqui abajo, de la misma manera existen muchos procesos que se inician una vez que añades alguna funcionalidad, como el ARCn, que es cuando la base de datos esta en modo archivelog.

PMON.- La funcionalidad de este proceso es la de monitorear que los demás procesos de la instancia estén corriendo, a su vez es responsable de limpiar el Database Buffer Cache y limpiar recursos que el cliente haya utilizado.

SMON.-La tarea principal de este proceso es la de limpieza a nivel sistema, y también una de las tareas principales de este proceso es llevar a cabo la recuperación al iniciar la instancia cuando anteriormente finzalizo de una manera abrupta, como un shutdown abort o un crash del servidor.

CKPT.-Su función es la de actualizar las cabeceras de los control files y de los data files, con información de Checkpoint (SCN, Posición de Checkpoint, etc), a su vez la avisa al DBWn que debe de escribir los bloques del Buffer Cache a disco. Muy importante saber, que el CKPT no escribe los datos, ni al Redo Log ni a los data files.

DBWn.-Este proceso escribe los contenidos sucios del buffer Cache, a este proceso se le conoce como un proceso flojo, ya que por si solo no escribe a disco, este unicamente escribe a disco cuando no hay bloques de datos limpios en el buffer cache o cuando CKPT le informa que debe hacerlo.

LGWR.- De lo que se encarga es de escribir los Redo Log Buffers a disco (Online Redo Log). Este proceso utiliza un método que se le conoce como Fast Commit. Cuando un usuario ejecuta un commit, a la transacción se le asigna un SCN (System Change Number), LGWR pone una marca de commit en el Buffer Cache e inmediatamente escribe a disco, cuando se han escrito estos datos en el Online Redo Log, el proceso actualiza el Buffer Cache haciendo mención de que estos ya se escribieron a disco.

Conclusion
Espero que esta pequeña explicación te ayude a comprender la diferencia entre la Instancia y lo que en Oracle se conoce como Base de Datos. De la misma manera los procesos basicos y memoria basica de la instancia, para los procesos y la memoria existen mas de los mencionados aqui, pero estos son los minimos necesarios en una configuracion de Oracle.

miércoles, 30 de marzo de 2011

Que es un Online Redo Log

Que es Online Redo Log?
El Online Redo log, es una estructura fisica que consiste de minimo de dos archivos, estos a su vez pueden estar multiplexados en dos o mas copias identicas, que a estos se le conocen como miembros de un grupo de Redo log. Como mencionamos, el Online Redo Log consiste de minimo dos archivos, esto permite que Oracle escriba en un archivo de Online Redo Log mientras el otro se archiva (Cuando mencionamos archivar, es si la base de datos se encuentra en modo ARCHIVELOG).
En los Online Redo logs se almacenan registros de Redo, los cuales estan conformados por vectores de cambio (change vectors), cada uno de estos vectores describe los cambios a un bloque de datos.

Todos los registros de tipo redo tiene metadata relevante al cambio, incluyendo:
  • SCN y la estampa de tiempo del cambio
  • El ID de la transaccion que ha generado el cambio
  • SCN y la estampa de tiempo cuando la transaccion fue cometida (si es que fue cometida)
  • Tipo de operacion que efectuo el cambio
  • Nombre y tipo del segmento de dato modificado

Los Online Redo Log son usados unicamente en el proceso de la recuperación de la base de datos.
Basicamente,lo que hay que entender como principio, es que cuando algun DML (insert,update o delete) o un DDL (alter, create, drop) sucede en nuestra base de datos, Oracle registra los cambios en memoria, en un buffer llamado Redo Log Buffer, que con este buffer hay un proceso asociado llamado LGWR.

El proceso LGWR de lo que se encarga es de escribir de la estructura de memoria (Redo) Log Buffer a los Online Redo Logs, y muy importante es saber cuales son las circunstancias que hacen que el LGWR escriba al Online Redo Log:
  • Cuando un usuario hace un commit a la transaccion
  • Cuando sucede un cambio (log switch) de archivo de Redo Log
  • Cuando han pasado tres segundos desde la ultima escritura del LGWR hacia el Online Redo Log
  • Cuando el Redo Log Buffer esta 1/3 lleno o contiene mas de 1Mb de datos en el buffer.
  • Cuando el proceso DBWn necesita escribir datos del Database Buffer Cache hacia disco.
El proceso LGWR escribe a los archivos de Online Redo Log de manera circular, cuando el LGWR escribe en el ultimo archivo de Online Redo Log disponible, el LGWR se regresa a escribir al primer archivo de Online Redo Log.

Ahora que ya vimos que es , y como mencionabamos arriba, los Online Redo Logs, son unicamentes usados en el proceso de recuperacion de la base de datos.

En el proceso de recuperacion, se presenta tanto lo que es aplicar cambios cometidos no reflejados en los datafiles, a esto se le conoce como Roll Forward, y remover los cambios aplicados no cometidos de los datafiles, a esto se le conoce como Roll Back.

Suena un poco confuso, pero realmente no lo es, lo unico que hay que saber es que cuando se realiza un commit, Oracle añade un Marcador de Commit en el redo log buffer, asi es como Oracle sabe que datos son cometidos y cuales no.

Aqui un pequeño algoritmo de como es el proceso de recovery, este lo tome del blog de Arup Nanda, no me lo acredito, solamente lo estoy traduciendo:

Leer las entradas de tipo Redo Log, empezando con el mas antiguo
Verificar el numero SCN del Cambio
Buscar el Marcador de Commit.
Si el marcador es encontrado, entonces los datos han sido cometidos.
Si es encontrado, entonces buscar los cambios en los datafiles (via el numero SCN)
    ¿Cambios estan reflejados en los datafiles?
    Si si, entonces brinca
    Si no,aplicar los cambios a los datafiles (Roll Forward)
Si no es encontrado,entonces los datos estan sin cometer,buscar los cambios en los datafiles
    ¿Cambios estan reflejados en los datafiles?
    Si no, entonces brinca
    Si si, entonces hacer un update a los datafiles con los datos antes del cambio (Roll Back)

Para ver la informacion que tiene los redo logs, puedes hacer una sesion de logminer, que eso lo veremos en otra entrada, pero por el momento te esneño un ejemplo de la informacion que puedes ver.

En una sesion con el el usuario HR, voy a crear una tabla llamada BLAH, y voy ver la informacion de la transaccion, una vez que veo esta informacion voy a darle commit para finalizar la transaccion.

TESTDB >create table blah( name varchar2(100), num number);

Table created.

TESTDB >insert into "HR"."BLAH"("NAME","NUM") values ('Texto Nada Mas Probar Que Inserto','60671');

1 row created.

TESTDB >select dbms_transaction.local_transaction_id from dual;

LOCAL_TRANSACTION_ID
--------------------------------------------------------------------------------
47.30.24303

TESTDB >commit;

Commit complete.

Ahora uso la utileria de log miner para poder ver esta informacion del redo log utilizando el XID de la transaccion de arriba, y aqui podemos ver la informacion del SQL_REDO y SQL_UNDO

column sql_redo format a30 word_wrapped
column sql_undo format a30 word_wrapped
column seg_owner format a12
select seg_owner,SQL_REDO,SQL_UNDO FROM V$LOGMNR_CONTENTS where XIDUSN=47 and XIDSLT=30 and XIDSQN=24303

SEG_OWNER SQL_REDO SQL_UNDO
------------ ------------------------------ ------------------------------
set transaction read write;
HR insert into delete from "HR"."BLAH" where
"HR"."BLAH"("NAME","NUM") "NAME" = 'Texto Nada Mas
values ('Texto Nada Mas Probar Que Inserto' and "NUM"
Probar Que Inserto','60671'); = '60671' and ROWID =
'AAATuqAAEAAAA+YAAA';

commit;

Conclusion
Espero que con esta pequeña informacion de lo que es un Redo Log y con la entrada anterior de lo que es un registro tipo undo puedas ver la diferencia entre ambos y su uso especifico de estos.

miércoles, 16 de marzo de 2011

Clonar con RMAN una Base de Datos sin conexion al Catalogo y a la Base de datos de Origen

Uno de las tareas comunes y a veces repetitivas que tenemos para los usuarios de desarrollo, es la necesidad de clonar una base de datos de produccion hacia una de desarrollo, pero uno de los problemas que presentaba el comando DUPLICATE de rman era que para poder hacerlo tenias que tener una conexion a la base de datos origen (TARGET DATABASE) , que pasaba si por consecuencias del destino no tenias o no podias conectarte a esta base de datos, realmente te ponia en una situacion en donde te las tenias que ingeniar para poder clonar tu base de datos.

En la version de 11gR2 puedes clonar tu base de datos sin que tengas que conectarte a la base de datos origen y tampoco al catalogo, solamente con que tengas acceso al respaldo es mas que suficiente, claro tomando en cuenta de que es un respaldo consistente y que tambien se hayan respaldado los archive logs, para un ejemplo de como hacer un respaldo lo puedes encontrar en nuestra entrada  Respaldos con RMAN - Parte I .Vamos a ver como se hace

Para empezar tenemos que asegurarnos que el respaldo sea visible en el servidor donde se encuentra la base de datos auxiliar (AUXILARY DATABASE), ya sea copiando los archivos del servidor donde se encuentra al servidor de la base de datos auxiliar o por un NFS share.

El siguiente paso es asegurarnos que tenemos todas nuestras variables de ambiente definidas para la base de datos auxiliar, como ORACLE_HOME,ORACLE_SID, ORACLE_BASE, y cualquier otra variable que use tu auxiliar.

Importante, la siguiente variable de ambiente tiene que estar presente, ya que si no te puedes enfrentar al Bug 1300348.1 (Recovery Time For Rman Duplication Does Not Match Specified Until Time Clause). En donde lo que sucede es se trunca la fecha y es como si fueran las 00:00 hrs de la fecha a la que vas a hacer la recuperacion.

NLS_DATE_FORMAT='DD-MON-YYYY HH24:MI:SS'
export NLS_DATE_FORMAT


Tambien tenemos que definir nuestro archivo de parametros init_AUXILIAR_BD.ora (pfile). Puedes tomar como ejemplo el archivo de parametros de la base de datos Origen, asegurandote que el parametro db_name= AUXILIAR_BD y control_files = DIRECTORIO_CTL_AUXILIAR_BD

Asegurate de que $ORACLE_HOME/bin se encuentre en el PATH tambien
ejemplo
export PATH=$ORACLE_HOME/bin:$PATH


Ahora vamos a copiar el archivo de password de la base de datos origen a nuestra auxiliar, este archivo se encuentra en $ORACLE_HOME/dbs para unix o $ORACLE_HOME/database para windows, lo puedes encontrar con el nombre de orapwNOMBRE_BD.

Una vez que hayamos completado los pasos anteriores,vamos a crear el archivo spfile del pfile initAUXILIAR_BD.ora que configuramos arriba y vamos a arrancar la base de datos auxiliar en modo nomount

oracle $ sqlplus

SQL*Plus: Release 11.2.0.2.0 Production on Thu Mar 17 01:00:23 2011

Copyright (c) 1982, 2010, Oracle. All rights reserved.

Enter user-name: /as sysdba

Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - 64bit Production
With the OLAP, Data Mining and Real Application Testing options

TESTDB >create spfile from pfile='/mount/dba01/oracle/TESTDB/pfile/initTESTDB.ora';

File created.

TESTDB >startup nomount
ORACLE instance started.

Total System Global Area 3658891264 bytes
Fixed Size 2163680 bytes
Variable Size 1392516128 bytes
Database Buffers 2248146944 bytes
Redo Buffers 16064512 bytes

TESTDB >exit

Ahora vamos a crear el script de rman para hacer la clonacion, que te puedes ayudar del siguiente query, corriendolo en la base de datos origen para hacer los cambios de directorio, este lo utilizo en Unix

SELECT 'set newname for datafile '
|| a.file#
|| ' to ''&aux_data_mnt'
|| SUBSTR (a.NAME, INSTR (a.NAME, '/', -1, 1) + 1)
|| ''';'
FROM v$datafile a, v$tablespace b
WHERE a.ts# = b.ts# and
a.file# IN (SELECT DISTINCT file#
FROM v$backup_datafile)
UNION ALL
SELECT 'set newname for tempfile '
|| a.file#
|| ' to ''&aux_data_mnt'
|| SUBSTR (a.NAME, INSTR (a.NAME, '/', -1, 1) + 1)
|| ''';'
FROM v$tempfile a;

Del resultado de query de arriba, voy a construir el script de rman, llamado clone_TESTDB.rmn, toma en cuenta que nos vamos a conectar a la base de datos auxiliar, asi que tenemos que alojar los canales auxiliares.

RUN
{
ALLOCATE AUXILIARY CHANNEL CH1 TYPE DISK ;
ALLOCATE AUXILIARY CHANNEL CH2 TYPE DISK ;
ALLOCATE AUXILIARY CHANNEL CH3 TYPE DISK ;
set newname for datafile 1 to '/mount/u01/oracle/TESTDB/data/system01.dbf';
set newname for datafile 2 to '/mount/u01/oracle/TESTDB/data/sysaux01.dbf';
set newname for datafile 3 to '/mount/u01/oracle/TESTDB/data/def01.dbf';
set newname for datafile 4 to '/mount/u01/oracle/TESTDB/data/undorbs1_1.dbf';
set newname for tempfile 1 to '/mount/u01/oracle/TESTDB/data/temp01.dbf';
DUPLICATE DATABASE TO TESTDB
UNTIL time "to_date('12-MAR-201112:57:29','dd-MON-yyyyhh24:mi:ss')"
BACKUP LOCATION '/mount/copy01/SOURCEDB'
logfile
group 1 (
'/mount/u01/oracle/TESTDB/log/redo01g01.log',
'/mount/u01/oracle/TESTDB/log/redo02g01.log'
) size 50M,
group 2 (
'/mount/u01/oracle/TESTDB/log/redo01g02.log',
'/mount/u01/oracle/TESTDB/log/redo02g02.log'
) size 50M,
group 3 (
'/mount/u01/oracle/TESTDB/log/redo01g03.log',
'/mount/u01/oracle/TESTDB/log/redo02g03.log'
) size 50M
;
}

Si te fijas en el script, la clave se encuentra en la seccion del comando DUPLICATE,
DUPLICATE DATABASE TO TESTDB
UNTIL time "to_date('12-MAR-201112:57:29','dd-MON-yyyyhh24:mi:ss')"
BACKUP LOCATION '/mount/copy01/SOURCEDB'
Ya que no estamos diciendo que sea el duplicado directamente de la base de datos TARGET, sino que estamos diciendole a rman donde se encuentra nuestro respaldo. Algo que debes saber es que cuando clonas una base de datos sin conexion al catalogo y a tu base de datos origen, la unica clausula UNTIL que puedes usar es TIME, no puedes usar SCN o SEQUENCE.
Ahora si ya estas listo para hacer la clonacion, conectate con la utileria de rman en la base de datos auxiliar, y corre el script creado arriba

oracle $ rman auxiliary /

Recovery Manager: Release 11.2.0.2.0 - Production on Thu Mar 17 02:38:44 2011

Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved.

connected to auxiliary database: TESTDB (not mounted)

RMAN>@clone_TESTDB.rmn

Conclusion

Esta nueva manera de hacer una clonacion, ta va a ayudar a mitigar errores, ya que no es necesario conectarte a la base de datos de origen, y de la misma manera, si la base de datos origen no esta disponible, vas a poder clonar tu base de datos.

jueves, 10 de marzo de 2011

Tratas de conectarte como sysdba y no puedes por el error Ora-12547

Aqui de regreso al blog, les pido mil disculpas por no actualizarlo en el ultimo mes, pero estuve viajando y a su vez en un proceso de upgrade a 11.2.0.2 muy pesado. Tocando el tema de este upgrade, ando desarrollando unos scripts en donde tengo que hacer un clon de la base de datos en vivo, esto es sin la nueva funcionalidad de RMAN en 11g.

Haciendo pruebas con este script que les platico, en pruebas, acabe borrando todos los datafiles, controlfiles y redologs!!! Esto si que es preocupante si fuera la base de datos de produccion, pero como era una de pruebas, no pasa nada, el problema surgio cuando tratando de recrear la base de datos, no me dejaba conectarme ni como sysdba, marcando el error ORA-12547.

oracle $ sqlplus

SQL*Plus: Release 11.2.0.2.0 Production on Thu Mar 10 22:39:43 2011

Copyright (c) 1982, 2010, Oracle. All rights reserved.

Enter user-name: /as sysdba
ERROR:
ORA-12547: TNS:lost contact

Cual es mi sorpresa que al buscar informacion de los procesos de la base de datos en mi servidor, veo que ninguno esta corriendo

ejemplo
oracle $ ps -eaf | grep TESTDB | grep -v "grep" | wc -l
       0

Despues de unos cuantos dolores de cabeza tratando de averiguar que fue lo que me estaba impidiendo acceder desde sqlplus a mi instancia, por cierto teniendo todas las variables de ambiente correctas, me di cuenta de que los segmentos de memoria compartida y los semaforos en Unix seguian presentes.

Oracle en 9i,10g y 11g trae una utileria llamada sysresv que nos permite saber que semaforos y segmentos de memoria compartida esta siendo utilizada por nuestra instancia.

$ORACLE_HOME/bin/sysresv

Una vez que corri e identifique los segmentos de memoria compartida y los semaforos que estaban presentes para mi instancia

oracle $ $ORACLE_HOME/bin/sysresv

IPC Resources for ORACLE_SID "TESTDB" :
Shared Memory:
ID KEY
1073741917 0xfc4002bc
Semaphores:
ID KEY
2130706467 0x0b90e3f0
67108901 0x0b90e3f1
1711276072 0x0b90e3f5
1543503922 0x0b90e3f6
1828716596 0x0b90e3f7
Oracle Instance not alive for sid "TESTDB"

Me di a la tarea de removerlos con el comando "ipcrm", de las siguientes dos maneras, toma en cuenta que mi prompt en unix es "oracle $"

oracle $ ipcrm -m [shared_memory_ID]

oracle $ ipcrm -s [semaphore_ID]

Ahora si, despues de que los segmentos de memoria y semaforos no estaban presentes, pude acceder a sqlplus sin ningun problema, pudiendo arrancar mi instancia sin ningun inconveniente

oracle $ sqlplus

SQL*Plus: Release 11.2.0.2.0 Production on Thu Mar 10 23:07:51 2011

Copyright (c) 1982, 2010, Oracle. All rights reserved.

Enter user-name: /as sysdba
Connected to an idle instance.

TESTDB> startup nomount
ORACLE instance started.

Total System Global Area 2088402944 bytes
Fixed Size 2159904 bytes
Variable Size 721423072 bytes
Database Buffers 1342177280 bytes
Redo Buffers 22642688 bytes
TESTDB>

Conclusion
Espero que este pequeño ejemplo les ayude cuande se les presente esta situacion, aunque no es algo que sucede seguido, cuando sucede puede ser un dolor de cabeza arreglarlo y atacarlo.