
🌐 También en: English · Deutsch · Français
Deep Dive de la serie en torno al Ansible Tour. Nivel: administración Linux avanzada. El tour explica los roles; los deep dives explican la técnica que hay debajo – cómo funciona, por qué está aquí, qué hace exactamente esta instalación con ella, cómo operarla en el día a día y qué otras opciones habría habido.
Las dos aplicaciones se apoyan aquí en MariaDB. El blog la ejecuta como pod junto a WordPress (parte 3), los dos servidores Nextcloud directamente en el host (parte 4). Este artículo explica qué hace InnoDB con la memoria y el disco, qué puñado de ajustes importa para estas cargas, qué dicen las mediciones – y cómo una sola línea en una unidad systemd hizo que SELinux no protegiera la base durante cinco semanas.
🧭 Cómo funcionan MariaDB e InnoDB
El buffer pool: la base vive en RAM
InnoDB, el motor de almacenamiento detrás de cada tabla aquí, lee y escribe datos en páginas de 16 KB. Las páginas leídas se quedan en el buffer pool, un gran bloque de memoria; la siguiente lectura de la misma fila no cuesta ningún acceso a disco. Los cambios se hacen primero en el buffer pool y se escriben más tarde en los ficheros de datos. La cifra más importante de un servidor MariaDB es por tanto la proporción de peticiones de páginas que el buffer pool puede responder – la tasa de aciertos.
Redo log y doublewrite: por qué un fallo no pierde nada
Antes de que una página modificada se escriba en su fichero de datos, el cambio se registra en el redo log, un diario secuencial. Tras un fallo, InnoDB lo reproduce y cada transacción confirmada vuelve a estar. El doublewrite buffer protege contra una página escrita a medias durante un corte de luz: cada página va primero a una zona aparte y después a su sitio real, de modo que una página rota se puede reparar desde la copia.
Un ajuste decide con qué frecuencia se fuerza el redo log a disco. Con innodb_flush_log_at_trx_commit = 1 (por defecto) cada commit espera un fsync. Con 2 el log se escribe en el commit pero se sincroniza solo una vez por segundo – mucho más rápido con muchas escrituras pequeñas, con el riesgo de perder hasta un segundo de commits si cae de golpe toda la máquina (no solo MariaDB).
Tablas temporales: memoria o disco
Las consultas con GROUP BY, DISTINCT, UNION o algunas ordenaciones necesitan una tabla temporal interna. Se crea en memoria hasta tmp_table_size (y max_heap_table_size); una más grande – o una con columnas TEXT/BLOB, que el motor de memoria no puede alojar – va a disco, a tmpdir. WordPress y Nextcloud usan columnas TEXT con generosidad, así que las tablas temporales en disco no son señal de un mal ajuste sino inevitables. La única pregunta es dónde está «el disco».
Conexiones, hilos, el slow log
Cada conexión de cliente recibe un hilo y sus propios búferes; max_connections limita cuántas puede haber y con ello el consumo de memoria en el peor caso. El slow query log registra cada sentencia más lenta que long_query_time – el primer sitio donde mirar cuando una página va lenta.
🛡️ Por qué está aquí
- Las dos aplicaciones se construyen y prueban con ella. WordPress no admite oficialmente otra cosa; Nextcloud recomienda MySQL o MariaDB.
- Una serie LTS. 10.11 recibe correcciones hasta febrero de 2028; las actualizaciones dentro de la serie son pequeñas y previsibles.
- Gobernanza comunitaria. MariaDB la desarrollan la MariaDB Foundation y la empresa, no un único fabricante con sus propias prioridades.
🔧 Qué hace este repositorio
Dos maneras de ejecutar la misma base
| Blog | Servidores Nextcloud | |
|---|---|---|
| Dónde | Pod en K3s (mariadb:10.11.19) | En el host, repositorio MariaDB Community, serie fijada en 10.11 |
| Rol | blog_k3s_deploy | next_mariadb |
| Buffer pool | 384 MB | 2 GB / 512 MB |
tmpdir | volumen en memoria (512 MB) | tmpfs de systemd (4 GB) |
| Accesible por | Service ClusterIP, NetworkPolicy: solo el pod de WordPress | 0.0.0.0:3306, nftables: solo la red de pods |
| SELinux | container_t con categorías MCS propias | mysqld_t |
¿Por qué dos maneras? El blog se construyó desde el principio «todo en el clúster». Para Nextcloud la base es el componente más pesado y valioso, y en el host recibe la sandbox completa de systemd, su propio dominio SELinux y las herramientas de copia de la distribución sin un contenedor de por medio.
Los ajustes que importan
[mysqld]
innodb_buffer_pool_size = 2G # per host (512M on the small one)
innodb_flush_method = O_DIRECT # no double caching in the page cache
innodb_flush_log_at_trx_commit = 2 # sync the redo log once per second
innodb_linux_aio = aio # io_uring is disabled in the kernel
max_connections = 50 # measured peak: 15
tmp_table_size = 32M
max_heap_table_size = 32M
slow_query_log = 1
long_query_time = 1
skip_name_resolve = 1 # pod IPs cannot be resolved anywayinnodb_linux_aio = aio: AlmaLinux desactiva io_uring (kernel.io_uring_disabled = 2). El valor por defecto «auto» lo intentaba igualmente primero, escribía un avisoEPERMen cada arranque y luego volvía de todos modos al AIO clásico de Linux.skip_name_resolve: cada conexión desde un pod provocaba una resolución DNS inversa de una dirección10.42.xque nunca puede funcionar – latencia al conectar y un aviso por conexión en el log. Seguro, porque ninguna cuenta está autorizada por nombre de host.max_connections = 50: el pico medido fue de 15 y 10 conexiones; 50 deja margen y acota la memoria en el peor caso.
Tablas temporales en RAM
Entre el cuatro y el seis por ciento de todas las tablas temporales van a disco en estos servidores – columnas TEXT, ver arriba. Desde el 16 de octubre de 2026 ese «disco» es RAM: el drop-in de systemd da a MariaDB su propio /tmp como tmpfs (TemporaryFileSystem=/tmp:size=4G), el pod del blog monta ahí un volumen en memoria. Un tmpfs solo ocupa memoria mientras existen ficheros; 4 GB dejan sitio para los ficheros de ordenación de una reconstrucción de índices durante una actualización de Nextcloud. Una trampa por el camino: junto con PrivateTmp=yes gana el directorio privado en disco y el tmpfs se ignora sin aviso.
La sandbox – y cinco semanas sin SELinux
El drop-in 99-hardening.conf quita a la base casi todo lo que no necesita: ninguna capability (un servidor en el puerto 3306 no necesita ninguna), NoNewPrivileges, un sistema de ficheros de solo lectura salvo el directorio de datos y el de logs, un filtro de llamadas al sistema, ningún acceso a parámetros del kernel, módulos o logs, MemoryDenyWriteExecute.
La unidad de la distribución arranca MariaDB mediante /bin/sh -c "… galera_recovery …; exec mariadbd". Con NoNewPrivileges, SELinux deniega la transición de dominio del shell (initrc_t) a mysqld_t, salvo que la política la permita expresamente – y no lo hace. Resultado: del 11 de septiembre al 16 de octubre de 2026 MariaDB corrió como initrc_t, un dominio que SELinux apenas restringe, mientras cada comprobación decía «enforcing». La solución es una línea: ExecStart=/usr/sbin/mariadbd $MYSQLD_OPTS, arrancado directamente por systemd, sin el shell que solo existe para clústeres Galera. El deep dive de SELinux cuenta la historia completa; la lección para cualquier endurecimiento: comprobar ps -eZ, no solo el modo.
Cuentas
- El usuario de la aplicación solo puede conectarse desde la red de pods (
10.42.%), no desde cualquier sitio. - Las cuentas anónimas, la base
testy un permiso proxy sobre un nombre de host, queskip_name_resolvedejó sin sentido, están eliminados. - Cada exportador tiene su propio usuario con permisos mínimos (
PROCESS,BINLOG MONITOR,SELECT) – en los hosts Nextcloud el exportador reutilizaba antes la contraseña de root, así que su fichero de configuración contenía de hecho la contraseña de root. - Root en el host se autentica mediante
/root/.my.cnf; en el pod la contraseña de root viene de un Secret de Kubernetes montado como fichero, no como variable de entorno.
📊 Medido
| Blog | Nextcloud A (mayor) | Nextcloud B | |
|---|---|---|---|
| Versión | 10.11.19 | 10.11.19 | 10.11.19 |
| Datos + índices | 47 MB | 361 MB | 58 MB |
| Buffer pool | 384 MB | 2 GB | 512 MB |
| Buffer pool sin usar | 87 % | 84 % | 89 % |
| Tasa de aciertos desde el reinicio (~9–11 h) | 99,70 % | 99,45 % | 99,66 % |
| Tablas temporales en «disco» (tmpfs) | 3,3 % | 6,0 % | 4,1 % |
| Pico de conexiones | 6 | 15 | 10 |
| Consultas lentas (> 1 s) | 0 | 0 | 0 |
Estas bases son pequeñas. Toda la base Nextcloud del servidor mayor cabe cinco veces en su buffer pool, y la tasa de aciertos supera el 99 % a las pocas horas – los fallos son casi todos la primera lectura tras el reinicio de la mañana. Ninguna consulta tardó más de un segundo. Dos conclusiones: afinar más allá de lo hecho aquí no aportaría nada medible, y los buffer pools son generosos; en el servidor mayor podría bajar a 1 GB y devolver memoria – con 23 GB de RAM no hay motivo.
🧰 Operación diaria
# host (Nextcloud): root via /root/.my.cnf
mariadb -e "SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_read%'"
mariadb -e "SHOW ENGINE INNODB STATUS\G" | less
tail -f /var/log/mariadb/slow.log
# pod (blog): root password from the mounted Secret
k3s kubectl -n wordpress exec -it deploy/mariadb -c mariadb -- \
sh -c 'MYSQL_PWD="$(cat /etc/secrets/db-root-password)" mariadb -uroot'
# is it confined?
ps -eZ | grep mariadbd
# a consistent dump without locking the application
mariadb-dump --single-transaction --quick --routines --events nextcloud | gzip > nc.sql.gzCopias de seguridad
Una máquina de copias recoge cada noche por SSH un volcado de cada base (--single-transaction toma una instantánea coherente sin bloquear las tablas InnoDB), conserva los 14 últimos tras comprobar que cada uno está completo y versiona todo durante 365 días. Restaurar es gunzip < dump | mariadb nextcloud en una base vacía – probado, no supuesto.
Actualizaciones
Dentro de la serie, el paquete del host viene del repositorio fijado y dnf-automatic instala las correcciones de seguridad; el pod del blog sigue el pin de imagen en versions.yml. Cambiar de serie – a la siguiente LTS – es un paso deliberado: primero el volcado, luego cambiar el repositorio o la imagen, arrancar, ejecutar mariadb-upgrade, comprobar la aplicación.
Contraseñas
Todas las contraseñas de las bases están en el vault de Ansible. Cambiar una significa: modificarla en el vault y ejecutar el playbook – pone la nueva contraseña en MariaDB y en la configuración de la aplicación en la misma ejecución.
🆘 Chuleta: síntoma → comando
La versión corta de este artículo para el momento en que algo va mal. Ejecutar en el host como root; <…> son marcadores.
| Síntoma | Comando |
|---|---|
| ¿Está en marcha, y confinada? | systemctl status mariadb |
| No arranca | journalctl -u mariadb -n 50 |
| La aplicación va lenta | tail -f /var/log/mariadb/slow.log |
| Bloqueos o deadlocks | mariadb -e "SHOW ENGINE INNODB STATUS\G" | less |
| ¿Es suficiente el buffer pool? | mariadb -e "SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_read%'" |
| Una consola SQL en el blog | k3s kubectl -n wordpress exec -it deploy/mariadb -c mariadb -- \ |
| Un volcado antes de un cambio | mariadb-dump --single-transaction --quick --routines --events nextcloud | gzip > nc.sql.gz |
| ¿Están bien las tablas? | mariadb-check --all-databases |
| Sin gráficos de base de datos en Grafana | systemctl status mysqld_exporter |
🔭 Lo que viene
- Recuperación a un instante concreto. Con el log binario activado, una restauración podría llegar a cualquier segundo entre dos volcados nocturnos. Con estos volúmenes de escritura basta el volcado nocturno; sería el primer cambio si eso dejara de ser cierto.
- La siguiente serie LTS bastante antes de febrero de 2028, probada primero en el servidor Nextcloud pequeño.
- Análisis de consultas con el performance schema en Grafana – hoy no hay nada lento que analizar.
⚖️ Alternativas – y por qué MariaDB
| Opción | Punto fuerte | Por qué no aquí |
|---|---|---|
| PostgreSQL | Excelente base, Nextcloud la admite | WordPress no la admite de forma nativa; dos motores para dos aplicaciones duplicarían la operación. |
| MySQL 8 | El original, admitido por ambas | Dirigido por un solo fabricante, funciones que se alejan de MariaDB; ninguna ventaja para estas cargas. |
| SQLite | Ningún servidor | Bien para pruebas, no para un Nextcloud multiusuario con escrituras concurrentes. |
| MariaDB 10.11 LTS | Admitida por ambas, gobernanza comunitaria, serie de largo plazo | Elegida. |
MariaDB es el componente menos emocionante de esta instalación, y eso es un elogio. Los hallazgos interesantes no estaban en la base, sino a su alrededor: en la unidad del sistema que la arrancaba, en el kernel que desactivaba una interfaz de E/S, en el directorio donde se escribían las tablas temporales. La base en sí simplemente hizo su trabajo – sin una sola consulta de más de un segundo.


