Usando Firebird durante 24/7/365

3 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

 

Usando Firebird con WiFi

2 comentarios

En esta época es muy común que haya conexiones WiFi en todas partes, tanto en los hogares como  en las oficinas e inclusive en lugares públicos. Entonces la pregunta es: ¿qué tan eficiente es usar Firebird con WiFi?

Primero, hay que decir que es perfectamente posible pero … pueden ocurrir problemas. Veamos:

Pérdidas de señal

En una red WiFi casi siempre en un momento o en otro ocurren pérdidas de señales, si haces una búsqueda con Google verás que hay millones de personas quejándose de eso. La culpa de la pérdida de señal puede ser del hardware o del software. Pero vayamos a lo nuestro:

El Servidor del Firebird no sabe si te has conectado a la Base de Datos por medio de una red cableada o por medio de WiFi. Eso implica que lo importante es la calidad de tu red, no de si es cableada o WiFi.

Si la culpa de la pérdida de señal es del hardware, entonces hay que reemplazarlo. No pretendas conectar a ochopotocientas computadoras con un router WiFi barato, de esos que cuestan casi lo mismo que una docena de caramelos. Si la conexión será por WiFi entonces el router debe ser de una marca bien conocida, de muy buena calidad. Esto se lo debes aclarar muy bien a tu cliente, y por escrito, para que luego no te echen la culpa de la lentitud o del tiempo perdido. Desde luego que esto se aplica a todo tipo de redes, sean cableadas o WiFi: si tu cliente quiere buena velocidad entonces debe invertir en hardware de buena calidad, no puedes garantizar ni velocidad ni confiabilidad si no es así. Aunque en una red cableada con hardware de mala calidad podrías obtener un resultado aceptable con redes WiFi nunca es así: hardware malo implica rendimientos miserables con bases de datos.

Si la culpa de la pérdida de señal es del software entonces eso significa que no está bien configurado. Y aquí hay varios puntos que tener en cuenta:

  1. El Windows puede desconectarse del router para ahorrar energía. Puedes verificarlo entrando en Panel de Control | Administrador de dispositivos | Adaptadores de red | Nombre_de_tu_router | Propiedades | Administración de energía. Si está marcada la opción “Permitir que el equipo apague este dispositivo para ahorrar energía”, quítale la marca.
  2. En el archivo FIREBIRD.CONF que se encuentra en la carpeta donde instalaste el Firebird hay una entrada llamada DummyPacketInterval que sirve para indicarle al Servidor del Firebird cuantos segundos debe esperar antes de enviarle un paquete vacío de reconocimiento al Cliente. ¿Qué significa esto? Que si el Cliente no está enviando solicitudes al Servidor (un comando INSERT, UPDATE, DELETE, SELECT, etc., por ejemplo) el Servidor no puede saber si el Cliente continúa conectado o si se ha desconectado. La forma de verificar que continúa conectado es enviándole un paquete vacío que solamente sirve para reconocimiento. Si el Cliente le envía una respuesta al Servidor entonces el Servidor sabe que el Cliente continúa conectado. Si el Cliente no le envía una respuesta entonces evidentemente se murió la conexión. La entrada DummyPacketInterval sirve justamente para eso: para decirle al Servidor cada cuantos segundos debe verificar que el Cliente está conectado.
  3. En el punto 1. hemos visto como pedirle al Servidor que verifique la conexión pero … ¿y si queremos que sea el Cliente quien la verifique? Esto siempre es importante, antes de enviarle un comando (INSERT, UPDATE, DELETE, SELECT, EXECUTE PROCEDURE, etc.) al Servidor queremos verificar que hay una conexión activa. La forma más sencilla y rápida de conseguirlo es pidiéndole al Servidor que nos devuelva algún dato, por ejemplo la fecha de hoy. Para ello le podemos enviar un comando como: SELECT CURRENT_DATE FROM RDB$DATABASE y si como resultado obtenemos una fecha entonces estamos seguros de que la conexión está activa (se le dice “viva” en muchos documentos sobre redes). El Cliente solamente necesita saber si la conexión está activa cuando envía una solicitud, para que ésta no rebote; en los demás momentos no le importa.
  4. El Windows puede ayudarnos a mantener la conexión activa. Si se lo pedimos puede enviar paquetes de reconocimiento cada “x” segundos. Los datos en el protocolo TCP/IP viajan en grupos conocidos como paquetes, los cuales están compuestos por una cabecera, los datos del usuario, y la cola. Si en un paquete no se envían datos del usuario entonces puede usarse para saber si una conexión está activa o no. IMPORTANTE: Estas instrucciones son solamente para usuarios avanzados, si no es tu caso ni lo intentes o podrías dejar a tu Windows inservible. No lo olvides: no lo intentes si no sabes muy bien lo que estás haciendo. El Windows viene con un programa llamado REGEDIT el cual nos permite modificar el Registro, también podríamos modificarlo con un archivo que tenga la extensión .REG o con algunos otros programas utilitarios. En el Registro del Windows hay una clave llamada “Parameters” que encontrarás en HKEY_LOCAL_MACHINE | System | CurrentControlSet | Services | Tcpip. A esa clave le puedes agregar los siguientes valores DWORD: KeepAliveInterval, que determina la frecuencia con la cual el Windows repite transmisiones “keepalive” (mantener viva) cuando no recibe respuesta, puedes ponerle 1, lo cual significa que enviará paquetes cada 1 segundo; KeepAliveTime, que determina los segundos que esperará el Windows desde que se terminó la última conexión o intento de reconocimiento para enviar reconocimiento, si por ejemplo le pones 60 eso significa que esperará que hayan transcurrido 60 segundos después de la última conexión o intento de reconocimiento antes de verificar si está activa; TcpMaxDataRetransmissiones, que determina cuantas veces como máximo se enviará un paquete antes de decidir que la conexión está muerta, su valor por defecto es de 5.

