jueves, 22 de abril de 2010

¿Que es un SEGMENTO de Oracle?

Segmentos de datos y temporales

. Introducción

Un segmento almacena la información de una estructura lógica de Oracle dentro de un Tablespace. Está formado por una o más extensiones y, a medida que va creciendo el segmento se van asignando nuevas extensiones al mismo. Hay cuatro tipos de segmentos: de datos, de índices, temporales y de rollback.

. Segmentos de datos e índices

En un segmento de datos se almacenan todos los datos de una tabla que no esté particionada o que no forme parte de un cluster, de una partición de una tabla particionada o, de un cluster de tablas. Se crea el segmento de datos a la hora de ejecutar la sentencia create que crea la tabla, cluster o partición. En dicha sentencia se indican también los valores de la cláusula storage, que se han explicado en el capítulo que hace referencia a las extensiones, y va a determinar la forma en que dicho segmento va a ir asignando y desasignando las extensiones.

En el caso de los índices, existe un segmento para cada índice no particionado o para cada partición de un índice particionado. Al igual que con las tablas, los segmentos de índices se crean al ejecutar la sentencia de creación de índices en la cual, también se pueden indicar valores para la cláusula storage y así parametrizar la forma en que se le asignarán las extensiones a medida que vaya creciendo.

. Segmentos temporales

Cuando Oracle procesa las consultas se puede ver en la necesidad de utilizar espacio en disco para poder llevar a cabo algunas partes del parsing (análisis) y de la ejecución de la misma. Solamente utilizará este tipo de segmentos cuando no pueda realizar la consulta íntegramente en memoria o cuando no pueda buscarse un método alternativo para realizarla utilizando los índices.

Hay varios tipos de sentencias en las que Oracle se ve en la obligación de utilizar los segmentos temporales:

SELECT ... ORDER BY.
CREATE INDEX.
SELECT ... GROUP BY.
SELECT ... UNION ...
SELECT DISTINCT ...
SELECT INSERSEC ...
SELECT MINUS ...

Se puede dar el caso en el que algunas consultas en las que intervengan joins en los que no haya índices que faciliten la unión y en las que se den a la vez sentencias del tipo "group by" y "order by" o incluso "distinct", en las que no solo se requiere de un nuevo segmento temporal sino que pueden adquirirse dos segmentos para poder realizar dichas consultas.

Como es natural, cuantas más operaciones se hagan en memoria mejor será el rendimiento del sistema, por lo que si en nuestra aplicación existe un número considerable de consultas de las mencionadas anteriormente, resulta muy apropiado hacer un tunning para decidir si ampliar la zona de memoria reservada para las ordenaciones, aumentando el valor del parámetro SORT_AREA_SIZE.

En Oracle también existen las tablas temporales y los índices temporales para dichas tablas. Estos objetos tambíen utilizan segmentos temporales, pero se les asigna y desasigna de forma diferente a como se hace con las consultas, creación de índices y ordenaciones.

. Asignación de segmentos temporales en consultas.

En las consultas, los segmentos temporales se van asignando según se van necesitando y, al terminar la ejecución de la sentencia, se desasignan. Para determinar en qué tablespace se van a crear los segmentos temporales necesarios para estas consultas, a cada usuario de la base de datos, se le asigna un tablespace para dicha función. Esto se realiza con el siguiente comando:

Alter user nombre_de_usuario default tablespace nombre_tablespace_temporal;

Por defecto, en la creación del usuario también se le puede asignar un tablespace temporal y, si no se le indica, el sistema le asigna por defecto siempre el tablespace SYSTEM. Es muy importante que ningún esquema o usuario tenga como tablespace temporal el SYSTEM por varios motivos. En primer lugar, porque SYTEM no es un tablespace temporal y por lo tanto, no está optimizado para la gestión de los segmentos temporales, en segundo lugar, al utilizar SYSTEM como tablespace temporal, se aumenta la fragmentación de dicho tablespace por culpa de los segmentos temporales que se van creando y borrando en medio de segmentos de datos e índices con lo que disminuye drásticamente el rendimiento del tablespace principal de la base de datos, y por último, se corre el peligro de que se llene este tablespace por culpa de alguna select mal escrita y que se descontrole aumentando desproporcinadamente el tamaño del segmento temporal creado para ejecutarla.

