Usando Firebird durante 24/7/365

5 comentarios

Algunas aplicaciones requieren acceso a las bases de datos durante 24/7/365, o sea durante las 24 horas del día, los 7 días de la semana y los 365 días del año. En otras palabras: sin interrupción, por ningún motivo.

Algunos ejemplos típicos son:

  • Sanatorios, hospitales, centros de salud
  • Farmacias que trabajan las 24 horas
  • Estaciones de servicio (expendio de combustibles)
  • Policía
  • Fuerzas Armadas
  • etc.

Una aplicación desarrollada para ser utilizada por ellos tiene la obligación de poder funcionar sin interrupción en cualquier momento del día. No le puedes decir al Director de un hospital que entre las 22:00 y las 23:00 no pueden registrarse los datos de los pacientes porque hay que hacerle un mantenimiento a la Base de Datos. Ni decirle a un General que si mañana el país es atacado por el enemigo entre las 02:00 y las 03:00 entonces no podrá usar la Base de Datos porque ya tiene mucha basura y que hiciste un proceso para que elimine esa basura pero requieres que nadie esté conectado a la Base de Datos.

¿Y cuál es el problema?

El problema radica en que a las bases de datos de Firebird debe hacérsele una tarea de mantenimiento llamada sweep de vez en cuando. El sweep (barrido, en castellano) tiene como finalidad eliminar a todas las versiones inútiles de las filas que fueron modificadas o borradas. Cada vez que una fila es modificada o borrada se crea una versión de esa fila llamada delta. La parte positiva de esto es que puede realizarse un ROLLBACK y dejar a la fila como se encontraba anteriormente si el usuario cambió de idea. La parte negativa es que se va acumulando basura y todas las operaciones se van volviendo más lentas y por lo tanto esa basura debe ser eliminada alguna vez.

 Y el sweep puede demorar mucho tiempo.

¿Cuándo se inicia el sweep?

El sweep puede iniciarse automáticamente (que es su valor por defecto) cuando la diferencia entre la OST (Oldest Snapshot Transaction) y la OAT (Oldest Active Transaction) es mayor que el intervalo predefinido del sweep. Ese intervalo es de 20.000 por defecto pero puede modificarse.

Si el intervalo del sweep es de 0, entonces el sweep nunca se iniciará automáticamente. Eso implica que hay que iniciarlo manualmente. Para ello se usa el programa GFIX con la opción –sweep. En este caso lo recomendable es que nadie esté usando la Base de Datos mientras se realiza el sweep.

 ¿Qué ocurre cuándo se inicia el sweep?

Que la transacción que hizo iniciar al sweep no empezará hasta que el sweep finalice. Supongamos que el intervalo del sweep es de 20.000, entonces el desafortunado usuario que quiso iniciar una transacción cuando OST – OAT fue de 20.001 tendrá que esperar hasta que finalice el sweep antes de que su transacción pueda empezar. A quienes iniciaron sus transacciones antes que él no les afectará, pero a él sí. Y si justo es un General de muy malas pulgas, entonces…

 ¿Se puede evitar que se inicie el sweep sin perjudicar el rendimiento de la Base de Datos?

Sí.

La buena noticia es que si las aplicaciones que usan la Base de Datos están correctamente diseñadas entonces nunca será necesario realizar el sweep.

La basura que se encuentra dentro de una Base de Datos puede deberse a los siguientes motivos:

  • Una operación de UPDATE que finalizó con un COMMIT
  • Una operación de DELETE que finalizó con un COMMIT
  • Una operación de UPDATE que finalizó con un ROLLBACK
  • Una operación de DELETE que finalizó con un ROLLBACK

La basura dejada por las transacciones que finalizaron con un COMMIT es recolectada (garbage collection) automáticamente cuando se hace un SELECT a esas filas. Por lo tanto, para eliminar toda la basura de una tabla que fue dejada por los COMMIT se puede escribir un simple comando: SELECT * FROM MiTabla y listo: esa tabla ya no tendrá basura dejada por los COMMIT.

