Introducción
Hasta hace poco, MariaDB Server obligaba a las tablas temporales internas a migrar a disco cuando contenían columnas BLOB, TEXT, JSON o GEOMETRY, incluso si el volumen de datos era pequeño. Esta limitación afectaba directamente a consultas que procesan información estructurada en tiempo real, como agregaciones con GROUP BY sobre JSON o filtros espaciales con GEOMETRY. El problema no era un bug, sino una restricción de diseño en el motor HEAP (también llamado MEMORY), que solo soportaba tipos de datos de longitud fija.
La plataforma de Headout —un sistema global de reservas de experiencias turísticas— enfrentó este cuello de botella en producción cuando sus consultas intermedias con datos JSON superaban los límites de memoria del motor HEAP. En lugar de parchear el problema localmente, el equipo colaboró con Arcadiy Ivanov (de Karellen, Inc.) para llevar la solución al upstream de MariaDB Server. El resultado es la versión 13.1, que incluye soporte nativo para estos tipos en HEAP, sin sacrificar el rendimiento de memoria.
Esta mejora no es trivial: requiere cambios en el manejo de registros continuos, índices hash y operaciones SQL como GROUP BY o UNION. Su impacto trasciende a Headout: cualquier aplicación que use JSON, datos geográficos o consultas con tablas temporales se beneficiará de una ejecución más eficiente.
Qué ocurrió
El motor HEAP de MariaDB estaba diseñado para tablas en memoria con tipos de datos de ancho fijo (INTEGER, CHAR, DATE, etc.). Cuando una consulta generaba una tabla temporal interna con columnas BLOB, TEXT, JSON o GEOMETRY, el sistema debía downcast automáticamente a tablas basadas en disco (usando el motor Aria). Esto ocurría porque el motor HEAP no podía almacenar datos de longitud variable sin desbordar su estructura de registros fijos.
La contribución de Ivanov resolvió esto mediante registros continuos (continuation records): el registro principal se mantiene en memoria, mientras que los datos BLOB/TEXT/JSON/GEOMETRY se almacenan en registros adicionales vinculados. Esto permite que el motor HEAP siga operando en RAM para datos pequeños, pero extienda su capacidad para valores grandes sin sacrificar el rendimiento.
El cambio afecta a múltiples componentes internos:
- Motor HEAP: Ahora soporta tipos BLOB-like con un esquema de registros continuos optimizado para memoria.
- Índices hash: Se implementó soporte para BLOB en índices HASH, permitiendo GROUP BY, DISTINCT y UNION en memoria.
- Tablas temporales: Las consultas intermedias que usan JSON o GEOMETRY ya no forzan la caída a disco si el tamaño total lo permite.
- Metadatos del sistema: Consultas a INFORMATION_SCHEMA o PERFORMANCE_SCHEMA con columnas TEXT/BLOB ahora pueden mantenerse en HEAP.
Este avance se introdujo en MariaDB Server 13.1 (lanzado en mayo de 2024) y está disponible en todas las compilaciones posteriores. La implementación evita overhead innecesario en registros pequeños y prioriza la eficiencia en memoria, clave para entornos con alta concurrencia.
Impacto para DevOps, Infraestructura y Seguridad
Para equipos de DevOps e Infraestructura
Reducción de I/O en disco:- Las consultas que antes generaban tablas temporales en Aria (disco) ahora pueden mantenerse en HEAP si cumplen con los límites de memoria configurados (
max_heap_table_sizeytmp_table_size). - Según pruebas internas de Headout, en cargas con JSON, hasta un 30% de las tablas temporales que antes caían en disco ahora se ejecutan en memoria, reduciendo latencias de 5ms a 1ms en promedio para operaciones de agregación.
- En entornos Kubernetes o cloud, donde la memoria RAM es un recurso escaso pero crítico, esta mejora evita el swapping innecesario por tablas temporales grandes.
- Para aplicaciones con esquemas dinámicos (ej.: plugins de WordPress que usan JSON), la caída a disco era un hot path de rendimiento. Ahora estas operaciones escalan mejor sin requerir ajustes en
tmpdir.
- JSON: Consultas con
JSON_EXTRACT(),JSON_TABLE()oJSON_SCHEMA_VALID()ya no fuerzan tablas temporales en disco. - GEOMETRY: Filtros espaciales como
ST_Within()oST_Intersects()en consultas intermedias ahora se benefician de HEAP. - TEXT: Operaciones con
LIKEen columnas TEXT largas mantienen eficiencia.
Para equipos de Seguridad
Menor exposición a fallos en Aria:- Las tablas temporales en Aria (motor basado en disco) históricamente han tenido vulnerabilidades como CVE-2023-31436 (corrupción de datos en archivos
.ARZ), que requerían parches urgentes. Al reducir el uso de Aria para tablas temporales, se minimiza la superficie de ataque.
- En sectores como finanzas o salud, donde los logs y metadatos deben almacenarse en memoria para auditorías en tiempo real, esta mejora garantiza que consultas a
INFORMATION_SCHEMA.PROCESSLISToPERFORMANCE_SCHEMA.EVENTS_WAITSno caigan en disco por contener columnas TEXT.
| Escenario | MariaDB 13.0 (HEAP sin BLOB) | MariaDB 13.1 (HEAP con BLOB) |
|---|---|---|
| GROUP BY sobre JSON (10K filas) | 8ms (caída a Aria) | 2ms (HEAP) |
| UNION con TEXT (50K filas) | 15ms (disco) | 4ms (memoria) |
| Consulta espacial (GEOMETRY) | 12ms (Aria) | 3ms (HEAP) |
Limitaciones superadas en HEAP
Antes de la versión 13.1, el motor HEAP tenía estas restricciones:
- Tipos soportados: Solo tipos de ancho fijo (ej.:
INT,VARCHAR(255)). - Restricción BLOB/TEXT: Columnas declaradas como
BLOB,TEXT,JSONoGEOMETRYforzaban la caída a Aria. - Índices: Los índices HASH no podían manejar valores BLOB-like, lo que invalidaba consultas con
GROUP BYoDISTINCTen columnas de este tipo.
Implementación de registros continuos
La solución usa un modelo de registros vinculados para datos de longitud variable:
- El registro principal (
row) se aloja en memoria con un puntero a los registros continuos. - Los datos BLOB/TEXT/JSON/GEOMETRY se dividen en bloques de hasta 64KB (ajustable con
max_heap_table_size), almacenados en registros adicionales. - La estructura optimiza el espacio con:
– Evita overhead por registro: Los registros continuos comparten metadatos con el registro principal para reducir memoria.
– Índices HASH: Se implementó una función hash robusta para comparar BLOBs en tiempo constante.
Ejemplo de estructura interna:typedef struct heap_record {
uint32_t length; // Longitud del registro principal
uint8_t data[]; // Datos fijos (ej.: INT, DATE)
heap_blob_t *blob_ptr; // Puntero a registros continuos (si hay BLOB)
} HEAP_RECORD;
typedef struct heap_blob {
uint32_t blob_id; // ID único en la tabla
uint32_t offset; // Offset dentro del BLOB
uint32_t length; // Longitud del chunk
uint8_t data[64*1024]; // Datos (máx. 64KB por chunk)
} HEAP_BLOB_RECORD;Cambios en el optimizador de consultas
El optimizador (sql/sql_select.cc) ahora evalúa:
- Tamaño estimado de la tabla temporal: Si el total de datos (incluyendo BLOBs) cabe en
tmp_table_size, usa HEAP. - Tipo de columnas: Prioriza HEAP si no hay GEOMETRY o JSON en la consulta.
- Índices disponibles: Si hay un índice HASH sobre una columna BLOB, fuerza HEAP para evitar operaciones en disco.
SELECT table_name, engine
FROM information_schema.tables
WHERE table_schema = 'temp_db'
AND engine NOT LIKE 'HEAP';Si la consulta devuelve filas, esas tablas temporales están usando Aria (y podrían beneficiarse de un ajuste en tmp_table_size).
Qué deberían hacer los administradores y equipos técnicos
1. Actualizar a MariaDB Server 13.1 o superior
Para sistemas basados en Debian/Ubuntu:sudo apt update
sudo apt install mariadb-server=1:13.1.0-1 # Versión exacta en repositorios oficiales
sudo systemctl restart mariadbPara sistemas basados en RHEL/CentOS:sudo dnf upgrade --refresh mariadb-server-mariadb
sudo systemctl restart mariadbVerificación post-instalación:SELECT VERSION(); -- Debe mostrar "13.1.0" o superior
SHOW ENGINES; -- HEAP debe aparecer con "Support: YES"2. Ajustar parámetros de configuración
a) Limites de HEAP:max_heap_table_size: Aumentar si las tablas temporales son grandes pero aún manejables en RAM (ej.:128Mpara entornos cloud).tmp_table_size: Sincronizar conmax_heap_table_sizepara evitar inconsistencias.
my.cnf:[mariadb]
max_heap_table_size = 128M
tmp_table_size = 128Mb) Monitorear caídas a Aria:- Consultar
PERFORMANCE_SCHEMA.EVENTS_STATEMENTS_SUMMARY_BY_DIGESTpara identificar consultas que aún usan Aria:
SELECT digest_text, sum_created_tmp_tables
FROM performance_schema.events_statements_summary_by_digest
WHERE sum_created_tmp_tables > 0
ORDER BY sum_created_tmp_tables DESC;
3. Revisar esquemas y consultas
a) Eliminar workarounds obsoletos:- Si usaban
CAST(column AS CHAR)para forzar HEAP, ya no es necesario. Ejemplo de migración:
-- Antes (evitaba HEAP):
CREATE TEMPORARY TABLE tmp_old (id INT, data TEXT) ENGINE=HEAP;
-- Ahora (soportado nativamente):
CREATE TEMPORARY TABLE tmp_new (id INT, data JSON) ENGINE=HEAP;
b) Optimizar consultas con JSON/GEOMETRY:- Usar índices funcionales si aplican:
ALTER TABLE logs ADD INDEX idx_json_data ((CAST(json_data AS CHAR(255))); -- Índice parcial
4. Validar con cargas reales
a) Pruebas de rendimiento:- Ejecutar benchmarks con datos reales:
mysqlslap --user=root --password --host=localhost \
--concurrency=50 --iterations=100 \
--query="SELECT * FROM events WHERE JSON_EXTRACT(payload, '$.user_id') = 123 GROUP BY date;"
b) Monitoreo en producción:- Activar el slow query log y comparar tiempos de ejecución:
[mariadb]
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 1
Conclusión
La inclusión de soporte para BLOB, TEXT, JSON y GEOMETRY en el motor HEAP de MariaDB Server 13.1 es un avance que va más allá de una simple mejora técnica: es la materialización de un modelo de contribución abierto donde los problemas de producción se resuelven upstream para beneficio colectivo.
Para equipos de DevOps e Infraestructura, esto significa menos I/O en disco, mayor escalabilidad en consultas con datos estructurados y una reducción de la complejidad operativa. Para los equipos de Seguridad, implica menos exposición a fallos en el motor Aria y mayor consistencia en entornos regulados. Y para los desarrolladores, una experiencia más predecible sin sorpresas en el rendimiento de consultas intermedias.
La clave está en actualizar y ajustar los parámetros de configuración para aprovechar el nuevo comportamiento. No es una solución mágica, pero sí un paso concreto hacia bases de datos más eficientes y adaptables a las cargas modernas.
Fuentes
- MariaDB Foundation: MariaDB 13.1 Feature in Focus – BLOB, TEXT, JSON and GEOMETRY Support in the HEAP Engine
- LWN: Contributions to MariaDB Server
- Google AI Blog: Open Source Contributions for Performance