. Asignación de segmentos temporales para tablas temporales

El segmento requerido para una tabla temporal y para sus índices temporales se asigna en el momento de producirse la primera insert en dicha tabla. Este segmento al igual que en el caso anterior, se creará en el tablespace temporal del usuario que está creando la tabla temporal. Para conocer el tablespace por defecto de un usuario y su tablespace temporal, podemos consultar la vista dba_users.

Select username, default_tablespace, temporary_tablespace from dba_users;

La explicación del funcionamiento de las tablas temporales excede los objetivos de este manual por lo que no se va a profundizar más en ellas, simplemente se indicará aquí que la eliminación del segmento temporal que se ha creado se hará dependiendo del tipo de tabla temporal que se ha creado. Cuando la tabla temporal es específica para una transacción, Oracle eliminará el segmento creado al finalizar dicha transacción, y si por el contrario, la tabla es específica para la sesión, su segmento se eliminará al terminarse esta sesión.

Segmentos de Rollback

. Introducción

En cada base de datos Oracle tenemos uno o más segmentos de rollback en los que se almacena la información que ha sido cambiada por las transacciones. Estas transacciones pueden ser definitivas, es decir, se ha realizado ya el commit de ellas, o puede que aún no se haya hecho dicho commit. Este tipo especial de segmento se utiliza principalmente para poder realizar una lectura consistente de la base de datos Oracle mientras se están modificando los datos y para poder llevar a cabo las recuperaciones de la base cuando ésta cae por algún motivo.

La información de un segmento de rollback se almacena en las llamadas entradas de rollback. En estas entradas se detalla en qué datafile estaba el dato que ha sido modificado, en qué bloque dentro de dicho datafile y también el dato viejo que se ha modificado en la transacción. Además, todas las entradas de rollback de una misma transacción están encadenadas unas con otras para que así, si se deben deshacer los cambios llevados a cabo en esa transacción, resulta más fácil de encontrarlos todos.

Las vistas más importantes de las que podemos extraer información sobre los segmentos de rollback son: v$rollname, dba_rollback_segs y v$rollstat.

En una base de datos Oracle, se guardan todos cambios en los bloques modificados en una estructura llamada "logs de rehacer" o, "redo logs". Cuando se crea una nueva entrada de rollback en un segmento de rollback, realmente se está modificando un bloque que se encuentra en dicho segmento de rollback con la información de dicha entrada, por lo que este cambio también se almacena en los log de rehacer. Este doble almacenamiento de la información que se guarda en los segmentos de rollback y en los log de rehacer es fundamental para poder realizar un buen proceso de recuperación de la base de datos en caso de que se produzca en fallo en ella. Cuando se produce una caída de la base de datos, en el momento de la recuperación, se recupera el estado de los segmentos de rollback tanto con las transacciones que ya se habían terminado como con aquellas transacciones cuyo commit aún no se había realizado. El siguiente paso que se produce es el rollback de todas aquellas transacciones que se encuentran en los segmentos de rollback y para las cuales no se había completado el commit.

. Utilización de los segmentos de rollback

Como se ha indicado anteriormente, los segmentos de rollback se utilizan para poder deshacer los cambios de las transacciones para las que no se ha hecho un commit y para asegurar la consistencia de lectura. Para facilitar estas tareas, Oracle guarda por cada bloque una tabla de las transacciones que en cada momento se están ejecutando en el mismo. Además, por cada transacción, por cada nuevo cambio que se realiza en los bloques de datos se crea una entrada de rollback que se encadena a las anteriores entradas de rollback asignadas a esa misma transacción de forma ordenada.

Gracias a este sistema, cada vez que se desea restaurar el estado de una transacción al realizar el rollback de la misma, simplemente se debe detectar en qué bloque del segmento de rollback se está almacenando los cambios producidos por dicha transacción mirando en las tablas de transacciones de los bloques del segmento de rollback y, una vez detectado el bloque, se deben seguir una a una las entradas de rollback de la transacción que se encuentran ordenadas y encadenadas, para ir restaurando los valores antiguos en los bloques de datos de forma ordenada.