La basura dejada por el ROLLBACK sin embargo, solamente puede ser eliminada con un sweep.

Por lo tanto la solución es muy simple y muy sencilla: No usar ROLLBACK.

¿Y cómo se puede evitar usar ROLLBACK?

Hay varias alternativas posibles, una posible solución sería esta:

  • Haces un SELECT a la fila que te interesa, por supuesto finalizando ese SELECT con un COMMIT. El resultado de ese SELECT lo guardas en una tabla temporal que no es de Firebird, por ejemplo en una tabla .DBF
  • Le muestras la fila de la tabla .DBF al usuario
  • Le permites que cambie los campos o que borre la fila
  • Si decide Guardar los cambios, entonces haces un UPDATE a la tabla de Firebird con los valores que se ven en la pantalla y luego el COMMIT correspondiente
  • Si decide Cancelar los cambios, entonces allí termina todo, no tocas la tabla de Firebird para nada

Como ves, en estos casos se trabaja un poco más pero te aseguras que todas las transacciones terminen con un COMMIT.

Recolectando la basura

Adicionalmente, en tu aplicación deberías tener un proceso que se encargue de hacer un SELECT * a todas las tablas de tu Base de Datos. Cuando el usuario ejecuta ese proceso entonces se hace un SELECT * FROM MiTabla1, SELECT * FROM MiTabla2, SELECT * FROM MiTabla3, etc.

Recordatorio:

La técnica mostrada en este artículo es necesaria solamente para las bases de datos que deben estar activas durante 24/7/365. En los demás casos se puede seguir el procedimiento normal de hacer el sweep automáticamente o manualmente.

Conclusión:

Las bases de datos de Firebird pueden perfectamente ser usadas en entornos que las requieren abiertas durante las 24 horas, los 7 días de la semana y los 365 días del año. Lo que debemos tener en cuenta en esos casos es que deberíamos evitar el sweep porque el sweep puede demorar mucho tiempo en bases de datos muy grandes. La forma de evitar el sweep es nunca terminar las transacciones con ROLLBACK porque las transacciones que terminan con ROLLBACK dejan basura que solamente puede ser eliminada con un sweep, en cambio la basura dejada por las transacciones que terminan con un COMMIT puede ser eliminada con un comando SELECT * FROM MiTabla.

 Entonces, el problema es causado por la forma en que Firebird actúa cuando se hace un UPDATE o un DELETE que finalizaron con un ROLLBACK pero puede ser solucionado si la aplicación finaliza todas las transacciones con un COMMIT.

Artículos relacionados:

La arquitectura MGA

Entendiendo a las transacciones

Entendiendo a los identificadores de las transacciones

Entendiendo sweep y garbage collection

El índice del blog Firebird21

El foro del blog Firebird21

 

Anuncios

La Next Transaction después de un ciclo backup/restore

Deja un comentario

Como recordarás, al Firebird hay unas cuantas transacciones que le interesan, ellas son:

  • Oldest Transaction, representada por las letras OIT que significan Oldest Interesting Transaction
  • Oldest Active Transaction, representada por las letras OAT
  • Oldest Snapshot Transaction, representada por las letras OST
  • Next Transaction, representada por las letras NT

 Puedes leer más sobre ellas en este artículo:

Entendiendo los identificadores de las transacciones

Los números de las transacciones siempre van en aumento, hasta que se realiza un ciclo backup/restore.

¿Qué sucede cuándo se realiza un ciclo backup/restore?

 Que en la Base de Datos restaurada (no en la original, sino en la restaurada), el identificador de todas las transacciones que finalizaron con un COMMIT es puesto en 1.

¿Y por qué el número de la Next Transaction no es 2, ó 3, ó un número muy cercano a ellos?

Después de todo, podrías pensar que si todas las transacciones que finalizaron con un COMMIT tienen el identificador 1, la Next Transaction debería tener el número 2. O si el programa GBAK abre alguna transacción más, entonces un número muy cercano al 2. Pero no es así, la Next Transaction puede estar muy alejada del número 2.

La respuesta es que el programa GBAK puede abrir muchas transacciones cuando restaura una Base de Datos.

