Entendiendo sweep y garbage collection

9 comentarios

Como habíamos visto en este artículo:

https://firebird21.wordpress.com/2013/06/14/la-arquitectura-mga/

cuando se actualiza (UPDATE) o se borra (DELETE) un registro el Firebird guarda en la Base de Datos la versión anterior de ese registro. ¿Para qué hace eso? Para poder revertir al registro original cuando se hace un ROLLBACK.

Un ROLLBACK se hace si ocurrió un error o si el usuario cambió de idea y no quiere guardar lo último que hizo, o si se cerró anormalmente la conexión.

Por lo tanto, cada comando UPDATE y cada comando DELETE le agrega un registro a la tabla respectiva (en el caso del DELETE el nuevo registro solamente tiene un marca que le indica al Firebird que ese registro está “borrado”).

Veamos un ejemplo de UPDATE:

El precio de “Televisor Toshiba de 20 pulgadas” es de 120 dólares. Como se está vendiendo poco ya que la mayoría de la gente ahora prefiere televisores de más pulgadas se decidió disminuir su precio a 100 dólares, tratando de conseguir que aumenten las ventas al disminuir el precio.

Entonces, en nuestra tabla de PRODUCTOS, luego del correspondiente UPDATE, tendríamos:

SWEEP1

Captura 1. Si haces clic en la imagen la verás más grande

Ahora hay dos posibilidades:

  1. Que la transacción termine con un COMMIT exitoso
  2. Que la transacción termine con un ROLLBACK

Si la transacción terminó con un COMMIT exitoso entonces el registro antiguo, el que tiene el TID 143 ya no sirve, es inútil. Pero el Firebird no lo elimina de la Base de Datos, lo deja ahí. Y eso implica que está ocupando espacio inútilmente.

Si la transacción terminó con un ROLLBACK entonces el registro nuevo, el que tiene el TID 279 ya no sirve, es inútil. Pero el Firebird no lo elimina de la Base de Datos, lo deja ahí. Y eso implica que está ocupando espacio inútilmente.

De lo anterior se deduce que cada vez que escribes el comando UPDATE dejas un registro inservible dentro de la Base de Datos. O el original queda inservible o el actualizado queda inservible.

Hay por lo tanto dos tipos de registros inservibles:

  • Los dejados por los COMMIT
  • Los dejados por los ROLLBACK

¿Hay diferencia si el registro inservible fue dejado por un COMMIT o por un ROLLBACK?

Sí, la diferencia es que los registros inservibles dejados por los COMMIT pueden ser eliminados automáticamente durante la recolección de la basura (ver más abajo), en cambio los dejados inservibles por los ROLLBACK nunca son eliminados automáticamente.

¿Qué es la “basura”?

Esos registros inservibles, inútiles, que fueron dejados por los UPDATE o por los DELETE siguen ocupando espacio dentro de la Base de Datos, pero como ya son inservibles y totalmente inútiles se les llama “basura”.

¿Cuál es el problema con la basura?

Que ocupa espacio inútilmente dentro de la Base de Datos y por lo tanto ésta es más grande de lo que debería ser y además se vuelve cada vez más lenta.

¿Qué significa “garbage collection”?

En castellano: recolección de la basura. Cuando se recolecta la basura todos esos registros inservibles dejados por los COMMIT son eliminados permanentemente y definitivamente de la Base de Datos. Como consecuencia de ello, la Base de Datos queda con espacio reutilizable y además las operaciones dentro de ella (INSERT, UPDATE, DELETE, FETCH, SELECT) se realizan más rápidamente.

¿Cuándo se realiza la “garbage collection”?

Cada vez que un registro es “tocado” por un SELECT toda la basura relacionada con ese registro como consecuencia de los COMMIT es eliminada. En otras palabras, si al escribir un SELECT un registro está en el resultado obtenido entonces toda la basura relacionada con ese registro, producida por los  COMMIT, es eliminada.

Fíjate que solamente el SELECT elimina a la basura, los demás comandos: INSERT, UPDATE, DELETE, no la eliminan, la dejan así mismo como estaba.

¿Cuál es la forma más rápida de eliminar toda la basura de una tabla?

Escribir el comando:

SELECT
   COUNT(*)
FROM
   MiTabla

