Base de datos Firebird de 1 Tb: informe preliminar
Dmitry Kuzmenko, última actualización 31-03-2014
Traducciones de este documento: Portugués Ruso Chino
Lea nuestro artículo sobre una base de datos aún más grande (1,7 terabytes): Más detalles sobre la base de datos de 1,7 terabytes.
¿Por qué crear una base de datos Firebird de un terabyte?
Muchas empresas trabajan con grandes bases de datos Firebird y dependen de ellas para respaldar operaciones comerciales importantes. Algunas de las bases de datos Firebird ya tienen cientos de gigabytes de tamaño y siguen creciendo (consulte la sección “¿Quién es grande?”), y es fácil predecir el momento en que sean 2, 3 o 5 veces más grandes. Por lo tanto, los administradores de bases de datos y los proveedores están interesados en investigar el comportamiento de Firebird con bases de datos grandes y obtener algunas recomendaciones sobre cómo gestionarlas.
Además, la razón importante que teníamos en mente al crear la base de datos Firebird de 1 Tb era la eliminación definitiva de la percepción predominante de Firebird como motor de base de datos para “bases de datos pequeñas”. Este mito parece estar muerto ahora, pero algunos analistas y periodistas lo resucitan regularmente, y esperamos terminar de una vez por todas con esta ridícula percepción.
| ## Hardware |
Firebird es bien conocido por su increíble escalabilidad y esta investigación lo ha confirmado una vez más. El propósito inicial de este experimento era simplemente la creación de una base de datos Firebird de 1 Tb de tamaño, por lo que utilizamos una computadora de escritorio común:
Tabla 1: Hardware
| Componente | Parámetros |
| CPU | AMDAthlon 64 x2 5200 |
| RAM | 4GB |
| Placa base | MSI K9N Platinum |
| HDD1 (sistema operativo y temp) | ST3160815AS, 160GB, SATA II |
| HDD2 (auxiliar) | HDT721064SLA360, 640GB,SATAII |
| HDD2 (auxiliar) | HDS728080PLA380, 80GB, SATA I |
| HDD3 (base de datos) | ST31500341AS, 1.5TB, SATA II (Firmware CC1H) |
En esencia, colocamos el HDD de 1,5 Tb en uno de nuestros escritorios de oficina, sin ninguna otra modificación. Este HDD se formateó con un tamaño de clúster de 16 Kb (el mismo que el tamaño de página de la base de datos, como puede ver a continuación).
Software
Como es una computadora de escritorio, el sistema operativo es Windows XP Professional SP3, 32 bits. Para realizar realmente la prueba utilizamos el cargador del kit de herramientas basado en TPC (descárguelo desde http://ibdeveloper.com/tests/tpc-c/, tanto los binarios como las fuentes están disponibles).
Nos gustaría enfatizar que el cargador inserta datos como se insertarían en un escenario de la vida real: los registros se insertan y se ubican dentro de la base de datos (y en áreas físicas del disco) en varias tablas maestro-detalle-subdetalle, no tabla por tabla.
Tabla 2: Software
| Software | Versión |
| Sistema operativo | Windows XP Professional SP3, 32bit |
| Firebird | 2.1.3 SuperServer (snapshot) |
| Cargador | Cargador personalizado de la prueba basada en tpc |
Plan
Teníamos un plan muy directo para este experimento:
- Crear la base de datos y cargarla con 1 Tb de datos, sin índices
- Crear claves primarias e índices apropiados (por lo que en realidad el tamaño de la base de datos es superior a 1 Tb)
- Recopilar estadísticas de la base de datos
- Ejecutar varias consultas SQL y estimar el rendimiento de la base de datos
Configuración de la base de datos y del servidor Firebird
La base de datos tiene un tamaño de página de 16384 bytes, el mismo que el clúster del HDD, para maximizar el rendimiento del disco (leer/escribir 1 página en un ciclo de E/S).
En la configuración de Firebird hemos configurado un directorio adicional para espacio temporal y lo apuntamos al disco de 640 Gb (donde había ~300 Gb libres).
Paso de carga
Los datos se cargaron en esta base de datos en varios pasos. La computadora se utilizó durante las operaciones de carga como un escritorio normal (tenemos MS Office, Firefox, IBAnalyst, etc. - alrededor de 8-12 programas ejecutándose al mismo tiempo). Si hubiéramos dedicado el hardware solo a esta tarea, probablemente habría sido más rápido, así que considere estos valores solo como un ejemplo de gama baja; definitivamente no son los mejores resultados.
Tabla 3: Operaciones de carga
| |
| Descripción | Valor |
| Tiempo de carga | ~70 horas |
| Total de registros insertados | 6,2 mil millones |
| Velocidad media de inserción | 24500 registros/segundo |
| Tamaño medio de registro | 146 bytes (mín 13 bytes, máx - 600 bytes) |
| Transacciones | 646489 |
Pasamos ~4 días cargando, y después de eso teníamos una base de datos Firebird con exactamente 1 Tb de tamaño (es decir, 1 099 900 125 184 bytes).
A continuación puede ver el crecimiento de la base de datos y la dinámica de transacciones en el Visor de FBDataGuard:

Índices
Creamos los índices uno por uno y contamos sus tiempos de creación y el tamaño apropiado del archivo temporal utilizado para la clasificación.
El índice más grande se creó para la tabla ORDER_LINE. Su clave primaria contiene cuatro campos (Smallint, Smallint, Integer y Smallint). El archivo temporal para este índice de clasificación fue de 182 Gb, y el tamaño final del índice en la base de datos es de 29,3 Gb.
Es interesante ver que incluso el índice para una tabla con 3,8 mil millones de registros tiene profundidad = 3, porque el tamaño de página era de 16384 bytes, por lo que no hay sobrecarga al buscar datos usando la clave primaria para esta tabla.
Estadísticas
Después de eso recopilamos las estadísticas de la base de datos. Tomó 7 horas 32 minutos 45 segundos.
Hemos puesto la información estadística clave en una sola tabla e incluimos algunas consultas y mediciones de tiempo:
Tabla 4: Estadísticas consolidadas para la base de datos de 1 Tb
| Nombre de la tabla | Recuento de registros | Tamaño, gb | Tiempo de ejecución de select count(*) | Tiempo de creación del índice | Tamaño del archivo tmp, Gb | Tamaño del índice, Gb |
| WAREHOUSE | 1240 | 0.002 | 0s | 0 | 0 | 0.0 |
| ITEM | 100000 | 0.012 | 0.7s | - | - | 0.0 |
| DISTRICT | 124000 | 0.017 | 0.7s | 6 | - | 0.0 |
| NEW_ORDER | 111600000 | 32 | 20m 00s | 23m 00s | 4.56 | 0.8 |
| CUSTOMER | 372000000 | 224 | - | 41m 00s | - | 2.6 |
| customer_last | 1h 52m 32s | 12.4 | 2.3 | |||
| fk_cust_ware | 2h 10m 51s | - | 2.3 | |||
| HISTORY | 372000000 | 32 | - | - | - | - |
| ORDERS | 372000000 | 25 | 32m 00s | 45m 41s | 15.2 | 2.5 |
| STOCK | 1240000000 | 404 | - | 3h 34m 44s | 41.5 | 9.2 |
| ORDER_LINE | 3720051796 | 359 | - | 12h 6m 18s | 182.0 | 29.3 |
Las estadísticas de la base de datos se pueden descargar desde aquí.
Puede usar el Visor gratuito de FBDataGuard Community Edition para interpretar los datos de texto y ver no solo las métricas de rendimiento de la base de datos, sino también el consumo de CPU y memoria.
Consultas
En primer lugar, ejecutamos consultas select count(*) en varias tablas (consulte la cuarta columna de la Tabla 4 anterior). Como saben, debido a la naturaleza multiversión de Firebird, select count(*) para toda la tabla es una operación costosa para el servidor porque requiere visitar cada página, y los desarrolladores experimentados de Firebird no usan select count(*), pero lo usamos para demostrar la relación de rendimiento general de la base de datos y el hardware.
Después de las consultas select count ejecutamos consultas de un escenario de la vida real y, para ser honestos, quedamos asombrados con tan buenos resultados. Compruébelo usted mismo:
| Consulta | Estadísticas | Descripción |
| select w_id, w_name, c_id, c_last from WAREHOUSE, customer where c_w_id = w_id |
PLAN JOIN (WAREHOUSE NATURAL, CUSTOMER INDEX (FK_CUST_WARE)) ------ Performance info —— Prepare time = 15ms Execute time = 79ms Avg fetch time = 6.08 ms Current memory = 272 264 476 Max memory = 272 514 048 Memory buffers = 16 384 Reads from disk to cache = 82 Writes from cache to disk = 0 Fetches from cache = 3 648 |
Unión simple de tablas con 12400 y 372000000 registros, sin condiciones WHERE. “Avg fetch time = 6.08 ms” es para obtener la primera fila. |
| select w_id, w_name, c_id, c_last from WAREHOUSE, customer where c_w_id = w_id and c_w_id = 10000 |
PLAN JOIN (WAREHOUSE INDEX (WAREHOUSE_PK), CUSTOMER INDEX (FK_CUST_WARE)) ------ Performance info —— Prepare time = 16ms Execute time = 78ms Avg fetch time = 6.00 ms Current memory = 272 266 148 Max memory = 272 514 048 Memory buffers = 16 384 Reads from disk to cache = 88 Writes from cache to disk = 0 Fetches from cache = 3 656 |
Unión de las mismas tablas con una condición que fuerza la selección de registros recientes. “Avg fetch time = 6.00 ms” es para obtener la primera fila. |
| select count(*) from WAREHOUSE, customer where c_w_id = w_id and c_w_id = 10000 Result = 30000 |
PLAN JOIN (WAREHOUSE INDEX (WAREHOUSE_PK), CUSTOMER INDEX (FK_CUST_WARE)) ------ Performance info —— Prepare time = 0ms Execute time = 453ms Avg fetch time = 453.00 ms Current memory = 272 263 844 Max memory = 272 514 048 Memory buffers = 16 384 Reads from disk to cache = 1 048 Writes from cache to disk = 0 Fetches from cache = 60 024 |
Recuento de registros para la consulta anterior |
| SELECT * FROM ORDER_LINE WHERE OL_W_ID = 500 |
Plan PLAN (ORDER_LINE INDEX (ORDER_LINE_PK)) ------ Performance info —— Prepare time = 0ms Execute time = 94ms Avg fetch time = 7.23 ms Current memory = 136 445 536 Max memory = 136 592 176 Memory buffers = 8 192 Reads from disk to cache = 150 Writes from cache to disk = 0 Fetches from cache = 2 402 |
Consulta a la tabla más grande (3,8 mil millones de registros). “Avg fetch time = 7.23 ms” es para obtener la primera fila. |
<br>Plan<br><br>PLAN (ORDER_LINE INDEX (ORDER_LINE_PK))<br><br> <br><br>------ Performance info ------<br><br>Prepare time = 0ms<br><br>Execute time = 3s 438ms<br><br>Avg fetch time = 0.01 ms<br><br>Current memory = 136 445 496<br><br>Max memory = 136 592 176<br><br>Memory buffers = 8 192<br><br>Reads from disk to cache = 1 840<br><br>Writes from cache to disk = 0<br><br>Fetches from cache = 598 636<br> |
| SELECT * FROM ORDER_LINE
WHERE OL_W_ID = 500 | La misma consulta a la tabla más grande (3.8B registros), pero esta vez hemos obtenido todos los registros (299245 registros obtenidos). |
| | |
| select w_id, w_name, c_id, c_last
from WAREHOUSE, customer
where c_w_id = w_id and (c_w_id > 8000) and (c_w_id < 10000) | Plan
PLAN JOIN (WAREHOUSE INDEX (WAREHOUSE_PK), CUSTOMER INDEX (FK_CUST_WARE))
------ Performance info ——
Prepare time = 0ms
Execute time = 125ms
Avg fetch time = 9.62 ms
Current memory = 272 270 824
Max memory = 272 514 048
Memory buffers = 16 384
Reads from disk to cache = 91
Writes from cache to disk = 0
Fetches from cache = 3 659 | Unir tablas con 1240 registros y 372M registros. |
| select count(*)
from WAREHOUSE, customer
where c_w_id = w_id and (c_w_id > 8000) and (c_w_id < 10000)
Result = 59 970 000 | Plan
PLAN JOIN (WAREHOUSE INDEX (WAREHOUSE_PK), CUSTOMER INDEX (FK_CUST_WARE))
------ Performance info ——
Prepare time = 0ms
Execute time = 13m 4s 718ms
Avg fetch time = 784 718.00 ms
Current memory = 272 268 532
Max memory = 272 514 048
Memory buffers = 16 384
Reads from disk to cache = 2 332 583
Writes from cache to disk = 0
Fetches from cache = 119 977 902 | Contar registros de la consulta anterior |
Resumen
En este experimento Firebird muestra los siguientes resultados
-
Indudable capacidad para manejar bases de datos grandes. Estamos bastante seguros de que es posible crear y usar una base de datos de 32 Tb en hardware apropiado, y Firebird mostrará el mismo alto rendimiento que muestra para bases de datos más pequeñas (es decir, 1Tb y menos).
-
Buena escalabilidad y una huella sorprendentemente pequeña. La base de datos de 1Tb se creó en una computadora de escritorio habitual y, más importante aún, se puede usar para realizar consultas generales: si no obtienes millones de registros, la velocidad de la consulta es la misma que para bases de datos de tamaño moderado (10-15Gb).
Este no es el final de este experimento: tenemos la intención de ejecutar algunas consultas, recopilar estadísticas adicionales y publicar un informe más detallado en breve. Permanece atento.
Contactos
Envía todas tus preguntas y consultas a [email protected]