Ejemplo:

En la ventanita “Símbolo del sistema” escribimos el comando GSTAT -h para conocer los identificadores de las transacciones de una Base de Datos.

NT1

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

Se hace el ciclo backup/restore con la opción -v[erbose] y luego se ejecuta el comando GSTAT -h en la Base de Datos restaurada, obteniendo estos valores:

NT2

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

En la Captura 1. podemos ver los identificadores originales de las transacciones y en la Captura 2. podemos ver los valores de los identificadores en la Base de Datos restaurada. Y lo que llama la atención es que la Next Transaction es 304, un número aparentemente muy alto, muy alejado del 3 que uno podría esperar. ¿Por qué?

Porque el programa GBAK abre varias transacciones:

  • Al iniciar la restauración de la Base de Datos, la Next Transaction es puesta en 1
  • Luego, para restaurar los metadatos puede abrir nuevas transacciones
  • Si se usó la opción -o[nce] se iniciará una transacción por cada tabla restaurada
  • Si se usó la opción -v[erbose] se iniciará una transacción por cada índice restaurado

Entonces, ahora sí ya tiene sentido del por qué la Next Transaction está tan alejada del número 1. Es que el programa GBAK abre varias transacciones al restaurar un backup.

Fíjate en un detalle interesante. Como la Base de Datos restaurada aún no ha sido utilizada entonces no importa que los identificadores de las otras transacciones (OIT, OAT, OST) estén desfasados. En este momento nada significan y por lo tanto el número que tengan es irrelevante.

Sin embargo, si te conectas a la Base de Datos e inicias una transacción cuando te desconectes esos números sí ya estarán actualizados. Por ejemplo:

NT3

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

Aquí, usando el programa ISQL nos conectamos a la Base de Datos restaurada, salimos con un EXIT (al salir con un EXIT de ISQL se ejecuta automáticamente un COMMIT, si se sale con un QUIT entonces se ejecuta automáticamente un ROLLBACK) y volvemos a verificar los identificadores de las transacciones ¿y con qué nos encontramos?

Conque los identificadores OIT, OAT y OST se han actualizado.

Estos nuevos valores sí son los correctos. Los anteriores no tenían importancia porque aún no se había usado la Base de Datos, entonces eran irrelevantes sus valores.

Para verificar que la opción -v[erbose] realmente inicia varias transacciones se restauró la misma Base de Datos pero sin esa opción, y este fue el resultado obtenido:

NT4

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

Como puedes ver ahora la Next Transaction es solamente 84, entonces se comprobó que usando la opción -v[erbose] el programa GBAK inicia varias transacciones. Usando esa opción, Next Transaction fue 304, sin usarla fue 84. Desde luego que esos números variarán en tu caso porque dependen de la cantidad de índices que hayas definido.

Conclusión:

Al hacer un ciclo backup/restore con el programa GBAK, en la nueva Base de Datos el valor de la Next Transaction empieza con 1 pero como el programa GBAK abre varias transacciones para poder realizar sus tareas, entonces al finalizar la restauración el valor de la Next Transaction puede estar bastante alejado del 1, dependiendo de la cantidad de transacciones que el programa GBAK tuvo que abrir.

No importa cuales son los valores de los identificadores OIT, OAT, y OST al finalizar la restauración porque aún no han sido utilizados. Solamente después de finalizar la primera transacción sus valores serán actualizados y estarán muy próximos al de la Next Transaction.

Artículos relacionados:

Entendiendo los identificadores de las transacciones

El índice del blog Firebird21

El foro del blog Firebird21

Un ejemplo de transacciones mal administradas

Deja un comentario

En Firebird es extremadamente importante tener un buen manejo de las transacciones porque eso nos asegura que nuestra Base de Datos se encuentre en perfecto estado de salud.

Cuando no es así, se degrada el rendimiento porque el tamaño de la Base de Datos es mayor del que debería ser ya que está teniendo mucha basura dentro de ella y eso afecta a la velocidad con la cual se realizan las operaciones (SELECT, INSERT, UPDATE, DELETE, FETCH).

