Introducción

MariaDB Server permite extender su funcionalidad mediante plugins que se integran directamente con el motor. Hasta ahora, esta extensión se realizaba casi exclusivamente en C o C++, lo que requería familiaridad con la base de código del servidor y sus estructuras internas. Sin embargo, la propuesta MDEV-40189 explora cómo bajar esa barrera de entrada permitiendo desarrollar plugins en lenguajes como Rust, Python, JavaScript o Lua.

La motivación detrás de este cambio no es reemplazar el desarrollo nativo en C/C++, sino ofrecer alternativas para equipos que ya dominan estos lenguajes o que buscan prototipar funcionalidades rápidamente sin incurrir en los riesgos de memoria y seguridad típicos de C. Por ejemplo, un equipo de DevOps podría implementar un plugin de auditoría en Rust para evitar errores de punteros, mientras que un equipo de datos podría escribir un plugin de transformación de datos en JavaScript para prototipar lógicas complejas antes de migrarlas a stored procedures.

Qué ocurrió

La propuesta MDEV-40189 (abierta en 2023) plantea investigar tres enfoques técnicos principales para soportar plugins en múltiples lenguajes:

  1. Generación de bindings automáticos: Usar herramientas como SWIG (Simplified Wrapper and Interface Generator) para exponer la API de plugins de MariaDB a lenguajes de alto nivel. SWIG puede generar wrappers para Python, Java, Ruby, Lua y otros, permitiendo que el código en estos lenguajes invoque funciones del servidor sin escribir C manualmente.
  1. Runtimes embebidos: Integrar motores de ejecución como GraalVM (para JavaScript) o V8 (para JavaScript) directamente en el proceso del servidor. MySQL ya implementó este modelo a través de su Multilingual Engine (MLE), mientras que Percona Server experimentó con V8 para funciones almacenadas en JavaScript. La clave aquí es cómo aislar el runtime para evitar fugas de memoria o corrupción del proceso principal.
  1. WebAssembly (WASM): Compilar plugins a WASM y ejecutarlos en un sandbox dentro del servidor. Este enfoque ofrece aislamiento claro y portabilidad, pero plantea desafíos en la exposición de APIs del servidor, manejo de memoria y rendimiento. Empresas como Cloudflare ya usan WASM para extensiones en entornos de alto rendimiento, aunque no en el contexto de bases de datos.

El equipo detrás de MariaDB no busca implementar estos enfoques de inmediato, sino evaluar su viabilidad técnica mediante proofs of concept (PoC) enfocados en tipos específicos de plugins. Por ejemplo, un PoC inicial podría implementar un plugin de audit plugin en Rust usando bindings generados con bindgen, o un plugin de information schema en JavaScript con GraalVM.

Impacto para DevOps / Infraestructura / Cloud / Seguridad

Para equipos de DevOps e Infraestructura

La posibilidad de escribir plugins en lenguajes modernos tiene varias implicancias prácticas:

  • Reducción de riesgos operativos: Rust, con su modelo de ownership y borrow checker, reduce los riesgos de segmentation faults o memory leaks en plugins críticos. Por ejemplo, un plugin de conexión a un servicio externo que maneje credenciales podría beneficiarse de la seguridad de Rust frente a un equivalente en C.
  • Prototipado rápido: Equipos que no dominan C podrían prototipar funcionalidades como user-defined functions en Python o JavaScript antes de migrarlas a código nativo. Esto acelera ciclos de desarrollo, especialmente en entornos ágiles o de feature experimentation.
  • Integración con ecosistemas existentes: Un plugin para exponer métricas de MariaDB a Prometheus podría escribirse en Go o Python usando bindings, evitando la necesidad de mantener código en C. Esto es relevante para equipos que ya usan herramientas de monitoreo basadas en estos lenguajes.

Para equipos de Cloud

En entornos cloud, donde la portabilidad y el aislamiento son críticos, los enfoques de WASM o runtimes embebidos (como GraalVM) podrían ofrecer ventajas:

  • Sandboxing: WASM permite ejecutar plugins en un entorno aislado, reduciendo el riesgo de que un plugin malicioso comprometa el proceso del servidor. Esto es especialmente útil en arquitecturas multi-tenant donde varios clientes comparten una instancia de MariaDB.
  • Portabilidad: Un plugin compilado a WASM podría ejecutarse en cualquier entorno que soporte WASM (incluyendo Kubernetes con sidecar containers), simplificando despliegues en arquitecturas híbridas.

Para equipos de Seguridad

