23 formas más de acelerar Firebird
Alexey Kovyazin, IBSurgeon, [email protected], 08-Ene-2019
Traducciones: Portugués
¿Por qué “23 más”?
Algunos de ustedes recuerdan el artículo «45 formas de acelerar la base de datos Firebird», que fue publicado en mayo de 2016. Ahora es el momento de publicar la siguiente serie de consejos y trucos, basados principalmente en la experiencia de optimización y mantenimiento de bases de datos y servidores Firebird con un alto número de conexiones (1000+).
1. Establezca las opciones de energía en Alto rendimiento en Windows Server 2016 y 2019
Por defecto, Windows Server tiene un plan de energía establecido en “Equilibrado”, que no es adecuado para servidores de bases de datos. Establézcalo en “Alto rendimiento” y gane aproximadamente un +20% de rendimiento en operaciones intensivas de CPU. Se puede configurar en línea, sin reiniciar ni rearrancar. La imagen a continuación muestra el gráfico de CPU, que demuestra la ventaja del plan de energía “Alto rendimiento”:

Más detalles sobre nuestras pruebas con los planes de energía de Windows se pueden encontrar aquí.
2. Habilite «Interactuar con el escritorio» en Classic para Windows
Si está utilizando Firebird con arquitectura Classic en Windows, habilite la casilla «Permitir que el servicio interactúe con el escritorio». Sin esta configuración, el recurso «desktop heap» está limitado por Windows, y Firebird no puede abrir más de 250-300 conexiones (depende de los metadatos de la base de datos y del consumo de memoria relacionado) - se producirá un error Out Of Memory.