En este artículo habíamos visto el significado de los identificadores de las transacciones:

https://firebird21.wordpress.com/2013/09/08/entendiendo-los-identificadores-de-las-transacciones/

Podemos ver los valores actuales de esos identificadores usando el programa GSTAT y la opción -h, ejemplo:

C:\Archivos de Programa\Firebird\Firebird_2_5\bin>GSTAT -h MiBaseDatos

TRANSA01

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

En la Captura 1 tenemos un ejemplo de una Base de Datos muy bien administrada porque la diferencia entre los valores de Oldest transaction Oldest active Oldest snapshot es de 1 y la diferencia entre Oldest activeNext transaction también es de 1. Esa es la menor diferencia que podemos tener y nos indica que las transacciones de esta Base de Datos se encuentran en perfecto estado. Pero esa diferencia de 1 solamente podemos tenerla cuando nadie está usando la Base de Datos ya que mientras está en uso la diferencia casi siempre será mayor que 1 pero nunca debería ser más que 10 multiplicado por el número de usuarios. Es decir que si hay 16 personas usando la Base de Datos una diferencia mayor que 160 implicaría que algunas transacciones continúan activas cuando no deberían estarlo.

Aquí hay otro ejemplo:

TRANSA02

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

En la Captura 2 descubrimos que hay una diferencia significativa entre la OAT (Oldest Active Transaction) y Next transaction y nadie está usando la Base de Datos en este momento ¿Qué significa eso? que la transacción 3999 no finalizó ni con un COMMIT ni con un ROLLBACK, es por lo tanto una transacción “colgada” y debe ser corregida porque de no hacerlo se irá acumulando basura. En Oldest snapshot tenemos el número de la transacción más antigua cuya basura no puede ser recolectada automáticamente. O sea que toda la basura que dejaron las transacciones 3999 a 4196 no puede ser recolectada. Evidentemente cuanto mayor sea la diferencia entre Next transaction y Oldest snapshot mayor será el problema que tendremos con la basura.

La solución aquí es ejecutar un sweep manualmente, así:

GFIX -sweep -user SYSDBA -password masterkey MiBaseDatos

Al finalizar la ejecución de ese programa volvemos a verificar las estadísticas de la Base de Datos y esto es lo que obtenemos:

TRANSA03

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

¡¡¡Perfecto!!! Ahora sí la Base de Datos está sin basura y con los valores de los identificadores de las transacciones correctos.

Ejemplo de transacciones mal administradas

El motivo de escribir este artículo es que ví en Internet un mensaje de alguien pidiendo ayuda porque el sweep no le funcionaba. Los valores de los identificadores de sus transacciones eran los siguientes:

Oldest transaction  371932
Oldest active      1906983
Oldest snapshot    1906983
Next transaction   2696106

¿Qué podemos deducir mirando esos números?

  1. La transacción 371932 no finalizó con un COMMIT
  2. La transacción 1906983 no finalizó ni con un COMMIT ni con un ROLLBACK
  3. No se puede recolectar la basura que dejaron las transacciones 1906983 a 2696105
  4. Como la diferencia entre la Oldest active y la Next transaction es muy grande entonces es seguro que la aplicación que creó la transacción Oldest active (Contabilidad, Facturación, Ventas, Sueldos, etc.) ya se olvidó totalmente de ella y jamás le hará ni un COMMIT ni un ROLLBACK. Eso implica que hay que revisar la aplicación para descubrir por qué dejó una transacción activa y corregir ese problema (todas las transacciones deberían finalizar con un COMMIT o con un ROLLBACK, aún las que solamente hacen un SELECT)
  5. El sweep (barrido) solamente afectará a las transacciones del 1 al 371931. Toda la basura dejada por las transacciones 371932 a 2696105 no podrá ser eliminada ¿por qué no? porque si se la eliminara entonces la transacción 1906983 ya no tendría una visión estable de la Base de Datos
  6. Por lo tanto, la solución es buscar a la transacción 371932 y eliminarla. Y luego volver a intentar el sweep.
  7. Si el problema continúa entonces repetir el paso 6. para las siguientes Oldest transaction cuyos valores sean menores que Oldest active.