De la misma manera, se utiliza para facilitar la lectura consistente ya que se detecta el valor antiguo de los bloques navegando por la cadena de las entradas de rollback de la transacción.

¿Cómo se asignan las transacciones a los segmentos de rollback?.

Cada vez que comienza una nueva transacción, se asigna a un determinado segmento de dos formas diferentes:

  • Se asigna la transacción al siguiente segmento de rollback que se encuentre libre en ese momento de manera automática. Solamente se asigna una transacción cuando se realiza una instrucción de DDL o de DML que no sea una select.
  • También se puede asignar una transacción a un segmento de rollback en concreto de forma manual. De esta forma, se puede asignar a un segmento de rollback grande una transacción que conocemos de antemano que modifica un gran volumen de datos. Una vez finalizada la transacción, Oracle vuelve a asignar la siguiente de manera automática al primer rollback que encuentra libre. La instrucción es la siguiente: Set transaction use rollback segment nombre_segmento_rollback;

Cuando se finaliza una transaccion, Oracle libera la información de rollback aunque no la destruye, esto es para soportar la lectura consistente de consultas que han comenzado antes de que se realizara el commit. Para asegurarse que la información se encuentra en los segmentos de rollback el mayor tiempo posible para estas consutas sin borrarla, Oracle va asignando las extensiones a los segmentos de rollback de manera secuencial y, cuando se ha llenado el segmento, se reutilizan las extensiones empezando nuevamente por la primera, como si fuera un segmento circular.

Un segmento de rollback puede tener asignadas solamente un número fijo de transacciones como máximo. Oracle se encarga de asignar las transacciones de una instancia de manera que todos los segmentos tengan el mismo número de transacciones aproximadamente, sin tener en cuenta el tamaño de las mismas ya que, de antemano no lo puede conocer. El número de transacciones que puede contener cada segmento de rollback depende del tamaño del bloque.

. Asignación de extensiones

Como hemos indicado anteriormente, un segmento de rollback debe tener al menos dos extensiones y cada una de sus extensiones está formada por un número determinado de bloques. A continuación vamos a explicar cómo se organizan las transacciones en los segmentos de rollback.

En un segmento de rollback pueden estar realizándose a la vez varias transacciones. Estas transacciones pueden estar escribiendo en distintas extensiones o incluso en la misma. Sin embargo, en un bloque de una extensión solamente puede contener información de una transacción, es decir, que no pueden escribir dos transacciones en el mismo bloque de la misma extensión a la vez. Además, como hemos indicado que la escritura de transacciones es secuencial, en cada momento una transacción escribe en una sola extensión. Cuando una transacción se queda sin espacio para escribir en la extensión en la que estaba, puede hacer dos cosas, bien reutilizar una extensión que ya estaba asignada al segmento o bien requerir una nueva extensión para el segmento de rollback.

La primera transacción que necesita más espacio nuevo chequea la siguiente extensión del segmento de rollback, y si no contiene información de transacciones activas, la adquiere. A partir de ese momento, todas las demás transacciones que necesiten espacio utilizarán esta extensión. Si, nuevamente se llena esta extensión y alguna transacción sigue necesitando espacio libre, Oracle vuelve a comprobar si en la siguiente extensión que le toca ocupar, siguiendo el orden secuencial y circular de asignación de extensiones, no se están realizando transacciones activas (insistimos en la naturaleza circular de los segmentos de rollback que, una vez ocupada la última extensión, vuelve a intentar ocupar la primera como si formaran todas un anillo).

Como estamos viendo, Oracle mantiene un anillo formado por las extensiones que ha ido adquiriendo este segmento de rollback y siempre intenta reusar una de las extensiones que lo forman antes que adquirir una nueva del sistema. Si en algún momento Oracle necesita utilizar una extensión y, en todas los que forman parte del anillo se están escribiendo transacciones activas, se ve obligado a adquirir una nueva extensión del sistema y a añadirla al anillo del segmento de rollback para seguir escribiendo. El número máximo de extensiones que pueden formar parte de un segmento de rollback viene determinado por una parámetro definido en el initSID.ora y que es MAXEXTENTS.

Ya hemos visto cómo se asignan extensiones a un segmento de rollback, pero ¿cómo se van desasignando?.

