IT-Admin.tech

Ajuste del kernel para bases de datos: THP, vm.swappiness y I/O‑Scheduler en la práctica

Architekturdiagramm eines Datenbankhosts mit Page-Cache, THP, Swap und Block-I/O-Queue vor einer NVMe-SSD
Technisches Diagramm: Transparent Hugepages, Page Cache, Swap und Block-I/O-Queue eines Datenbankhosts — NVMe-SSD als klares Artefakt für Storage-Entscheidungen.

Para bases de datos de producción estables, un ajuste dirigido del kernel para bases de datos suele ser más eficaz que simplemente escalar verticalmente. Tres parámetros del kernel afectan con especial fuerza al rendimiento y la latencia: Transparent Hugepages (THP), vm.swappiness y el I/O‑Scheduler. Esta guía práctica explica cómo funcionan estos mecanismos, qué impacto tienen sobre la operación, la monitorización y la seguridad, cómo medir los cambios, desplegarlos de forma segura y revertirlos —incluye indicaciones específicas para contenedores (Docker/Podman) y virtualización.

Kernel-Tuning für Datenbanken: Vor dem Tunen: Ziele, Metriken und Change-Plan

Antes de modificar parámetros del kernel, defina objetivos medibles (p. ej. reducción de p95/p99, estabilidad de los tiempos de fsync) y riesgos aceptables. Establezca KPIs que pueda recopilar automáticamente: latencias de consultas desde la base de datos, iostat/iowait del host, vmstat (si/so = Swap-In/Swap-Out), PSI (Pressure Stall Information — un mecanismo del kernel para medir la presión de CPU/memoria/E/S), así como logs del kernel (dmesg/journal). Sin una métrica clara, las conclusiones serán difíciles.

Kurze Baseline-Checks

Shell
# Systemübersicht
uname -r; cat /etc/os-release; systemd-detect-virt || true

# Speicher, Swap und PSI
free -h; swapon --show; vmstat 1 5; sudo cat /proc/pressure/memory

# I/O
lsblk -o NAME,TYPE,SIZE,ROTA,MOUNTPOINTS
iostat -xz 1 5 || true

# THP-Status
for f in /sys/kernel/mm/transparent_hugepage/enabled /sys/kernel/mm/transparent_hugepage/defrag; do
  [ -f "$f" ] && echo "$f: $(cat $f)"
done

Documente la información de versiones (Kernel, Distribution, Storage-Treiber), porque el comportamiento puede variar entre versiones del kernel.

Transparent Hugepages (THP): Mechanik, Risiken und Praxis

THP intenta reducir los fallos de TLB (TLB = Translation Lookaside Buffer, una caché de direcciones virtual→físicas) agrupando muchas páginas pequeñas en páginas grandes (típicamente de 2 MiB). Esto beneficia cargas numéricas intensivas, pero en bases de datos transaccionales puede generar pausas inesperadas: la defragmentación por el kernel y las operaciones de copia al consolidar páginas grandes provocan bloqueos temporales de CPU o memoria que aumentan significativamente las latencias p99.

Wann THP wahrscheinlich Probleme macht

  • Picos súbitos en p99 sin un desencadenante de E/S identificable.
  • Actividad de defrag del kernel o de kswapd con alta utilización de memoria.
  • Picos de latencia reproducibles con determinados perfiles de consulta.

Testen, Deaktivieren und Persistenz

Los cambios se pueden probar en tiempo de ejecución vía sysfs; en producción se deben emplear mecanismos persistentes y reversibles (systemd‑Unit, GRUB-Commandline o Initramfs-Anpassung).

Shell
# Laufzeit-Test: THP deaktivieren
echo never | sudo tee /sys/kernel/mm/transparent_hugepage/enabled
echo never | sudo tee /sys/kernel/mm/transparent_hugepage/defrag

# Kontrolle
cat /sys/kernel/mm/transparent_hugepage/enabled
cat /sys/kernel/mm/transparent_hugepage/defrag

Ejemplo de una unidad systemd breve y segura que desactiva THP en el arranque. Cree el contenido de la unidad como un archivo:

Shell
sudo tee /etc/systemd/system/disable-thp.service >/dev/null <<'EOF'
[Unit]
Description=Disable Transparent Huge Pages
After=network.target

[Service]
Type=oneshot
ExecStart=/bin/sh -c 'echo never > /sys/kernel/mm/transparent_hugepage/enabled'
ExecStart=/bin/sh -c 'echo never > /sys/kernel/mm/transparent_hugepage/defrag'
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable --now disable-thp.service