Múltiples dispositivos usando la red WiFi

Además del problema que podemos tener con las pérdidas de señal hay otro problema que inclusive puede llegar a ser peor: los usuarios querrán usar la red WiFi para conectar no solamente las computadoras que accederán a las bases de datos sino también tabletas, teléfonos celulares smart, televisores smart, relojes smart, y cualquier otro dispositivo habido o por haber que pueda conectarse a una red WiFi.

Entonces, no podrás evitar que a algún “genio” se le ocurra ver una película on-line mientras otros usuarios necesitan una red rápida. Es muy difícil evitar esas conexiones piratas y siempre tendrán algún muy buen motivo para hacerlas … y lo que conseguirán será que los tiempos de respuesta de las solicitudes a las bases de datos sean paupérrimos.

Conclusión:

 Es posible conectarse a bases de datos de Firebird a través de redes WiFi, pero si se desea un buen tiempo de respuesta el hardware debe ser de buena calidad y el software debe estar bien configurado.

Sin embargo, una buena red cableada siempre será mejor que una buena red WiFi.

Para deslindar responsabilidades siempre es una muy buena idea hacerle firmar un documento a tu cliente que diga algo como: “Para trabajar con bases de datos son preferibles las redes cableadas, las redes WiFi solamente tienen un buen desempeño cuando el hardware es de muy buena calidad y el software está correctamente configurado, en otro caso es una mala opción usarlas. Pero aún con una buena red WiFi siempre la red cableada será más rápida y más confiable. Mi recomendación por lo tanto es usar una red cableada.”

Artículos relacionados:

El índice del blog Firebird21

El foro del blog Firebird21

 

Los archivos temporales del Firebird

Deja un comentario

El Firebird a veces necesita crear archivos temporales, eso generalmente ocurre cuando en un comando SELECT se usa la cláusula ORDER BY y no existe un índice que pueda ser usado, o cuando ya no hay espacio disponible en la porción de memoria RAM que utiliza para los ordenamientos, o cuando se crean tablas temporales (o sea: tablas GTT) de gran tamaño.

Si el Servidor del Firebird recibe la orden de ejecutar un SELECT que contiene la cláusula ORDER BY y no hay un índice que pueda utilizar entonces evidentemente debe ordenar esas filas en algún lado para poder mostrarlas ordenadas.

¿Dónde se realiza ese ordenamiento?

El Firebird usa una porción de la memoria RAM a la cual llama Sort Buffer para realizar en ella los ordenamientos. Sin embargo, el espacio del Sort Buffer es limitado y en ocasiones puede ser insuficiente.

¿Qué sucede cuando no hay espacio suficiente en el Sort Buffer para realizar allí el ordenamiento?

Que el Firebird crea archivos temporales. Como no dispone de memoria RAM (la cual es rapidísima) para ordenar el resultado de la consulta entonces crea en el disco duro archivos temporales. Esto es mucho más lento que usar la memoria RAM pero funciona y no hay otra alternativa: hay que crear archivos temporales sí o sí.

¿Cuáles son los nombres de esos archivos temporales?

Todos los archivos temporales creados por el Firebird empiezan con los caracteres FB_ y dependiendo de su contenido serán los siguientes caracteres, por ejemplo si empieza con:

FB_QUERY_  significa que es un archivo temporal creado porque se usó la cláusula ORDER BY sin tener un índice disponible

FB_TABLE_ significa que se creó una tabla temporal (una tabla GTT)

¿Cómo puedo especificar dónde se crearán esos archivos temporales?

Por defecto, si el Firebird es iniciado como un servicio entonces los archivos temporales son creados en la carpeta temporal del Windows, normalmente en C:\WINDOWS\TEMP\ pero si se quiere crearlos en otras carpetas hay dos formas de hacerlo:

  1. Especificando las variables de entorno FIREBIRD_TMP, TEMP, TMP
  2. Cambiando la entrada TempDirectories del archivo FIREBIRD.CONF que se encuentra en la carpeta donde instalaste el Firebird

TEMP1

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

En la Captura 1. podemos ver como especificar una carpeta donde guardar los archivos temporales del Firebird que no sea la que utiliza el Windows. Por supuesto que la carpeta especificada (en este caso: E:\FIREBIRD_ARCHIVOS_TEMPORALES) debe existir y el nombre de la carpeta puede ser cualquiera, el nombre mostrado en la Captura 1. es solamente un ejemplo.

TEMP2

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

En la Captura 2. podemos ver como especificar cual será la carpeta temporal en el archivo FIREBIRD.CONF, recordando que debemos borrar el símbolo de numeral que se encuentra a la izquierda de la entrada TempDirectories ya que el símbolo # indica que lo que sigue a continuación es un comentario.

El autor de este blog recomienda que se especifique la carpeta de los archivos temporales en la entrada TempDirectories y que de ser posible se utilice un disco RAM para ese propósito.

¿Puedo tener más de una carpeta para guardar los archivos temporales?

Sí, sin problema, lo único que debes hacer es separarlas con un punto y coma, por ejemplo:

TempDirectories=E:\FIREBIRD_TEMP;F:\ARCHIVOS_TEMP_FIREBIRD;G:\FIREBIRD_TEMP

¿Puedo especificar el tamaño de las carpetas dónde se guardarán los archivos temporales?

Sí, si lo deseas puedes especificar inclusive el tamaño en bytes que se usará en cada carpeta, por ejemplo:

TempDirectories=E:\FIREBIRD_ARCHIVOS_TEMPORALES 100000000

o

TempDirectories=E:\FIREBIRD_TEMP 250000000;F:\TEMP_FILES 300000000;G:\MIS_TEMPORALES 100000000

¿Por qué los archivos temporales del Firebird a veces tienen un tamaño muy grande?

Porque el Firebird expande las columnas CHAR y VARCHAR a su tamaño especificado en la definición de la tabla. Muchos programadores saben que el Firebird no guarda en el disco duro el tamaño especificado en la tabla sino que guarda el contenido de esas columnas comprimido. Entonces saben que pueden especificar un tamaño mucho mayor al necesario sin problema. Por ejemplo, supongamos que la mayor longitud que necesitamos en una columna es de 850 bytes pero en la definición de la tabla usamos 1.000 bytes, 4.000 bytes ó 12.500 bytes; estará todo bien, porque el Firebird nunca guardará más de 850 bytes en el disco duro, sin importar como se definió la columna. Eso en general es algo muy bueno.

Sin embargo, al hacer un SORT a esa columna la cosa cambia, porque allí sí el Firebird utiliza el tamaño usado en la definición de la columna.

De esta manera, inclusive a veces podríamos encontrarnos que tenemos un archivo temporal … cuyo tamaño es mayor al tamaño de la Base de Datos.

Así que, a no exagerar con el tamaño de las columnas CHAR y VARCHAR si existe la posibilidad de que alguna vez sean usadas en la cláusula ORDER BY de un comando SELECT.

¿Puedo borrar los archivos temporales?

Sí, si el Firebird no los está usando. El Windows no permite que se borre un archivo si algún programa lo está usando, esa es una muy buena medida de precaución.

Entonces, puedes intentar borrar cualquier archivo temporal. Si tuviste éxito eso significa que ningún programa lo estaba usando. Si no pudiste borrarlo entonces tendrás que esperar hasta que deje de ser usado.

Conclusión:

A veces el Firebird necesita crear archivos temporales en el disco duro. Nosotros podemos decirle cuales carpetas debe utilizar para eso e inclusive la cantidad de bytes que puede usar en cada carpeta.

Para aumentar la velocidad de los ordenamientos lo recomendable es usar un disco RAM, si eso no es posible entonces lo recomendable es que los archivos temporales se guarden en un disco duro distinto al usado para guardar las bases de datos.

Artículos relacionados:

Creando y usando tablas temporales

Usando un disco RAM para aumentar la velocidad

Acelerando los SORT

Configurando al Firebird

¿En cuál carpeta tener las bases de datos?

El índice del blog Firebird21

El foro del blog Firebird21

Usando Firebird con procesadores multinúcleo

2 comentarios

Como seguramente sabes, todas las computadoras modernas son multi-núcleo (multicore).

¿Por qué eso?

Porque la velocidad máxima de un núcleo (core) es de 4 gigahertz. Por lo tanto, si se desea obtener mayor velocidad la única alternativa es empaquetar dos o más núcleos (core) en el mismo procesador.

Cuando una computadora tiene un solo núcleo las tareas no se realizan en simultáneo, aunque al usuario así le parezca. Lo que hace el Sistema Operativo es asignarle unos cuantos milisegundos al proceso uno, luego unos cuantos milisegundos al proceso dos, luego unos cuantos milisegundos al proceso tres, etc. De esa manera todos los procesos utilizan al procesador secuencialmente y como lo hacen tan rápidamente al usuario le parece que lo hacen en simultáneo pero no es así.

En cambio si el procesador es multi-núcleo entonces sí se pueden estar realizando varios procesos al mismo tiempo. Mientras el núcleo 1 está ejecutando un proceso el núcleo 2 puede estar realizando otro proceso, el núcleo 3 otro proceso, y así sucesivamente.

En este momento no tiene sentido comprar una computadora de un solo núcleo porque la diferencia de precio con la computadora de múltiples núcleos es muy pequeña y además las de un solo núcleo ya no se fabrican.

Entonces, la pregunta es:

¿Puede Firebird tomar ventaja de los múltiples núcleos de una computadora?

Y la respuesta es sí.

Sin embargo, hay varios posibles escenarios y debemos tomarlos en cuenta.

Firebird viene en tres arquitecturas:

  • Classic
  • SuperClassic
  • SuperServer

Y el uso de los núcleos depende de la arquitectura que estemos usando.

 Si se usa Classic o SuperClassic entonces se pueden tener múltiples conexiones a una misma Base de Datos y se usarán diferentes núcleos.

Si se usa SuperServer un núcleo puede ser usado por una sola Base de Datos.

¿Qué significa lo anterior?

  • Que si usamos SuperServer y tenemos una sola Base de Datos entonces solamente se usará un núcleo de la computadora. No importa cuantos núcleos tenga la computadora, solamente se usará uno de ellos, el primero.
  • Que si usamos SuperServer y tenemos varias bases de datos entonces cada Base de Datos podrá usar un núcleo. Es decir, que si tenemos dos bases de datos la primera Base de Datos usará exclusivamente al núcleo 1 y la segunda Base de Datos usará exclusivamente al núcleo 2. Pero eso no lo realiza el Firebird automáticamente, hay que configurarlo, en la entrada CpuAffinityMask del archivo FIREBIRD.CONF hay que decirle cuales núcleos queremos usar. Si no lo hacemos entonces todas las bases de datos usarán solamente al núcleo 1, sin importar cuantos núcleos tenga la computadora, todas las bases de datos usarán solamente al núcleo 1.
  • Que si usamos Classic o SuperClassic entonces una sola Base de Datos puede usar varios núcleos. Y por supuesto que si tenemos varias bases de datos también se usarán varios núcleos. Esto no es necesario configurar ya que Classic y SuperClassic siempre utilizan todos los núcleos que tiene la computadora, sin importar la cantidad de bases de datos a las cuales los usuarios se conectan.

¿Cómo se configura SuperServer para usar varios núcleos?

En Windows, por defecto SuperServer usa solamente al primer núcleo. Si queremos que use más de un núcleo entonces debemos configurarlo. Para ello:

  1. Abrimos el archivo FIREBIRD.CONF que se encuentra en la carpeta donde instalaste al Firebird (por ejemplo, en C:\Archivos de Programa\Firebird\Firebird_2_5\)
  2. Buscamos la entrada CpuAffinityMask
  3. Borramos el símbolo de numeral que se encuentra a la izquierda (el símbolo # indica que lo que viene a continuación es un comentario)
  4. Establecemos el valor de CpuAffinityMask recordando que se trata de un bitmap (o sea, en binario), en donde:

1 = usará el núcleo 1

3 = usará los 2 primeros núcleos

15 = usará los 4 primeros núcleos

255 = usará los 8 primeros núcleos

Si quieres que un núcleo no se utilice entonces no debes indicarlo en el bitmap, por ejemplo para usar el núcleo 2 y el núcleo 3 pero no el núcleo 1 el valor debería ser 6.

Si conoces números binarios entonces es muy fácil saber cual debe ser el valor de CpuAffinityMask para indicarle cuales núcleos se deben usar.

Conclusión:

Firebird puede usar todos los núcleos que tiene una computadora, pero los núcleos que serán usados depende de la arquitectura utilizada. Classic y SuperClassic siempre usan todos los núcleos disponibles en cambio SuperServer por defecto usa solamente el primer núcleo y para que utilice otros núcleos hay que configurarlo mediante la entrada CpuAffinityMask del archivo FIREBIRD.CONF, recordando que con SuperServer una Base de Datos solamente puede usar un núcleo, jamás usará más de un núcleo, en cambio con Classic o con SuperClassic una Base de Datos usará todos los núcleos.

Artículos relacionados:

El índice del blog Firebird21

El foro del blog Firebird21

Acelerando los SORT

1 Comentario

Ya sabemos que en ocasiones el Firebird necesita ordenar las filas creando archivos temporales, a esa operación se la llama SORT (ordenar, en inglés) y puede ser lenta en tablas grandes. Entonces ¿qué podemos hacer para acelerar los SORT?

  1. Pedirle que los realice en un disco rápido
  2. Pedirle que los realice en un disco RAM
  3. Asegurándonos que el espacio libre en el disco temporario sea más grande que la Base de Datos
  4. Creando los archivos temporales en un disco distinto al de la Base de Datos

Los discos tienen distintas velocidades de lectura/escritura (y distintos precios también, claro). Los más rápidos suelen ser los SSD (Solid State Disk), aunque el problema es que son más caros que los discos duros magnéticos y también tienen una menor vida útil (aunque esto último está cambiando mucho, ya que cada vez duran más tiempo).

Como los SORT requieren crear archivos temporales, y muchos de esos archivos temporales pueden llegar a ser inmensos entonces debemos buscar por todos los medios acelerar el proceso.

Usar un disco RAM es una muy buena alternativa, aunque por supuesto eso requiere que la computadora tenga mucha memoria disponible. Para saber como crear un disco RAM y que programa usar para ello, puedes leer este artículo:

Usando un disco RAM para aumentar la velocidad

 ¿Y cuánto espacio libre debe tener el disco dónde se realizarán los SORT?

Evidentemente, cuanto más, mejor. Como no podemos saber de antemano cuanto será el espacio libre que necesitará el Firebird en general se toma como parámetro el tamaño de la Base de Datos. Es casi seguro que siempre necesitará menos que eso.

Entonces, si nuestra Base de Datos tiene un tamaño de 2 Gb, con tener 2 Gb en el disco donde se crearán los archivos temporales será suficiente. Pero no olvides que las bases de datos siempre crecen entonces hay que prever más, en ese caso un disco (duro o RAM) con 4 Gb sería muy bueno.

¿Y cómo se especifica dónde se crearán los archivos temporales?

En la carpeta donde instalaste el Firebird encontrarás un archivo cuyo nombre es FIREBIRD.CONF, dentro de ese archivo hay una entrada llamada “TempDirectories”. Debes borrar el símbolo de numeral que está a la izquierda y escribir los nombres de las carpetas donde se crearán los archivos temporales. Si usarás más de una carpeta deberás separarlas con punto y coma, por ejemplo:

TempDirectories=G:\TEMP
TempDirectories=G:\TEMP;F:\FIREBIRDTEMPS

¿Qué significan esas entradas?

La primera, que todos los archivos temporales se crearán en la carpeta G:\TEMP

La segunda, que los archivos temporales se crearán en G:\TEMP y que si alguna vez no hay espacio suficiente entonces se los continuará creando en F:\FIREBIRDTEMPS

Es decir, la segunda carpeta solamente se usa si la primera carpeta se quedó sin espacio.

¿Cómo se deben especificar los nombres de las carpetas en TempDirectories?

Como el Firebird primero usará la primera carpeta, y si se queda sin espacio allí usará la segunda carpeta, entonces en primer lugar deberías escribir el nombre de la carpeta que se encuentra en el disco más rápido. Si tienes un disco RAM entonces esa primera carpeta evidentemente será la del disco RAM.

En el ejemplo de arriba si el disco G: es un disco RAM y el disco F: es un disco SSD, entonces estará perfecto, porque primero especificamos el disco más rápido.

Desde luego que puedes tener más de dos carpetas, aunque en este ejemplo se mostraron 2 carpetas tú podrías tener 3, 4, 5, las que necesites. Solamente recuerda que siempre los discos más rápidos deben ser escritos primero.

¿Por qué los discos donde se encuentran las bases de datos y los archivos temporales debe ser distinto?

Si una sola persona está usando la Base de Datos, no hay problema, porque o está creando archivos temporales o no los está creando. En ambos casos estará trabajando a la máxima velocidad posible. Pero lo normal es que a una Base de Datos estén conectadas varias personas al mismo tiempo, cada una de ellas realizando alguna operación y ahí sí el tema se complica y mucho.

¿Por qué se complica?

Tenemos dos posibilidades:

  1. Están en un disco duro magnético
  2. Están en un disco no magnético (por ejemplo, un disco SSD)

Si están en un disco duro magnético, entonces hay un cabezal que debe moverse. Ese es un movimiento mecánico y por lo tanto siempre será lento. Si un usuario hace un SORT el cabezal debe moverse a un sector del disco duro. Otro usuario hace un INSERT, el cabezal debe moverse a otro sector del disco duro. Otro usuario hace un INSERT a otra tabla y nuevamente el cabezal debe moverse. Si los usuarios están ejecutando las operaciones de INSERT, UPDATE, DELETE, SELECT, FETCH, entonces los sectores estarán contiguos o muy cerca unos de otros, porque todos ocurren dentro de la misma Base de Datos. Pero si un usuario está haciendo un SORT esos sectores estarán muy alejados de la Base de Datos y ese constante ir y venir del cabezal hará que tanto las operaciones en la Base de Datos como el SORT sean mucho más lentos de lo que deberían. Si has leído algo sobre el diseño de Sistemas Operativos recordarás que usan semáforos: le dan unos milisegundos a un proceso para que haga lo que quiere hacer, luego otros milisegundos a un segundo proceso, luego otros milisegundos a un tercer proceso, y así sucesivamente hasta regresar al primer proceso. Para los usuarios esto es transparente, creen que cada uno de sus procesos se está ejecutando simultáneamente con los demás procesos pero eso no es así (bueno, salvo que la computadora tenga varios procesadores, claro). De todas maneras, sea la computadora multi-procesador o no, el cabezal del disco duro tendrá un constante ir y venir entre los sectores usados en el SORT y los sectores usados para las otras operaciones. Eso es lento y siempre será lento, podrá aumentarse la velocidad con discos duros más veloces, pero siempre será lento.

Si están en un disco no magnético (por ejemplo, un disco SSD), entonces no hay un cabezal que se mueve, en realidad nada se mueve, pero los discos tienen una vida útil limitada que aunque va aumentando porque la tecnología mejora, siempre tiene un límite. Entonces, si además de realizar las operaciones normales (INSERT, UPDATE, DELETE, SELECT, FETCH) también le pedimos que use a ese mismo disco SSD para los SORT, los backups y los restores, la vida útil de nuestro disco SSD será mucho más corta de lo que debería ser.

Por lo tanto la conclusión es muy sencilla: la Base de Datos debe encontrarse en un disco y los archivos temporales en un disco distinto.

Ese disco debe ser físicamente distinto, no sirve que esté particionado. Si está particionado se trata del mismo disco aunque para el Sistema Operativo sean dos discos diferentes, la realidad es que sigue siendo un mismo disco físico, y eso es justamente lo que no queremos.

Artículos relacionados:

Entendiendo el contenido de un PLAN

Usando un disco RAM para aumentar la velocidad

El índice del blog Firebird21

El foro del blog Firebird21

 

¿Cómo las bases de datos de Firebird aumentan de tamaño?

Deja un comentario

El tamaño que ocupan en el disco duro las Bases de Datos de Firebird no es tan sencillo de conocer como a primera vista se podría uno imaginar.

Cuando creas una Base de Datos de Firebird ésta no está vacía sino que ya tiene dentro suyo muchas tablas que luego serán usadas durante las tareas que se realicen en esa Base de Datos. A esas tablas internas se las conoce como “metadatos”.

Entonces, lo primero que notarás después de crear una Base de Datos si miras su tamaño es que éste es de cientos de kilobytes. Eso es debido a los metadatos. Está ok, así tiene que ser.

Luego, tú o los usuarios empiezan a realizar operaciones de manipulación de datos (inserciones, modificaciones, borrados) y allí puedes notar algo curioso: el tamaño de la Base de Datos parece ser muy grande para la cantidad de filas que hay en las tablas.

¿Por qué?

Porque cuando el Firebird necesita que la Base de Datos tenga más espacio para las filas que estás insertando, modificando o borrando no aloja espacio solamente para esa fila en particular sino que aloja mucho más espacio.

¿Y por qué hace eso, por qué no aloja solamente el espacio en disco exactamente necesario?

Por tres motivos:

  1.  Porque la tarea de alojar más espacio lleva tiempo, no es instantánea. Si cada vez que se inserta una nueva fila tendría que estar alojando espacio en el disco duro para esa fila entonces esas inserciones demorarían demasiado tiempo en bases de datos donde hay muchas inserciones concurrentes y los usuarios se quejarían de la extrema lentitud
  2. Porque como el Firebird aloja el espacio en páginas esos continuos alojamientos fragmentarían excesivamente al disco duro
  3. Porque si el disco duro se queda sin espacio entonces hay una gran posibilidad de que la Base de Datos aún tenga suficiente espacio libre previamente alojado para que pueda terminar todas las operaciones que se estaban realizando en ella, sin corrupción.

Entonces, alojar más espacio del necesario, para tener bastante espacio libre disponible tiene tres grandes ventajas: a) se consigue una gran rapidez en todas las operaciones de inserción, modificación, borrado, porque el espacio ya está disponible, b) no se fragmenta excesivamente el disco duro y c) si el disco duro se queda sin espacio libre es muy probable que la Base de Datos no se corrompa porque los datos que faltaban grabarse se grabarán en el espacio previamente alojado.