Al borrar un segmento de rollback, todas las extensiones que tenía asignadas el segmento se devuelven al tablespace y pueden ser utilizadas por el resto de objetos que pertenecen al tablespace. Existe otra manera de devolver el espacio utilizado por un segmento sin tener que eliminarlo. A la hora de crear un segmento de rollback se puede indicar un valor en el parámetro OPTIMAL de la cláusula storage que representa el tamaño óptimo de dicho segmento en bytes. Cada vez que Oracle necesista una nueva extensión para el segmento de rollback, compara el tamaño que tiene dicho segmento con el valor del parámetro optimal y, si lo ha sobrepasado, irá devolviendo al tablespace las extensiones más antiguas que se va encontrando en las que ya no quedan transacciones activas ya que, son las que menor probabilidad tienen de tener datos necesarios para mantener la consistencia de lectura. Si puede, liberará tantas extensiones como para quedarse con un tamaño aproximado al indicado en optimal pero siempre por encima.

El valor del parámetro óptimal nuca podrá ser menor que el espacio necesario para la creación del segmento, en el que participan el parámetro initial_extent, next_extent, y min_extents (recordemos que pct_increase no tiene sentido en los segmentos de rollback, todas las extensiones deben ser iguales). Para consultar los valores de estos parámetros podemos utilizar la vista dba_rollback_segs de la siguiente forma:

Select segment_name, initial_extent, next_extent, min_extents, max_extents
from dba_rollack_segs;

Y para conocer si nuestros rollback segments tiene asignado un tamaño óptimo:

Select name, optsize from v$rollname, v$rollstat
where v$rollname.usn = v$rollstat.usn order by 1;

. Estados de un segmento de rollback

Un segmento de rollback puede encontrarse en un determinado estado dependiendo de cada momento. Los estados en los que puede encontrarse son:

  • OFFLINE: No ha sido adquirido por ninguna instancia de la base de datos.
  • ONLINE: Ha sido adquirido por alguna de las instancias y puede contener datos de transacciones activas.
  • NEEDS RECOVERY: Contiene datos de transacciones que no se pueden hacer rollback porque sus datafiles están inaccesibles o corruptos.
  • PARTLY AVAILABLE: Contiene información de una transacción "en duda" que son transacciones en entornos de base de datos distribuidas de las que aún no se ha recibido respuesta.
  • INVALID: Ha sido borrado.

Esta información se puede obtener de la vista dba_rollback_segs. Las causas por las que un segmento puede pasar de un estado a otro son las siguientes:

Estado Inicial Estado Final Motivo
OnlineOfflineSe pone el segmento de rollback offline con la instrucción alter rollback segment nombre_segmento offline.
OfflineOnlineSe pone el segmento de rollback online con la instrucción alter rollback segment nombre_segmento online.
OfflineInvalidAl borrar el segmento de rollback
OnlinePartly AvailableCuando falla la red y hace que una transacción distribuida quede "en duda".
Partly AvailableOnlineSe resuelve la transacción "en duda".
Partly AvailableOfflineNo se resuelve la transacción "en duda".
Partly AvailableNeeds RecoveryCuando un fallo del medio hace inaccesible la transacción "en duda".
OnlineNeeds RecoveryCuando un fallo del medio hace inaccesibles los datafiles o cuando el segmento está corrupto.
Needs RecoveryOfflineSi se soluciona satisfactoriamente la recuperación del medio.
Needs RecoveryInvalidSi se borra el segmento de rollback

Los estados de Partly Available y Needs recovery son prácticamente iguales. En ambos el segmento contiene información de transacciones que no han sido resueltas. En un estado Partly Available, las transcciones distribuidas no han sido resueltas por culpa de un fallo en la red mientras que en el estado de Needs Recovery, las transacciones no han sido resueltas por un fallo del medio o por estar corrupto el propio segmento.

Una diferencia entre ambos estados es que un adminstrador o el propio Oracle puede poner un segmento Partly Available en estado Online, mientras que un segmento que necesita Recovery, primero debe pasar a estado Offline y luego Online. Además, un segmento en estado Needs Recovery puede ser borrado por el administrado para eliminarlo si estaba corrupto, sin embargo, no se puede borrar un segmento Partly available, primero se debe resolver la transacción en duda.

No hay comentarios:

Publicar un comentario