Alternativamente, puede establecer en GRUB el parámetro del kernel transparent_hugepage=never (ver la sección siguiente). Importante: pruebe con varios perfiles de carga y mida p95/p99 antes/después del cambio.

vm.swappiness: Comprensión, ajuste y riesgos

vm.swappiness es un parámetro del kernel (0–100) que describe cuán agresivamente el kernel volca memoria anónima a swap. Un valor bajo reduce el swapping en condiciones normales — a menudo recomendable para hosts de bases de datos, porque las latencias de swap ralentizan mucho las consultas. Sin embargo, no es automáticamente la mejor opción establecer vm.swappiness=0: en sistemas con RAM limitada o cargas mixtas, evitar el swap de forma agresiva puede provocar una recuperación de páginas más intensa, lo que aumenta la carga de CPU y de I/O.

Establecer y persistir

Shell
# Aktuellen Wert prüfen
sysctl vm.swappiness; cat /proc/sys/vm/swappiness

# Laufzeit setzen
sudo sysctl -w vm.swappiness=10

# Dauerhaft (sysctl.d)
sudo tee /etc/sysctl.d/99-db-tuning.conf >/dev/null <<'EOF'
# DB-Tuning: Swap-Verhalten
vm.swappiness = 10
EOF
sudo sysctl --system

Particularidades en contenedores y cgroups

En entornos con contenedores, el swapping inadecuado suele ser un problema derivado: un contenedor puede alcanzar el límite de cgroup aunque el host muestre RAM libre. En cgroup v1/v2 los parámetros y comportamientos difieren; configuraciones relevantes incluyen, entre otras, memory.swap.max y memory.high (cgroup v2). Los orquestadores (Kubernetes, Docker Engine) a veces aplican valores por defecto que afectan el comportamiento del contenedor.

Shell
# Docker: Memory-Limits prüfen und Container-Startbeispiel
docker inspect --format '{{.Name}}: Memory={{.HostConfig.Memory}} MemorySwap={{.HostConfig.MemorySwap}}' postgres

# Starten ohne zusätzliches Swap (Host verhindert swap usage durch MemorySwap)
docker run -d --name postgres 
  --memory=8g --memory-swap=8g 
  -v /srv/dbdata:/var/lib/postgresql/data 
  my-postgres-image

Recomendación: establezca límites coherentes para contenedores y host, pruebe el comportamiento OOM (Kernel OOM o systemd-oomd) y supervise dmesg/journal en busca de eventos OOM o de OOM-Killer.

Planificador de E/S: selección según tipo de almacenamiento y trampas

El planificador de E/S (I/O‑Scheduler) afecta el orden, la priorización y el encolamiento (queueing) de las operaciones de bloque. Los kernels Linux modernos utilizan Multi-Queue (blk-mq). Reglas típicas:

  • NVMe local: none (el planificador en el propio dispositivo suele ser mejor que el encolamiento Linux).
  • Discos virtuales (VirtIO, VMware): mq-deadline reduce los picos de latencia.
  • HDDs o cargas interactivas de escritorio: bfq puede ser sensible a la equidad y a la latencia.

Importante: en capas como LVM, Device-Mapper (dm‑crypt) o Multipath debe configurar el planificador en el nivel correcto — con frecuencia en el dispositivo físico, no en el dispositivo LVM.

Comprobar, establecer y persistir

Shell
# Aktuelle Scheduler
for d in /sys/block/*/queue/scheduler; do
  echo "${d%/queue/scheduler}: $(cat $d)"
done

# Laufzeit-Änderung (Beispiel für nvme0n1)
echo none | sudo tee /sys/block/nvme0n1/queue/scheduler

# Persistenz mit udev-Regel
sudo tee /etc/udev/rules.d/60-io-scheduler.rules >/dev/null <<'EOF'
ACTION=="add|change", KERNEL=="nvme*", ATTR{queue/scheduler}="none"
ACTION=="add|change", KERNEL=="sd[a-z]", ATTR{queue/scheduler}="mq-deadline"
EOF
sudo udevadm control --reload-rules; sudo udevadm trigger --type=devices --action=change

Tenga en cuenta las instancias en la nube (p. ej. AWS EBS gp3, Azure Managed Disks): el comportamiento subyacente puede estar virtualizado; pruebe con carga de trabajo real. En entornos multipath: configure el scheduler en los dispositivos de backend, no solo en /dev/mapper/…

Métodos de medición: pruebas y herramientas fiables

El Kernel-Tuning solo tiene sentido si mide con claridad el efecto. Utilice pruebas combinadas en host y DB:

  • Herramientas de carga de trabajo para DB: pgbench para PostgreSQL, sysbench para MySQL, suites de benchmarking nativas. Estas generan patrones de acceso más realistas que las herramientas sintéticas de I/O por sí solas.
  • Herramientas del host: iostat (await, %util), blktrace para análisis profundo de I/O a nivel de bloque, fio para perfiles de I/O controlados.
  • Observabilidad del kernel: /proc/pressure/* para PSI, profiling con eBPF (bcc, bpftrace) para hacer visibles stalls y colas.
Shell
# Beispiel: fio für fsync-stress (synchrones write + fsync)
fio --name=fsync-test --filename=/srv/dbdata/testfile --size=4G 
  --bs=4k --iodepth=1 --numjobs=1 --rw=write --direct=1 --fsync=1 --runtime=300

# Simplifiziertes pgbench-Laufbeispiel
docker exec -it postgres pgbench -c 50 -T 120 -r mydb

Importante: Ejecute las pruebas en una ventana temporal representativa (no solo de forma breve) para capturar el comportamiento p99.

Resolución de problemas: por qué el tuning no produce efecto

Si los cambios no producen mejora, compruebe:

  • ¿Está realmente el archivo de la base de datos en el dispositivo ajustado? (bind‑mounts, LVM, dm‑crypt, Multipath).
  • ¿Proviene la latencia del array de almacenamiento o de la red (NAS/SAN/Cloud)?
  • ¿Se consume tiempo de CPU en la propia DB (Locking, Checkpoints) en lugar de en la ruta de I/O del host?
  • ¿Son las cgroups de los contenedores, systemd-oomd o las políticas del orquestador la causa?

A menudo el Kernel-Tuning es solo una parte de un paquete de medidas más amplio: optimización del almacenamiento, ajuste de los valores de la DB (intervalos de checkpoint, background writer) y análisis de la ruta de I/O deben considerarse en conjunto.

Estrategia de rollback y script de ejemplo

Prepare siempre rollbacks automatizables. Guarde los valores actuales antes de modificar y proporcione una restauración sencilla.

Shell
#!/bin/bash
# rollback-tuning.sh - einfache Rücksetz-Routine
set -euo pipefail

echo "Sichern aktueller Werte..."
mkdir -p /root/kernel-tuning-backup
cat /sys/kernel/mm/transparent_hugepage/enabled > /root/kernel-tuning-backup/thp_enabled
cat /sys/kernel/mm/transparent_hugepage/defrag > /root/kernel-tuning-backup/thp_defrag
cat /proc/sys/vm/swappiness > /root/kernel-tuning-backup/swappiness
for d in /sys/block/*/queue/scheduler; do
  dev=${d%/queue/scheduler}
  cat $d > "/root/kernel-tuning-backup/$(basename $dev)_scheduler"
done

# Rollback-Schritte (Beispielwerte aus Backup zurücklesen)
echo "Rollback: THP zurücksetzen"
[ -f /root/kernel-tuning-backup/thp_enabled ] && cat /root/kernel-tuning-backup/thp_enabled | sudo tee /sys/kernel/mm/transparent_hugepage/enabled
[ -f /root/kernel-tuning-backup/thp_defrag ] && cat /root/kernel-tuning-backup/thp_defrag | sudo tee /sys/kernel/mm/transparent_hugepage/defrag

echo "Rollback: swappiness zurücksetzen"
[ -f /root/kernel-tuning-backup/swappiness ] && sudo sysctl -w vm.swappiness=$(cat /root/kernel-tuning-backup/swappiness)

# Hinweis: Scheduler-Rollback kann ein Reboot erfordern, je nach udev/driver

echo "Rollback abgeschlossen - prüfen Sie Logs und KPIs"

Documente los valores originales en su sistema de ticketing y realice tras el rollback una comprobación de validación de los KPIs.

Enfoque especial: Docker y cgroup v2

En escenarios con contenedores se aplica: la mayoría de las configuraciones del kernel se hacen efectivas a nivel del host; sin embargo, los permisos de los contenedores y la configuración de cgroup pueden alterar el comportamiento. En cgroup v2 las opciones relevantes bajo /sys/fs/cgroup son: memory.high (límite suave), memory.swap.max (Swap-Limit) y memory.max (límite estricto). Kubernetes usa clases de QoS (Guaranteed/Burstable/BestEffort): establezca Requests y Limits de forma clara para que los contenedores funcionen de manera predecible.