NOTA: Como la transacción 371932 no finalizó con un COMMIT entonces eliminarla no afectará al contenido de las tablas que tengamos en nuestra Base de Datos ya que el contenido de las tablas solamente es afectado por las transacciones que finalizan con un COMMIT.

Conclusión:

Periódicamente (una vez al día, una vez a la semana, una vez al mes, dependiendo de la cantidad de transacciones que tiene tu Base de Datos) deberías verificarla para comprobar que se encuentra en perfecto estado, de no ser así deberías tomar las medidas adecuadas para que lo esté.

Artículos relacionados:

Entendiendo los identificadores de las transacciones

Entendiendo sweep y garbage collection

El índice del blog Firebird21

Evitando conflictos cuando las transacciones superan el límite

1 comentario

Todas las transacciones tienen un número que las identifica, a ese número se le llama TID (Transaction Identificator).

TID es un número de tipo INTEGER, y los números de tipo INTEGER van desde el 0 hasta el 2 ^ 31 – 1, es decir desde 0 hasta 2.147.483.647

¿Y qué sucede cuándo se alcanzó el límite?

Si el número de tu última transacción es 2.147.483.647 el número de la siguiente transacción será 1, la cuenta se reinicia.

¿Y eso puede causar problemas?

Sí, porque habrá dos transacciones con el mismo TID, o sea que tendrás dos transacciones cuyo TID es 1. Y eso solamente puede provocar corrupción en tu Base de Datos.

¿Y cuál es la solución?

Hacer un ciclo backup/restore usando el programa GBAK antes de alcanzar el límite. Por ejemplo cuando el TID es 2.100.000.000 haces un ciclo backup/restore con GBAK y con eso conseguirás que en la Base de Datos restaurada (no en la original, sino en la que restauraste) se eliminen los TID de todas las transacciones. Por lo tanto:

  • Antes de que el número de la Next Transaction (siguiente transacción) llegue a 2.147.483.647 haces un backup de tu Base de Datos, usando para hacer el backup el programa GBAK
  • Restauras ese backup (probablemente con el mismo nombre que la Base de Datos original)
  • A partir de este momento todas las conexiones deben realizarse en la Base de Datos restaurada, no en la Base de Datos original
  • Eso te permitirá tener otras 2.147.483.647 transacciones

Ejemplo:

  1. Cuando el número de la Next Transaction llega a 2.100.000.000 se hace un backup, usando para ello el programa GBAK
  2. Se restaura el backup
  3. A partir de este momento todas las conexiones se hacen en el backup restaurado
  4. Se vuelve al punto 1.

De esta manera no habrá límites a la cantidad de transacciones totales de tu Base de Datos.

¿Por qué hay que usar GBAK para hacer el backup?

Porque GBAK además de hacer el backup también recolecta la basura (es la opción por defecto, y por supuesto que debe estar habilitada).

¿Qué significa “recolectar la basura”?

Eliminar permanentemente de la Base de Datos versiones de registros que ya no son útiles pero que permanecían en la Base de Datos, ocupando lugar innecesariamente. Cuando se hace un UPDATE o un DELETE el Firebird guarda la versión anterior del registro para que si la transacción finaliza con un ROLLBACK poder regresar a esa versión anterior. Eso va dejando versiones de registros inservibles a los cuales se les llama “basura”, alguna de la cual puede ser eliminada automáticamente, pero no toda. Para asegurarte de que toda la basura sea eliminada debes hacer un sweep (barrido) manual o usar el programa GBAK.

¿Por qué al recolectarse la basura se eliminan los TID?

Porque como hemos visto en este artículo:

https://firebird21.wordpress.com/2013/09/08/entendiendo-los-identificadores-de-las-transacciones/