Desde la perspectiva de seguridad, la introducción de múltiples lenguajes de plugins plantea desafíos específicos:

  • Ataques por inyección de código: Runtimes embebidos como V8 o GraalVM podrían ser explotados si no se implementan controles estrictos de sandboxing. Por ejemplo, un ataque a la API expuesta a JavaScript podría permitir ejecución arbitraria de código si el runtime no está debidamente aislado.
  • Control de versiones y vulnerabilidades: Equipos de seguridad deberán monitorear no solo las versiones de MariaDB, sino también las versiones de los runtimes embebidos (como V8 o GraalVM) y sus dependencias. Por ejemplo, V8 12.x introdujo cambios en el manejo de memoria que podrían afectar la estabilidad de un plugin si no se actualiza correctamente.
  • Políticas de permisos: La exposición de APIs de plugins a lenguajes de alto nivel requerirá nuevos modelos de control de acceso. Por ejemplo, un plugin en Python debería poder limitar qué funciones del servidor puede invocar, similar a cómo MySQL implementa sandboxes para JavaScript.

Detalles técnicos

Enfoques técnicos en evaluación

1. Generación de bindings con SWIG

SWIG es una herramienta madura (versión 4.1.1, lanzada en 2023) que genera wrappers para múltiples lenguajes a partir de headers en C/C++. Para MariaDB, SWIG podría usarse para exponer la API de plugins, que incluye funciones como:

plugin_init(int *argc, char **argv);
plugin_deinit(void);

Un ejemplo de cómo se generaría un wrapper para Python usando SWIG:

%module mariadb_plugin
%{
#include <mysql/plugin.h>
%}

%include "mysql/plugin.h"

Esto generaría un módulo Python (mariadb_plugin.py) que permite invocar funciones del servidor desde Python:

import mariadb_plugin

def init_plugin():
    argc = 0
    argv = []
    mariadb_plugin.plugin_init(argc, argv)
Limitaciones:
  • SWIG genera bindings «crudos» que requieren manejo manual de memoria y punteros.
  • No abstrae las complejidades del ciclo de vida del plugin (ej.: cuándo llamar a plugin_deinit).
  • La performance puede verse afectada por las capas de indirección.

2. Rust y bindgen

bindgen es una herramienta de Mozilla (versión 0.69.1, 2024) que genera bindings de Rust para APIs en C. Para MariaDB, bindgen podría usarse para exponer la API de plugins a Rust, pero requeriría una capa safe adicional.

Ejemplo de generación de bindings para la API de plugins:

bindgen /usr/include/mysql/plugin.h -o mariadb_plugin.rs -- -I/usr/include/mysql

Esto generaría un crate de Rust con tipos como:

extern "C" {
    pub fn plugin_init(argc: *mut i32, argv: *mut *mut i8) -> i32;
}
Desafíos:
  • La API de MariaDB usa punteros crudos y callbacks, lo que en Rust requiere wrappers seguros (safe abstractions).
  • El manejo de memoria debe ser explícito: por ejemplo, garantizar que los strings pasados a MariaDB no se liberen prematuramente.

3. Runtimes embebidos: GraalVM y V8

  • GraalVM (versión 23.1.1, 2024): Usado por MySQL en su Multilingual Engine para ejecutar JavaScript. GraalVM ofrece aislamiento mediante contexts y polyglot APIs, pero requiere configuración cuidadosa para evitar fugas de memoria.
  • V8 (versión 12.3.24, 2024): Usado por Percona Server en su soporte experimental para JavaScript. V8 es rápido pero no está diseñado para aislamiento estricto dentro de un proceso del servidor.
Ejemplo de integración con JavaScript en MySQL:
DELIMITER //
CREATE FUNCTION js_hello RETURNS STRING
LANGUAGE JAVASCRIPT
AS $$
  return "Hello from GraalVM!";
$$;
DELIMITER ;
Riesgos:
  • Fugas de memoria en el runtime pueden corromper el proceso de MariaDB.
  • La API expuesta a JavaScript debe ser minimalista para evitar vectores de ataque.

4. WebAssembly (WASM)

WASM es un formato binario portable que se ejecuta en un sandbox. Proyectos como Wasmtime (versión 14.0.0, 2024) permiten ejecutar WASM en entornos nativos.

Ejemplo de arquitectura:
  1. Compilar un plugin a WASM usando Rust o C++:
   rustup target add wasm32-unknown-unknown
   cargo build --target wasm32-unknown-unknown --release
   
  1. Cargar el WASM en MariaDB mediante un plugin nativo que actúe como host:
   #include <wasmtime.h>
   void load_wasm_plugin(const char *path) {
       wasmtime_engine_t *engine;
       wasmtime_store_t *store;
       // Inicializar runtime WASM
   }
   
Desafíos:
  • Solo una porción limitada de la API de MariaDB puede exponerse a WASM.
  • La performance puede verse afectada por el overhead de WASM.
  • Depuración es más compleja que en lenguajes tradicionales.