3. Cuidado: Controlador de dominio
El problema es que Windows con el rol de Controlador de dominio deshabilita la caché de escritura en el disco con la base de datos de Active Directory.
Esto afecta a Firebird de diversas maneras (así como a otras aplicaciones, por supuesto), y demuestra un rendimiento significativamente peor que en los servidores sin roles de Active Directory.
Tenga en cuenta que este problema afecta a versiones populares de Windows como Windows Small Business Server 2011, así como a otras versiones con DC.
4. Aumente el límite de «max open files» en Linux
Si está utilizando Linux como servidor de bases de datos, no olvide ajustar los límites para Firebird. Verifique los límites de su proceso Firebird (SuperServer o SuperClassic) con el siguiente comando:
cat /proc//limits
y preste atención a la línea con el número máximo de archivos abiertos.
Firebird puede usar hasta 4 handles por conexión, y si tiene algo como esto:
Max open files 4096 4096 files
significa que el número total de conexiones atendidas por el proceso Firebird estará limitado a alrededor de 1000.
Tenga en cuenta - si tiene 4 bases de datos en el servidor, se cuenta la conexión para cada base de datos.
Establezca un valor mayor - recomiendo 65535.
No olvide verificar nuevamente después de reiniciar el proceso Firebird: si se aplicó o no.
Para la arquitectura Classic, es necesario verificar y aumentar los límites para el usuario «firebird».
5. Use Linux moderno
Sí, entiendo que este consejo es trivial, pero he visto muchas veces una buena mejora del rendimiento después de la migración de CentOS 6 a 7, Ubuntu 12 a 16 (¡en el mismo hardware!), así que ahora es la recomendación imprescindible para servidores de bases de datos con más de 250-300 conexiones. El Linux moderno es un requisito previo antes de los siguientes pasos de optimización.
Versiones recomendadas de Linux: CentOS 7.x y Ubuntu 16, 18.
6. Reserve 40% de RAM para la caché de archivos en Windows
El Administrador de memoria del SO tiene implicaciones con respecto a la asignación de memoria y, por defecto, Windows requiere 40% de RAM para la caché de archivos.
Desafortunadamente, la pobre herramienta Administrador de tareas de Windows muestra la memoria que se usa para la caché de archivos como «libre», y algunos administradores intentan hacer que Firebird consuma toda esta memoria libre, por lo que establecen el parámetro DefaultDBCachePage en firebird.conf en valores muy altos, y esto generalmente conduce al swapping.
Siempre use la herramienta RAMMap para ver el uso real de memoria en Windows.
La regla empírica para Windows Server (dedicado para su uso como servidor Firebird) es la siguiente: la memoria de Firebird (Working Set) debe ser menor al 40% de la RAM total. Si el tamaño total de los working sets de todos los procesos es más del 50%, Windows puede iniciar el swap.
Tenga en cuenta: “reservar” aquí significa no solo “no establecer demasiados page buffers en Firebird” sino, también importante, restringir el uso de memoria de otro software. Por ejemplo, si tiene MS Exchange o MSSQL en el mismo servidor con Firebird, asegúrese de restringir sus apetitos de memoria.
Si le interesa conocer los detalles, he grabado el webinar dedicado a la gestión de memoria en Firebird:
- Parte 1. https://www.youtube.com/watch?v=ZBmLgbYt4aM
- Parte 2, https://www.youtube.com/watch?v=-1.DF2FnU-A
7. Reserve 30% de RAM para la caché de archivos en Linux
Linux trabaja con la caché de archivos de manera diferente que Windows y, en general, la cantidad de RAM utilizada para la caché de archivos puede ser significativamente menor que en Windows, sin una degradación notable del rendimiento de Firebird. Sin embargo, para garantizar un alto rendimiento del sistema con un alto número de conexiones, especialmente en Classic y SuperClassic, una buena idea será reservar 30% de RAM para la caché de archivos.
8. Use irqbalance en Linux
irqblalnce a menudo mejora el rendimiento de Firebird y el balanceo de carga de CPU en servidores con un alto número de núcleos.
9. Para Máquinas Virtuales - cuidado con el Memory Overcommit
Una Máquina Virtual puede configurarse para tener más memoria de la que existe físicamente en la máquina host - con una característica conocida como Memory Overcommit (el nombre puede ser diferente en los distintos sistemas de virtualización). Esto significa que en el caso de un pico de consumo de memoria (en la VM con el servidor de bases de datos o en la VM vecina) puede iniciarse el swap, lo que provocará retrasos significativos. Para una VM de alto rendimiento destinada a un servidor de bases de datos, toda la memoria debe ser estática.
10. Para Máquinas Virtuales - verifique los límites de la VM
A menudo las VM se crean con límites predeterminados de CPU e IO, que pueden ser muy bajos, como 50 IOPS y 10% de CPU. Verifique la configuración de la VM de su servidor y elimine cualquier límite - un servidor de bases de datos de alto rendimiento debe tener toda la CPU, el ancho de banda y el IO posibles.
11. Limpie los archivos temporales de Firebird
Firebird crea muchos archivos temporales para diversas operaciones: ordenamiento, procesamiento de BLOB, tracing. Estos archivos se almacenan en las siguientes ubicaciones: en Windows C:\ProgramData\firebird, en Linux / tmp / firebird
Normalmente estos archivos deberían limpiarse automáticamente, sin embargo, a veces esto no sucede (por ejemplo, en el caso de reinicio del servidor).
Verifique estas carpetas periódicamente y limpie los archivos antiguos - puede haber muchos GB de archivos obsoletos fb_NNN, y limpiarlos liberará espacio en la unidad del sistema.
12. No olvide habilitar la caché de archivos con una caché grande de Firebird
Como sabe, la caché de Firebird (también llamada «page buffers») se especifica mediante el parámetro DefaultDBCachePages en firebird.conf/databases.conf, o directamente en el encabezado de la base de datos.
En Firebird 3 SuperServer el tamaño de esta caché puede establecerse muy alto, pero es importante recordar otro parámetro: FileSystemCacheThreshold.
Si FileSystemCacheThreshold es menor que DefaultDBCachePages o page buffers, la caché de archivos del sistema operativo no se utilizará, lo que puede provocar problemas de rendimiento.
En el 99% de los casos, es mejor tener la caché de archivos habilitada.
Para asegurar esto, siempre establezca los parámetros de acuerdo con la siguiente regla:
- DefaultDBCachePages = X
- FileSystemCacheThreshold = X+ N, N>1
Hay casos raros en los que deshabilitar la caché de archivos mejora el rendimiento - si tiene tal ejemplo, por favor contácteme - [email protected]!
13. Acelere la base de datos de seguridad
Cada conexión a la base de datos Firebird establece la conexión con la base de datos de seguridad (security3.fdb en el caso de Firebird 3), y realiza varias lecturas y escrituras (páginas de transacción, página de encabezado). Si tiene conexiones frecuentes, el rendimiento de su base de datos de seguridad puede convertirse en un problema.
Como mínimo, puede hacer lo siguiente:
- Aumentar los page buffers para securityN.fdb (el óptimo empírico es 256 buffers)
- Mover security3.fdb a la unidad rápida (es una característica estándar en Firebird 3, en 2.5 requerirá reinstalación)
Luego, puede establecer Forced Writes OFF para la base de datos de seguridad - la pequeña probabilidad de corrupción no es un problema en este caso.
La forma más radical es hacer que la base de datos de seguridad sea de solo lectura - esto eliminará todas las escrituras en ella.
Si no cambia usuarios con frecuencia en la base de datos de seguridad, es la mejor solución.
14. Pruebe SuperClassic en Firebird 3
En Firebird 3 la arquitectura SuperServer fue muy publicitada como la solución de rendimiento definitiva, pero hay algunos tipos de carga que demuestran mejor rendimiento con SuperClassic (pero no Classic - siempre funciona más lento que SuperServer/SuperClassic).
¿Cómo llevar a cabo este experimento de forma segura? Siga los pasos a continuación:
Para probar SuperClassic
- Establezca en firebird.conf
- ServerMode=SuperClassic
- DefaultDbCachePages=1024
- gfix -buff 0
- Reinicie Firebird
Para volver a SuperServer
- Establezca en firebird.conf
- ServerMode=SuperServer
- DefaultDbCachePages=N # N*page size*databases_count < 25% RAM
- FileSystemCacheThreshold = N+1
- gfix -buff 0
- Reinicie Firebird
Por favor escríbame ([email protected]) sobre los resultados del experimento, me interesa ver los resultados.
15. ¿Base de datos grande? Aumente el tamaño de página
Por defecto, las bases de datos Firebird tienen los siguientes tamaños de página:
- 2.5 - 4096 bytes
- 3.0 - 8192 bytes
Sin embargo, el tamaño máximo de página es 16K (en 4.0 - 32K).
Para bases de datos de más de 100Gb en el 95% de los casos, es mejor tener el mayor tamaño de página disponible, con el fin de:
- Disminuir la profundidad de los índices. Se recomienda tener índices con profundidad menor o igual a 3. Los índices con profundidad 4 y 5 serán mucho más lentos
- Aumentar la utilización de la RAM. La caché de Firebird se especifica en páginas, 1000 páginas con tamaño de página de 8K serán 8Mb de memoria real, y con 16K - 16Mb.
- Disminuir el número de páginas del sistema. Acelerará el acceso a los registros de las tablas grandes (menos saltos pointer-pointer-data page), y ayuda con la preparación de las consultas SQL grandes. Para aumentar el tamaño de página de la base de datos, la base de datos debe respaldarse con la herramienta gbak y luego restaurarse con el parámetro -page ( gbak -c -page 16384).
Tenga en cuenta: si tiene una base de datos con muchos blobs pequeños, aumentar el tamaño de página puede disminuir la fragmentación o aumentarla, y es difícil predecir si aumentará o disminuirá el rendimiento.
16. No use el flag no_reserve
El flag no_reserve hace que Firebird no reserve espacio libre (30%) en las páginas de datos para las posibles versiones de registros, que ocurren después de UPDATE o DELETE. Este flag permite que los datos se almacenen de forma más compacta (y el tamaño de la base de datos también es menor), pero en caso de UPDATE/DELETE todos los cambios van a la nueva página de datos. Como resultado, en la base de datos con el flag no_reserve las operaciones UPDATE/DELETE son más lentas.
Entonces, si su base de datos no es de solo lectura, recomiendo eliminar el flag no_reserve.
Cómo verificar si está establecido o no - vea la línea Attributes en la salida de
gstat -h database
Cómo deshabilitarlo:
gfix -use reserve database
Después de este comando, las nuevas páginas de datos se crearán con espacio reservado.
Sin embargo, para lograr el efecto completo, es necesario respaldar la base de datos con gbak y luego restaurarla, en este caso, todas las páginas de datos estarán con espacio reservado.
Tenga en cuenta: el tamaño de la base de datos crecerá después de eliminar el flag no_reserve y hacer backup/restore.
17. Establezca un tamaño inicial alto para la tabla de bloqueos de Firebird
La tabla de bloqueos es el mecanismo de Firebird, que se utiliza para sincronizar el acceso a los objetos internos del motor.
La tabla de bloqueos de Firebird puede crecer automáticamente, pero su incremento es una operación lenta, que puede provocar micro-congelaciones. La tabla de bloqueos solo puede crecer, partiendo del tamaño inicial (se establece en firebird.conf).
Para evitar múltiples rondas de incremento de la tabla de bloqueos, una buena idea será vigilar el tamaño de la tabla de bloqueos al final del período de trabajo (día, semana, etc.) y luego establecerlo como tamaño inicial en firebird.conf.
LockMemSize=99999999
Como referencia: LockMemSize en sistemas de alta carga con ~1000 usuarios suele estar por debajo de 200Mb.
18. Use fb_lock_print para contar el número de conexiones a la base de datos
Obtener el número de conexiones a la base de datos es una tarea frecuente para los desarrolladores de bases de datos: puede ser necesario por motivos de licenciamiento, por ejemplo.
A menudo los desarrolladores usan la consulta SELECT count(*) FROM MON$ATTACHMENTS para obtener este valor, pero no es la forma óptima: las consultas frecuentes a las tablas MON$ pueden ser una carga para la base de datos, así que es mejor usar la alternativa:
Ejecute
fb_lock_print -d database_name | alias
y compruebe el valor de Owners: mostrará el número actual de conexiones a la base de datos.
19. Evite LEFT JOINs innecesarios
A menudo veo consultas con una construcción como esta:
T1 LEFT JOIN T2 ON (…) WHERE T2.Field_condition
Esencialmente, la condición sobre T2 excluye los NULL de la salida del LEFT JOIN T2, por lo que es posible cambiar LEFT JOIN a INNER JOIN: no afectará al resultado de la consulta.
INNER JOIN da más libertad al optimizador de Firebird y, en las versiones modernas de Firebird, se optimiza mucho mejor que LEFT.
Especialmente tiene sentido en los siguientes casos:
- No hay condición para T1 en la cláusula WHERE
- T2 es una tabla pequeña
20. Evite el conteo innecesario de registros
Otro error común en las consultas complejas a la base de datos y en los procedimientos almacenados es usar select count() solo para comprobar la existencia del registro.
La siguiente consulta leerá todos los registros según condition1:
(select count(*)…. where condition11) >0
Mejor use esta construcción en su lugar
Exists(select first 1 id where condition1)
Si condition1 devuelve más de 1 registro, la opción propuesta será mucho más rápida, porque no lee todos los registros, se detiene tras el primer registro obtenido.
21. Evite la ordenación innecesaria en los procedimientos almacenados
La ordenación de los resultados de la consulta dentro del procedimiento almacenado debe estar justificada por la lógica de negocio.
Por ejemplo, en el ejemplo del procedimiento almacenado de abajo, la cláusula ORDER BY es inútil desde el punto de vista de la lógica de negocio, pero añade una operación de ordenación innecesaria.
create or alter procedure NEW_PROCEDURE
returns (
SUMX double precision)
as
declare variable _amount double precision;
begin
for select T1.amount from Table1 t1 where ....
order by id
into :_amount
do
begin
sumx=sumx+_amount
end;
suspend;
end
Revise su código PSQL en busca de situaciones similares y elimine los ORDER BY inútiles (así como distinct y UNION).
22. No mantenga las consultas en estado preparado sin necesidad
A menudo vemos 500-1000 sentencias preparadas en cada conexión (se puede comprobar con consultas MON$).
La gran mayoría de ellas se ejecuta solo una vez y luego simplemente permanecen en la RAM, haciendo más grande el working set de Firebird y ralentizando las consultas MON$.
La recomendación es mantener las consultas SQL en estado preparado solo si están destinadas a ejecutarse muchas veces, o si su tiempo de preparación es grande (puede ser así para consultas muy grandes con muchos joins y acceso a tablas enormes).
23. Cierre siempre las consultas con ordenación grande
Hasta que la consulta SQL con ordenación (ORDER BY, GROUP BY, UNION, distinct) no se cierre, Firebird retiene los registros ordenados en la memoria. El tamaño de la memoria asignada para la ordenación se establece con el parámetro TempCacheLimit en firebird.conf; por defecto es 64Mb.
Incluso con un TempCacheLimit aumentado, las consultas de larga duración con un gran número de registros ordenados consumirán toda la cantidad asignada eventualmente y, como resultado, la ordenación pasará a archivos temporales (es decir, al disco). Como resultado, puede provocar una lentitud significativa.
La recomendación es cerrar todas esas consultas de forma oportuna.
¿Preguntas?
No dude en contactarme con cualquier pregunta: [email protected].