una transacción solamente le interesa al Firebird cuando está activa, está revertida o está en limbo. Una transacción que finalizó con un COMMIT (o que finalizó con un ROLLBACK pero la basura que dejó ya fue recolectada) no es de interés para el Firebird ni para alguien más. ¿Por qué no? porque ya nada queda por hacer en esa transacción. Una transacción es algo transitorio, algo temporal, después de finalizar con un COMMIT o después que su basura fue recolectada ya no es interesante, porque ya nada se puede hacer en ella. Por ese motivo los TID pueden reutilizarse, pero para que puedan ser reutilizados se debe hacer un backup con GBAK y luego usar la Base de Datos restaurada, no la original.

¿Y cómo puedo saber si el número de la Next Transaction está cerca del límite de 2.147.483.647?

Usando el programa GSTAT que viene incluido con el Firebird (o muchos otros programas de terceros que también te muestran ese dato)

Transacciones1

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

También podrías escribir:

SELECT
   MON$NEXT_TRANSACTION
FROM
   MON$DATABASE

Entonces, cuando el número de la Next Transaction supera los 2.100.000.000 (algo que puede tardar muchos años, dependiendo de la cantidad de transacciones diarias que tenga tu Base de Datos) urgentemente debes ir pensando en hacer un ciclo backup/restore.

Si por ejemplo tienes 1.000.000 de transacciones por día entonces recién en 2.100 días necesitarás realizar el ciclo backup/restore, y eso equivale a más de 5 años y medio.

Artículos relacionados:

La arquitectura MGA

Entendiendo los identificadores de las transacciones

El índice del blog Firebird21

Entendiendo los identificadores de las transacciones

3 comentarios

Cada transacción tiene un número que la identifica de forma exacta, no pueden existir dos transacciones con el mismo número y en el mismo momento.

Identificador de la transacción

Al número que identifica a la transacción se le conoce como TID (Transaction Identificator)

Estados de las transacciones

Una transacción solamente puede estar en uno de estos estados:

  • Confirmada. Significa que la transacción finalizó con un COMMIT
  • Revertida. Significa que la transacción finalizó con un ROLLBACK
  • Activa. Significa que la transacción aún no finalizó ni con un COMMIT ni con un ROLLBACK ni está en limbo
  • Limbo. Significa que falló el segundo COMMIT. En transacciones que involucran a dos bases de datos hay que hacer dos COMMIT, uno para cada Base de Datos. Si el primer COMMIT finalizó exitosamente y el segundo COMMIT falló entonces la transacción está en limbo.

Transacciones interesantes

Hay algunas transacciones que para el Firebird son de interés, y son las siguientes:

  • Oldest transaction (la transacción más antigua). Es la transacción más antigua que no finalizó con un COMMIT. Eso significa que puede estar revertida, activa o en limbo. Las transacciones confirmadas (o sea, las que finalizaron con un COMMIT) ya no le interesan al Firebird. ¿Por qué no? porque ya han sido guardadas exitosamente y ya nada le queda para hacer con ellas. A la Oldest transaction se la conoce también como la Oldest Interesting Transaction (la más antigua transacción interesante) y se la representa con las letras OIT.
  • Oldest active transaction (la transacción activa más antigua). Es la más antigua transacción que no finalizó ni con un COMMIT ni con un ROLLBACK y no está en limbo. Eso significa que el usuario en este momento tiene a la transacción abierta y está haciendo algo con ella (insertando, modificando, borrando, consultando, ejecutando un stored procedure). Se la representa con las letras OAT.
  • Oldest snapshot transaction  (la transacción instantánea más antigua). Es la transacción más antigua cuya basura no puede ser recolectada. Una transacción deja basura cuando modifica una fila, borra una fila, o finaliza con un ROLLBACK. Lo normal es que esa basura pueda ser recolectada y entonces este número es igual al de la OAT, ese es el caso más común. A la Oldest snapshot transaction se la representa con las letras OST.
  • Next transaction (siguiente transacción). Es el número que tendrá la siguiente transacción.

Barrido automático

El sweep (barrido, de barrer con una escoba) puede estar activado o desactivado. Si está activado entonces empieza cuando la diferencia entre la OST y la OIT es mayor que el sweep interval (intervalo del barrido). Por ejemplo:

OST = 45.201

OIT = 25.200