Versiones afectadas y estado actual

  • MariaDB Server: La propuesta MDEV-40189 está en fase de diseño (2023-2024). No hay releases oficiales con soporte para plugins en otros lenguajes.
  • SWIG: Versión estable 4.1.1 (marzo 2023). Compatible con Python 3.8+, Java 17+, Lua 5.4+.
  • Rust: bindgen 0.69.1 (abril 2024) soporta Rust 1.75+. Requiere libclang 16+.
  • GraalVM: Versión 23.1.1 (mayo 2024) soporta JavaScript, Python y Ruby.
  • V8: Versión 12.3.24 (junio 2024) es la última estable con soporte para embedders.

Qué deberían hacer los administradores y equipos técnicos

1. Evaluar la viabilidad con PoCs

Equipos interesados deberían comenzar con un proof of concept enfocado en un caso de uso concreto. Por ejemplo:

Opción A: Plugin de auditoría en Rust
  1. Instalar dependencias:
   sudo apt install clang libclang-dev rustc cargo
   
  1. Generar bindings con bindgen:
   bindgen /usr/include/mysql/plugin_audit.h -o audit_plugin.rs -- -I/usr/include/mysql
   
  1. Implementar un plugin seguro en Rust:
   mod safe_plugin {
       use std::ffi::{CString, CStr};

       pub unsafe extern "C" fn audit_init() -> i32 {
           println!("Inicializando plugin de auditoría en Rust");
           0 // OK
       }
   }
   
  1. Compilar e integrar con MariaDB:
   cargo build --release
   gcc -shared -o libaudit_plugin.so target/release/libaudit_plugin.so -lmysqlclient
   
Opción B: Plugin de Information Schema en JavaScript
  1. Instalar GraalVM:
   curl -L https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-23.1.1/graalvm-ce-java17-linux-amd64-23.1.1.tar.gz | tar -xz
   
  1. Configurar el Multilingual Engine en MariaDB (requiere compilación desde fuente):
   cmake -DMULTILINGUAL_ENGINE=ON ..
   make install
   
  1. Crear un plugin de ejemplo:
   CREATE FUNCTION js_get_status RETURNS STRING
   LANGUAGE JAVASCRIPT
   AS $$
     return JSON.stringify({
       version: "1.0",
       uptime: process.uptime()
     });
   $$;
   

2. Monitorear el desarrollo de la propuesta MDEV-40189

  • Seguir el progreso en MDEV-40189.
  • Probar builds experimentales de MariaDB que incluyan soporte para SWIG o runtimes embebidos.
  • Contribuir con feedback técnico sobre los enfoques propuestos.

3. Preparar políticas de seguridad

Si se implementa soporte para plugins en otros lenguajes, los equipos de seguridad deberían:

  1. Definir políticas de aislamiento:
– Para JavaScript: Configurar GraalVM en modo sandboxed y deshabilitar APIs peligrosas como eval o require.

– Para Python: Usar PyPy en modo restricted o RestrictedPython para limitar operaciones riesgosas.

  1. Monitorear vulnerabilidades en runtimes:
– Actualizar GraalVM y V8 tan pronto como se publiquen parches de seguridad (ej.: CVE-2024-4559 en V8 12.3.23).

– Usar herramientas como dependabot para alertar sobre vulnerabilidades en dependencias.

  1. Limitar permisos por lenguaje:
– Ejemplo de política para Python:
     import mariadb_plugin
     def init():
         if not hasattr(mariadb_plugin, "audit_log"):
             raise PermissionError("Acceso no autorizado a audit_log")
     

4. Documentar y capacitar

  • Crear guías internas para equipos que quieran adoptar estos enfoques.
  • Documentar los límites de cada enfoque (ej.: «WASM no soporta callbacks asíncronos»).
  • Capacitar a equipos en el uso de herramientas como SWIG, bindgen o GraalVM.

Conclusión

La propuesta de soportar plugins en lenguajes como Rust, Python, JavaScript y Lua en MariaDB Server abre oportunidades para equipos que buscan extender la base de datos sin dominar C/C++. Sin embargo, la implementación requiere resolver desafíos técnicos complejos: generación de bindings seguros, aislamiento de runtimes embebidos, y portabilidad con WASM.

Los equipos de DevOps e infraestructura deberían comenzar con proofs of concept enfocados en casos de uso específicos (auditoría, information schema, funciones almacenadas) y evaluar la viabilidad técnica antes de adoptar estos enfoques en producción. Mientras tanto, seguir el progreso de MDEV-40189 y contribuir con feedback técnico será clave para moldear la dirección de esta funcionalidad.

Para equipos que ya usan MariaDB en entornos críticos, la recomendación actual es no adoptar plugins en otros lenguajes en producción hasta que la propuesta esté más madura y se publiquen guías oficiales de seguridad y performance. La estabilidad y seguridad de la base de datos deben seguir siendo la prioridad.

FIN

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *