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 |
| Online | Offline | Se pone el segmento de rollback offline con la instrucción alter rollback segment nombre_segmento offline. |
| Offline | Online | Se pone el segmento de rollback online con la instrucción alter rollback segment nombre_segmento online. |
| Offline | Invalid | Al borrar el segmento de rollback |
| Online | Partly Available | Cuando falla la red y hace que una transacción distribuida quede "en duda". |
| Partly Available | Online | Se resuelve la transacción "en duda". |
| Partly Available | Offline | No se resuelve la transacción "en duda". |
| Partly Available | Needs Recovery | Cuando un fallo del medio hace inaccesible la transacción "en duda". |
| Online | Needs Recovery | Cuando un fallo del medio hace inaccesibles los datafiles o cuando el segmento está corrupto. |
| Needs Recovery | Offline | Si se soluciona satisfactoriamente la recuperación del medio. |
| Needs Recovery | Invalid | Si 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.
Temas Relacionados
Relacionado directamente con este tema, se pueden estudiar también los siguientes temas:
- ¿Qué son los segmentos de rollback privados y públicos?.
- ¿Cómo se puede poner un segmento online u offline y en qué condiciones?.
- ¿Cómo borrar un segmento de rolback?.
- ¿Qué es un Shrink?.
- ¿Cómo se modifican los parámetros de un segmento de rollback?.
- ¿Cómo se consigue la consistencia de lectura?.
- ¿Cómo se lleva a cabo el rollback de las transacciones?.
- ¿Cuál es el proceso seguido en la recuperación de la base de datos?.