Claro que esto también tiene sus desventajas. Estas son: a) cada vez que hay que alojar más espacio ocurre una demora, y b) la Base de Datos puede estar ocupando en el disco duro mucho espacio y si la cantidad libre en el disco duro es escasa eso afectará a los otros programas.

Claro que la desventaja b) es muy improbable que ocurra en esta época en que los discos duros son gigantescos y muy baratos, además si se cuenta con un Administrador que verifique el espacio libre en el disco duro nunca debería ocurrir algo así.

Un gráfico que ilustra el concepto

En este gráfico podemos ver como se aloja el espacio en una Base de Datos de Firebird.

ESTRUCTURA1

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

El espacio en C) está libre, nada hay ahí pero ya está asignado a la Base de Datos y para el Sistema Operativo es espacio ocupado por la Base de Datos y por lo tanto no puede ser usado por otros archivos. Cuando los usuarios insertan, modifican, o borran filas, esas inserciones, modificaciones, o borrados ocurren en C) y cuando el espacio en C) ya es pequeño se aloja más espacio a la Base de Datos, para que siempre tenga espacio libre a su disposición. Pero siempre esos alojamientos sirven para alojar a cientos o a miles de filas, no son para alojar a una o a dos filas sino a cientos o a miles de ellas. O sea que cada vez que se aloja un nuevo C) hay suficiente espacio en él para cientos o miles de filas.

¿Y cuántos bytes se alojan cada vez que la Base de Datos requiere de más espacio?

Cuando el Servidor descubre que la Base de Datos ya casi no tiene espacio libre debe reservar más espacio para ella. En el gráfico anterior la parte B) va creciendo hacia arriba haciendo que la parte C) sea cada vez más pequeña. Es entonces que el Servidor le aloja más espacio, según esta fórmula:

Al tamaño actual de la Base de Datos lo divide por 16

Nunca aloja más espacio que el establecido en la entrada DatabaseGrowthIncrement del archivo FIREBIRD.CONF (que por defecto es 128 Mb) ni menos de 128 Kb

Ejemplos:

Si la Base de Datos tiene 16 Mb entonces aloja 1 Mb (o sea, el tamaño de la Base de Datos dividido 16)

Si la Base de Datos tiene 16 Gb entonces aloja 128 Mb. No aloja 1 Gb sino que aloja 128 Mb. ¿Por qué? porque ese es el valor de la entrada DatabaseGrowthIncrement, salvo que haya sido cambiada.

Si la Base de Datos tiene 16 Gb y la entrada DatabaseGrowthIncrement tiene el valor 268435456 (que equivale a 256 Mb) entonces aloja 256 Mb.

¿Es conveniente aumentar o disminuir el valor de la entrada DatabaseGrowthIncrement?