Sweep interval = 20.000

OST – OIT = 45.201 – 25.200 = 20.001

Como el resultado de OST – OIT (que en este ejemplo es 20.001) es mayor que el intervalo del sweep (que en este ejemplo es 20.000) entonces empieza el sweep.

¿Que hace el sweep?

Elimina permanentemente de la Base de Datos toda la basura que fueron dejando las transacciones. Una transacción deja basura cuando modifica una fila, borra una fila, o finaliza con un ROLLBACK.

¿Es beneficioso el sweep?

Sí, muy beneficioso porque cuando finaliza la Base de Datos queda más limpia y en consecuencia conectarse a ella será más rápido y realizar operaciones en ella (INSERT, UPDATE, DELETE, FETCH, SELECT, EXECUTE PROCEDURE) también será más rápido.

Detectando problemas

Si la diferencia entre la OAT y la Next Transaction aumenta y aumenta eso significa que alguna transacción no está terminando con un COMMIT y por lo tanto está aumentando la cantidad de basura. Cuando la diferencia entre la OAT y la Next Transaction sea grande (“diferencia grande” depende de tu hardware y de tu software) notarás que cada vez toma más tiempo conectarse a la Base de Datos y realizar operaciones en ella. En estos casos lo correcto es utilizar el programa GFIX.EXE para hacer un sweep manual.

Reinicio de los identificadores de las transacciones. Caso 1

Cada vez que haces un ciclo backup/restore los números de los identificadores de las transacciones vuelven a empezar en uno. Por ejemplo:

NT = 65.920

Se hace un ciclo backup/restore y en la Base de Datos restaurada se ve que:

NT= 387

¿Qué pasó, por qué disminuyó la NT? Porque a todas las transacciones confirmadas el Firebird les asignó un número (el mismo número les asignó a todas las transacciones confirmadas) y a la basura la eliminó, o sea que dejó en la Base de Datos solamente las transacciones que previamente habían finalizado con un COMMIT.

¿Qué implica que los números de las transacciones interesantes cambien después de un ciclo backup/restore?

Que jamás deberías usar esos números dentro de tu programa para identificar a las transacciones entre una conexión y otra. O sea que tus programas no deberían depender de los números de las transacciones entre dos conexiones distintas. Dentro de la misma conexión no hay problema, el identificador no cambiará. Por ejemplo, una transacción está haciendo un INSERT en la tabla PRODUCTOS y esa transacción tiene el número 527. Puedes usar ese número 527 para identificarla sin problema. Pero si el usuario se desconectó de la Base de Datos y volvió a conectarse ya no deberías usar el número 527 porque ahora la transacción que hizo el INSERT a la tabla PRODUCTOS podría tener otro número (si se hizo un ciclo backup/restore entre ambas conexiones).

Reinicio de los identificadores de las transacciones. Caso 2

Hay otro caso en el cual el número de la Next Transaction no aumenta.

Los identificadores de las transacciones se guardan internamente como números de tipo INTEGER. Los números de tipo INTEGER pueden, como máximo, llegar hasta 2.147.483.647.

Entonces, ¿qué pasa cuando la Next Transaction alcanza a ese número?

Que ya no se puede seguir usando esa Base de Datos. Imposible. La conexión siempre será denegada.

¿Y cuál es la solución?

Hacer un ciclo backup/restore y usar la Base de Datos restaurada. No la original, porque la original ya está inaccesible, sino la restaurada.

Por lo tanto, si por algún motivo te interesa poder seguir accediendo a la Base de Datos original entonces el ciclo backup/restore que la reemplazará deberías hacerlo bastante antes de llegar al límite de 2.147.483.647 transacciones, por ejemplo al llegar a las 2.147.000.000 de transacciones podrías hacer un ciclo backup/restore y desde ese momento empezar a usar la Base de Datos restaurada, no la original. A la original podrás acceder un máximo de 483.647 veces más, cuando sea estrictamente necesario.

Artículos relacionados:

La Next Transaction después de un ciclo backup/restore

El índice del blog Firebird21

El foro del blog Firebird21