Shell
# Beispiel: Werte in cgroup v2 prüfen (Pfad kann je nach Engine variieren)
cat /sys/fs/cgroup//memory.high
cat /sys/fs/cgroup//memory.swap.max

# Kubernetes: PodSpec (Ausschnitt)
# requests/limits sicher definieren, um unerwarteten Swap zu vermeiden

Cree casos de prueba para escenarios OOM y compruebe cómo reaccionan sus políticas de orquestador (Eviction thresholds, PodDisruptionBudget).

Reglas prácticas de operación y recomendaciones

  • Cambie solo una variable del kernel por ventana de prueba, para que los efectos sean claramente atribuibles.
  • Automatice las copias de seguridad de los valores anteriores y los scripts de rollback.
  • En entornos con storage en la nube o SAN, compruebe primero si la fuente de latencia está fuera del host.
  • Utilice herramientas eBPF para visualizar breves bloqueos del kernel que las herramientas de monitorización suelen pasar por alto.
  • Mantenga las reglas de persistencia (sysctl.d, udev, systemd) versionadas en el repositorio de configuración.

Conclusión

Optimización del kernel para bases de datos es una tarea eficaz pero precisa: las Transparent Hugepages son una causa frecuente de picos p99, vm.swappiness debe ajustarse a la planificación de RAM y a la política de cgroup, y el I/O‑Scheduler debe elegirse según el tipo de almacenamiento. Trabaje de forma metódica: línea base, cambio dirigido, medición, prueba de persistencia (reinicio) y un plan claro de rollback. Solo así conseguirá mejoras reproducibles en Bare‑Metal, VMs y entornos de contenedores.

Este Runbook está pensado como un manual operativo: adapte los valores a su infraestructura, pruebe con cargas de trabajo reales y registre todos los pasos de forma revisable en su Change‑Management.

Operación, aspectos de actualización e integración

Además de los ajustes puntuales de parámetros, conviene integrar el Kernel‑Tuning en un contexto operativo más amplio: las actualizaciones de kernel y controladores, el nivel de NVMe/firmware, la topología NUMA y las configuraciones de base de datos interactúan fuertemente y pueden enmascarar o amplificar cambios. Antes de desplegar de forma amplia, compruebe la compatibilidad con los controladores de almacenamiento (nvme, virtio, multipath) y las versiones de firmware; algunos cambios de latencia están provocados por controladores o firmware y no se pueden resolver mediante sysctl.

Indicaciones de arquitectura

  • NUMA: Coloque preferentemente los DB‑Threads, el Page‑Cache y los archivos de datos en la misma NUMA‑Domain; una afinidad incorrecta incrementa el Cross‑node‑Traffic.
  • Configuración de BD: Alinee shared_buffers/innodb_buffer_pool de modo que el Host‑Page‑Cache y el caché de la BD no entren en conflicto; eso reduce reclamaciones (reclaims) innecesarias.
  • Cloud/Managed DB: En servicios gestionados a menudo no están disponibles las configuraciones del kernel — elija en su lugar clases de instancia adecuadas, Provisioned IOPS o opciones de almacenamiento especializadas.

Operación e integración de CI

Automatice las pruebas en su pipeline: ejecute corridas de fio/pgbench como parte de las release‑pipelines sobre una flota Canary reducida e integre la comparación de resultados (p50/p95/p99) en el reporting de CI. Versione sysctl.d, udev‑Rules y systemd‑Units en el repositorio de configuración y despliegue de forma idempotente con Ansible/Chef.

Lista de comprobación de monitorización

  • Alerta para PSI‑Memory > definida umbral (p. ej., 100ms) y para swap‑outs persistentes.
  • Monitoreo de tendencias: latencias p99, iowait, await y eventos OOM del kernel.
  • Auditoría: verificar parámetros del kernel y reglas udev mediante un escaneo de desviación de configuración (Configuration‑Drift‑Scan).

Estas perspectivas operativas garantizan que el Kernel‑Tuning forme parte de un change‑management fiable para su paisaje de software empresarial individual y no provoque efectos secundarios inesperados.

Para este tema también es importante desactivar Transparent Hugepages y configurar el I/O‑Scheduler Mq-Deadline Bfq None. El artículo sitúa estos aspectos de forma comprensible y muestra en qué hay que centrarse en el día a día.