En general, el valor por defecto de 128 Mb es bastante bueno para la gran mayoría de las situaciones y podríamos dejarlo así, pero en bases de datos que tienen muchísimo movimiento y crecen mucho y rápido puede ser conveniente aumentarlo, para que el Firebird no esté a cada rato alojando nuevo espacio. Disminuirlo no se justifica (salvo que el disco duro tenga poquísimo espacio libre) porque disminuir significa aumentar la fragmentación del disco duro algo que nunca es conveniente porque un disco duro fragmentado tarda más en ser leído.

El valor de la entrada DatabaseGrowthIncrement se expresa en bytes, no en megabytes. Por lo tanto en ella por defecto veremos el número 134217728 que equivale a 128 Mb.

Conclusión:

Para que las operaciones de mantenimiento de tablas (inserción, modificación, borrado) sean muy rápidas el Firebird les asigna a las bases de datos más espacio en el disco duro que el estrictamente necesario. Eso además tiene la ventaja de que es muy improbable de que ocurra corrupción porque si el disco duro se queda sin espacio libre es muy posible que la Base de Datos no, que aún tenga suficiente espacio libre previamente alojado para terminar exitosamente todas las operaciones que estaban realizando los usuarios.

 Para saber cuantos bytes debe alojar cada vez que lo hace, el Firebird divide por 16 al tamaño actual de la Base de Datos. El tamaño mínimo que aloja es 128 Kb y el tamaño máximo que aloja lo determina la entrada DatabaseGrowthIncrement del archivo FIREBIRD.CONF que por defecto es de 128 Mb pero que puede ser cambiado. Si se cambia entonces lo aconsejable es aumentarlo porque disminuirlo aumentará la fragmentación del disco duro, algo que nunca es bueno.

Artículos relacionados:

El índice del blog Firebird21

El foro del blog Firebird21

 

Especificando el archivo FIREBIRD.MSG que queremos usar

Deja un comentario

Este artículo está basado en el artículo:

http://www.firebase.com.br/fb/artigo.php?id=2644

Cuando instalamos al Firebird se copia en el disco duro un archivo llamado FIREBIRD.MSG que contiene los mensajes que mostrará el propio Servidor del Firebird y también algunos de los programas utilitarios que vienen incluidos en la instalación, tales como el GBAK.EXE, el GFIX.EXE, etc.

Si en la computadora hemos instalado solamente una versión del Firebird entonces no tendremos problema, siempre veremos los mensajes correctos, pero si hemos instalado al Firebird más de una vez entonces podremos encontrarnos con un mensaje similar al siguiente:

can't format message...

gbak: writing data for table @1
gbak:@1 records written

¿Qué significa eso?

Que no puede encontrar al archivo FIREBIRD.MSG o que el archivo FIREBIRD.MSG que encontró no corresponde a la versión del Firebird que se está ejecutando.

¿Cómo lo resolvemos?

Configurando a una variable de ambiente llamada FIREBIRD_MSG con la ruta completa al archivo FIREBIRD.MSG que queremos usar, así:

MSG1

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

Y a continuación podemos llamar al utilitario GBAK.EXE, al utilitario GFIX.EXE, etc. y todos los mensajes aparecerán correctamente formateados.

Alternativa:

La forma de resolverlo mostrada arriba siempre funcionará pero si queremos que funcione sin necesidad de configurar a la variable de ambiente FIREBIRD_MSG deberemos hacer lo siguiente:

  • Copiar el archivo FIREBIRD.MSG en la carpeta superior de donde se encuentra el archivo FBCLIENT.DLL

En Windows lo aconsejable es que el archivo FBCLIENT.DLL se encuentre en la misma carpeta en la cual se encuentra el .EXE de nuestra aplicación.

Por lo tanto, en la misma carpeta donde se encuentra nuestro ejecutable CONTA.EXE, STOCK.EXE, VENTAS.EXE, SUELDOS.EXE, etc. copiamos al archivo FBCLIENT.DLL y en la carpeta superior copiamos al archivo FIREBIRD.MSG

Artículos relacionados:

El índice del blog Firebird21

El foro del blog Firebird21

 

Older Entries

Seguir

Recibe cada nueva publicación en tu buzón de correo electrónico.

Únete a otros 200 seguidores