Lo que hace ese comando es contar la cantidad de registros que tiene la tabla pero para hacerlo debe recorrer la tabla desde el primer registro hasta el último registro porque el Firebird no guarda en alguna parte la cantidad de registros de la tabla. Por lo tanto, todos los registros de esa tabla están involucrados en el SELECT y por consiguiente en todos esos registros es recolectada la basura. Si la tabla tiene 12.000 registros entonces SELECT COUNT(*) recorre los 12.000 registros y el “garbage collection” elimina toda la basura que haya encontrado en cualquiera de esos 12.000 registros.

Recuerda que esta forma de eliminar a la basura solamente elimina a la basura que dejaron los COMMIT, la basura dejada por los ROLLBACK no se puede eliminar así.

¿Cuál es el problema con recolectar la basura usando SELECT?

Que para recolectar la basura de todas las tablas debes hacer SELECT COUNT(*) en todas las tablas o esperar que algún SELECT involucre a los registros que tienen basura. A veces, puede ocurrir que se hizo el UPDATE de un registro pero nunca se hizo un SELECT que involucre a ese registro y por lo tanto la basura que dejó el UPDATE permanece dentro de la Base de Datos.

Además, no te olvides que cuando se ejecuta un SELECT solamente se recolecta la basura que dejaron los COMMIT, la basura dejada por los ROLLBACK continúa allí.

¿Qué es el sweep?

El sweep (en castellano: barrido, de barrer con una escoba) es un proceso que recorre toda la Base de Datos y elimina toda la basura que se encuentra en ella, tanto la proveniente de los COMMIT como la proveniente de los ROLLBACK. Cuando el sweep finaliza la Base de Datos está bien limpia, sin basura.

¿Cuándo se realiza el sweep?

El sweep se puede realizar automáticamente o manualmente. Automáticamente es cuando lo inicia el propio Firebird y manualmente es cuando lo inicia un programa (por ejemplo: GFIX y GBAK pueden iniciar el sweep).

Sweep automático

Cada Base de Datos tiene una entrada denominada “sweep interval” o sea intervalo del sweep. Es un número de tipo INTEGER  y por lo tanto su valor puede estar entre 0 y 2.147.483.647. Por defecto su valor es 20.000.

Cuando la diferencia entre la OST y la OAT es mayor que el intervalo del sweep, se inicia el sweep. Por ejemplo:

OST = 45.201

OAT = 25.200

Sweep interval = 20.000

Diferencia = OST – OAT = 45.201 – 25.200 = 20.001

Como la diferencia es mayor que el intervalo del sweep, se inicia el sweep automático.

Si no se quiere realizar un sweep automático entonces el intervalo del sweep debe ser 0 (cero)

¿Cuál es el problema con el sweep?

Que este proceso de recorrer toda la Base de Datos y de eliminar toda la basura que hay en ella es lento, en algunos casos extremadamente lento y los usuarios se quejan de que todas las operaciones (INSERT, UPDATE, DELETE, FETCH, SELECT) se realizan muy despaciosamente. Y por supuesto podría ocurrir que el sweep automático se inicie cuando los usuarios están más apurados, más impacientes y por culpa del sweep todas sus transacciones son más lentas que una tortuga con tres patas. Es por lo tanto normal que el DBA (Administrador de la Base de Datos) ponga el intervalo del sweep en 0 (cero) y de esa manera realizará el sweep manualmente, en momentos en que nadie está usando la Base de Datos (o cuando muy pocos usuarios la están usando).

Pero …. a veces el DBA se olvida de que dejó el intervalo del sweep en cero y la Base de Datos se va volviendo cada vez más grande y más lenta por toda la basura que tiene acumulada.

En otras palabras, se necesita un DBA con cerebro, algo que no siempre se consigue.

Aprovechar el backup para hacer el sweep

Cuando haces un backup usando el programa GBAK tienes la opción de que también se haga el sweep de la Base de Datos. Esa es la opción por defecto y la recomendable. Así, cuando finaliza el programa GBAK puedes estar seguro de que el archivo de backup generado no tiene basura. Recuerda: la Base de Datos original continúa con toda la basura que tenía, el backup generado es el que no tiene basura.

Usando el programa GFIX para hacer el sweep

Una de las opciones de este programa nos permite pedirle que haga el sweep:

GFIX -sweep -user SYSDBA -password masterkey MiBaseDatos

Un pequeño “defecto” que tiene el programa GFIX es que no te avisa que finalizó exitosamente y eso confunde a los principiantes. O sea, si termina sin ningún mensaje significa que todo estuvo ok, si ocurrió algún problema entonces termina con un mensaje de error.

Conclusión:

El uso normal de la Base de Datos va dejando basura dentro de ella. Esa basura debe ser eliminada en algún momento porque de no eliminarse solamente causará que la Base de Datos tenga un tamaño mayor que el necesario y además que todas las transacciones sean más lentas de lo que deberían. La eliminación de la basura puede hacerse en forma automática (cuando el intervalo del sweep es mayor que cero y la diferencia entre la OST y la OAT es mayor que ese intervalo) o en forma manual (cuando el intervalo del sweep es cero y en ese caso hay que ejecutar el programa GFIX). También se elimina la basura cuando se hace un backup usando el programa GBAK y no se especifica la opción -garbage collection.

Artículos relacionados:

La arquitectura MGA

Entendiendo a las transacciones

Entendiendo a los identificadores de las transacciones

El índice del blog Firebird21

Introducción a las tareas de Administración

2 comentarios

Aunque una bien programada Base de Datos de Firebird prácticamente no necesita de mantenimiento y puede usarse 24/7 (o sea: durante las 24 horas, los 7 días de la semana) sin problemas, siempre hay algunas tareas que se deben realizar con ella. A la persona que realiza dichas tareas se la conoce como “Administrador de la Base de Datos” y puede ser una persona distinta del programador o desarrollador porque sus tareas son muy diferentes.

Las tareas del Administrador son las siguientes:

  • Elegir la versión del Firebird que se instalará
  • Instalar el Servidor del Firebird
  • Determinar el alias que tendrá la Base de Datos
  • Parametrizar el archivo FIREBIRD.CONF
  • Analizar las estadísticas de la Base de Datos
  • Realizar los backups y los restores

Por lo tanto, el Administrador debe conocer:

  • Las características de cada versión del Firebird
  • Las diferencias entre esas versiones
  • La arquitectura MGA
  • El significado de las estadísticas de la Base de Datos
  • Las ventajas y desventajas de cada manera de realizar los backups y los restores
  • Que es y como funciona la recolección de basura

Lo ideal es detectar los problemas potenciales que podrían ocurrir antes de que realmente ocurran, para evitar dolores de cabezas. Para eso es de una gran ayuda analizar las estadísticas porque ellas nos dirán que hace el Servidor y cuando.

La arquitectura MGA (multigeneracional) usa varias versiones de cada registro para que los lectores no interfieran con los escritores ni los escritores con los lectores. Gracias a esta arquitectura, si un usuario se arrepiente de lo que estaba haciendo o si se detecta un error, se puede regresar la Base de Datos al estado consistente anterior. Sin embargo, la arquitectura MGA tiene una desventaja: puede ser causa de un bajo rendimiento cuando las transacciones están mal programadas. Analizando las estadísticas se pueden encontrar esas malas transacciones.

Otra ventaja de la arquitectura MGA es que los usuarios pueden continuar trabajando mientras se realiza un backup. O sea que no es necesario realizar los backups durante la hora del almuerzo o a la medianoche, como con otros sistemas.

En el archivo de backup se copian las definiciones de los índices, pero no los índices. Cuando se realiza la restauración esos índices son regenerados y todos los parámetros de las transacciones son reiniciados.

Para obtener un mejor rendimiento, lo aconsejable es que el backup se realice en otra computadora. Para comprobar que se tiene un backup válido hay que verificar que la fecha y la hora de la Base de Datos original sean diferentes a la fecha y la hora del backup y también restaurar el backup en otra computadora. Si la restauración se realizó con éxito, entonces se puede confiar en esa copia.

El backup se puede automatizar, para que se realice todos los días a determinada hora (o inclusive, varias veces cada día). Esto puede hacerse mediante las “tareas programadas” del Windows o con programas especializados.

La recolección de basura depende de un correcto manejo de las transacciones. Lo que se recolecta son datos y páginas de índices y el Firebird puede realizar esa tarea automáticamente. Cuando se recolecta la basura:

  • Se limpia la Base de Datos
  • Se reorganiza el espacio de memoria
  • La limpieza se ejecuta en segundo plano, sin interferir con las operaciones de los usuarios

Si no se recolecta la basura, el rendimiento de la Base de Datos se irá degradando poco a poco, hasta que llegará el momento en que realizar cualquier operación con ella tomará demasiado tiempo.

Resumen de tareas administrativas

  • Ninguna tarea administrativa es requerida si la Base de Datos está bien programada
  • Si el manejo de las transacciones es el correcto, ninguna tarea de mantenimiento se necesita
  • La recolección de basura depende de un manejo correcto de las transacciones
  • La recolección de basura afecta a los datos y a las páginas de índices