--- title: "Cómo configurar huge pages para PostgreSQL y MySQL en Ubuntu" description: "Calcula y reserva huge pages en Ubuntu 24.04, haz que PostgreSQL y MySQL las usen para su memoria compartida y comprueba en /proc/meminfo que están en uso." category: "Temas Avanzados" language: es source: https://cubepath.com/es/docs/temas-avanzados/configuracion-de-huge-pages-para-bases-de-datos updated: 2026-09-25 --- # Cómo configurar huge pages para PostgreSQL y MySQL en Ubuntu Linux gestiona la memoria en páginas de 4 KB por defecto. Una base de datos con 16 GB de `shared_buffers` necesita más de cuatro millones de esas páginas, y cada acceso a memoria depende de que su traducción esté en la TLB de la CPU, que es pequeña. Las huge pages de 2 MB reducen el número de entradas 512 veces, lo que baja los fallos de TLB y el tamaño de las tablas de páginas de cada proceso. En este tutorial reservarás huge pages en Ubuntu 24.04, configurarás PostgreSQL 16 (y opcionalmente MySQL 8.0) para usarlas y verificarás que la memoria compartida está realmente en huge pages. ## Requisitos previos Para seguir esta guía necesitas: - Un servidor con Ubuntu 24.04 LTS, por ejemplo un VPS o un servidor dedicado de CubePath, con un usuario no root con privilegios `sudo`. - PostgreSQL 16 instalado desde los repositorios de Ubuntu (`sudo apt install postgresql`) o MySQL 8.0 (`sudo apt install mysql-server`). - Memoria suficiente: la ganancia se nota con buffers de varios GB. Con menos de 4 GB de RAM el beneficio es muy pequeño. > Importante: La memoria reservada como huge pages deja de estar disponible para el resto del sistema, aunque la base de datos no la use. Reserva solo lo que la base de datos necesita. ## Paso 1: Revisar el estado actual de la memoria Comprueba el tamaño de huge page por defecto y cuántas hay reservadas: ```bash grep -i huge /proc/meminfo ``` ```output AnonHugePages: 0 kB ShmemHugePages: 0 kB FileHugePages: 0 kB HugePages_Total: 0 HugePages_Free: 0 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB Hugetlb: 0 kB ``` `Hugepagesize: 2048 kB` indica páginas de 2 MB, que es lo que usarás en esta guía. `HugePages_Total: 0` significa que aún no hay ninguna reservada. Mira también el modo de las Transparent Huge Pages (THP), que son un mecanismo distinto que el kernel aplica de forma automática: ```bash cat /sys/kernel/mm/transparent_hugepage/enabled ``` ```output always [madvise] never ``` Ubuntu usa `madvise` por defecto: el kernel solo usa THP en la memoria que la aplicación marca expresamente. Es el valor adecuado para un servidor de bases de datos, así que no lo cambies. Las huge pages que vas a configurar aquí son explícitas (`hugetlbfs`), se reservan por adelantado y no se ven afectadas por este ajuste. ## Paso 2: Calcular cuántas huge pages necesita PostgreSQL PostgreSQL coloca en huge pages su segmento principal de memoria compartida, cuyo tamaño depende sobre todo de `shared_buffers`. Un punto de partida habitual es el 25 % de la RAM. Por ejemplo, en un servidor con 16 GB: ```bash sudo -u postgres psql -c "ALTER SYSTEM SET shared_buffers = '4GB';" ``` Reinicia PostgreSQL para que el nuevo tamaño se aplique: ```bash sudo systemctl restart postgresql ``` Desde PostgreSQL 15 el propio servidor calcula cuántas huge pages necesita para su memoria compartida: ```bash sudo -u postgres psql -c "SHOW shared_memory_size_in_huge_pages;" ``` ```output shared_memory_size_in_huge_pages ---------------------------------- 2138 (1 row) ``` Apunta este número. Reserva un pequeño margen por encima (un 2 o 3 %) para no tener que recalcular si cambias algún parámetro menor. En el ejemplo, 2200 páginas de 2 MB son unos 4,3 GB. ## Paso 3: Reservar las huge pages en el kernel Crea un archivo de sysctl propio para que la reserva se mantenga tras un reinicio: ```bash sudo nano /etc/sysctl.d/60-hugepages.conf ``` Añade la línea con el número de páginas calculado: ```ini vm.nr_hugepages = 2200 ``` Aplica la configuración: ```bash sudo sysctl -p /etc/sysctl.d/60-hugepages.conf ``` ```output vm.nr_hugepages = 2200 ``` Comprueba que el kernel ha podido reservarlas todas: ```bash grep -E 'HugePages_(Total|Free)' /proc/meminfo ``` ```output HugePages_Total: 2200 HugePages_Free: 2200 ``` Si `HugePages_Total` es menor que el valor pedido, la memoria está fragmentada y el kernel no encuentra bloques contiguos de 2 MB. Consulta la sección de solución de problemas. ## Paso 4: Obligar a PostgreSQL a usar huge pages El valor por defecto de `huge_pages` es `try`: PostgreSQL intenta usarlas y, si no puede, arranca en silencio con páginas normales. Ponlo en `on` para que falle al arrancar en lugar de degradar el rendimiento sin avisar: ```bash sudo -u postgres psql -c "ALTER SYSTEM SET huge_pages = 'on';" ``` Reinicia el servicio: ```bash sudo systemctl restart postgresql ``` Comprueba que el clúster está en marcha: ```bash sudo systemctl status postgresql@16-main --no-pager ``` ```output ● postgresql@16-main.service - PostgreSQL Cluster 16-main Loaded: loaded (/usr/lib/systemd/system/postgresql@.service; enabled-runtime; preset: enabled) Active: active (running) since ... ``` Si el servicio no arranca, revisa el log. El error típico cuando faltan páginas es este: ```bash sudo tail -n 20 /var/log/postgresql/postgresql-16-main.log ``` ```output FATAL: could not map anonymous shared memory: Cannot allocate memory HINT: This error usually means that PostgreSQL's request for a shared memory segment exceeded available memory, swap space, or huge pages. ``` En ese caso aumenta `vm.nr_hugepages` en `/etc/sysctl.d/60-hugepages.conf`, vuelve a aplicarlo y reinicia PostgreSQL. ## Paso 5: Verificar que la memoria compartida está en huge pages Con PostgreSQL arrancado, vuelve a mirar los contadores: ```bash grep -E 'HugePages_(Total|Free|Rsvd)' /proc/meminfo ``` ```output HugePages_Total: 2200 HugePages_Free: 2105 HugePages_Rsvd: 2043 ``` Estos números confirman que funciona: - `HugePages_Rsvd` pasa de 0 a casi el valor calculado en el paso 2: PostgreSQL ha reservado sus páginas. - `HugePages_Free` baja a medida que los backends tocan `shared_buffers`. Tras un rato de carga real, `Free` menos `Rsvd` queda cerca del margen que dejaste. Si `HugePages_Rsvd` sigue en 0, PostgreSQL no está usando huge pages: comprueba que `SHOW huge_pages;` devuelve `on` y que reiniciaste el servicio. ## Paso 6 (opcional): Configurar MySQL 8.0 con huge pages MySQL usa huge pages para el buffer pool de InnoDB a través de memoria compartida System V. Para eso el usuario `mysql` tiene que pertenecer al grupo autorizado por el kernel en `vm.hugetlb_shm_group`. Calcula las páginas a partir de `innodb_buffer_pool_size` más un 10 % de margen. Con un buffer pool de 4 GB: 4096 MB / 2 MB = 2048 páginas, más el margen, unas 2250. Si PostgreSQL y MySQL comparten servidor, suma ambas cifras en `vm.nr_hugepages`. Obtén el GID del usuario `mysql`: ```bash id -g mysql ``` ```output 110 ``` Edita el archivo del paso 3: ```bash sudo nano /etc/sysctl.d/60-hugepages.conf ``` Deja el número de páginas y el grupo, usando el GID que obtuviste: ```ini vm.nr_hugepages = 2250 vm.hugetlb_shm_group = 110 ``` Aplica los cambios: ```bash sudo sysctl -p /etc/sysctl.d/60-hugepages.conf ``` La documentación de MySQL recomienda además quitar el límite de memoria bloqueada del proceso. Crea un override de systemd: ```bash sudo systemctl edit mysql ``` Añade estas líneas en la zona editable del archivo: ```ini [Service] LimitMEMLOCK=infinity ``` Activa las huge pages en la configuración de MySQL: ```bash sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf ``` Añade estas líneas dentro de la sección `[mysqld]`: ```ini innodb_buffer_pool_size = 4G large_pages = ON ``` Reinicia MySQL y comprueba la variable: ```bash sudo systemctl restart mysql sudo mysql -e "SHOW VARIABLES LIKE 'large_pages';" ``` ```output +---------------+-------+ | Variable_name | Value | +---------------+-------+ | large_pages | ON | +---------------+-------+ ``` La variable solo refleja la configuración. Para confirmar que la asignación ha funcionado, revisa que el log de errores no contiene avisos de HugeTLB y que `HugePages_Rsvd` o `HugePages_Free` han cambiado en `/proc/meminfo`: ```bash sudo grep -i hugetlb /var/log/mysql/error.log ``` Si no devuelve nada y los contadores se han movido, InnoDB está usando huge pages. Si ves `Failed to allocate`, faltan páginas o el GID de `vm.hugetlb_shm_group` no es el del usuario `mysql`. ## Paso 7 (opcional): Usar huge pages de 1 GB En servidores con mucha RAM (por ejemplo, `shared_buffers` de 64 GB o más), las páginas de 1 GB reducen todavía más la presión sobre la TLB. Primero comprueba que la CPU las admite: ```bash grep -m1 -o pdpe1gb /proc/cpuinfo ``` ```output pdpe1gb ``` Si no aparece nada, la CPU (o la CPU virtual que expone el hipervisor) no las soporta y debes quedarte con páginas de 2 MB. Las páginas de 1 GB se deben reservar al arrancar, cuando la memoria aún no está fragmentada. Edita GRUB: ```bash sudo nano /etc/default/grub ``` Añade los parámetros a la línea existente, ajustando el número de páginas a tu caso: ```ini GRUB_CMDLINE_LINUX_DEFAULT="hugepagesz=1G hugepages=16" ``` Si esa línea ya tenía otros valores (por ejemplo `quiet splash`), mantenlos y añade los nuevos separados por un espacio. Regenera la configuración de GRUB y reinicia: ```bash sudo update-grub sudo reboot ``` Tras el reinicio, comprueba la reserva en el directorio del tamaño de 1 GB: ```bash cat /sys/kernel/mm/hugepages/hugepages-1048576kB/nr_hugepages ``` ```output 16 ``` Por último, indica a PostgreSQL ese tamaño y reinícialo: ```bash sudo -u postgres psql -c "ALTER SYSTEM SET huge_page_size = '1GB';" sudo systemctl restart postgresql ``` Con páginas de 1 GB, elimina o reduce `vm.nr_hugepages` en `/etc/sysctl.d/60-hugepages.conf` para no reservar también páginas de 2 MB que nadie va a usar. ## Solución de problemas - **`HugePages_Total` se queda por debajo de lo pedido.** La memoria está fragmentada. Pide al kernel que compacte la memoria con `echo 1 | sudo tee /proc/sys/vm/compact_memory` y vuelve a aplicar el sysctl. Si sigue sin llegar, reinicia: el archivo de `/etc/sysctl.d/` se aplica al principio del arranque, cuando hay bloques libres de sobra. - **El sistema se queda sin memoria tras reservar las páginas.** Has reservado demasiadas. Las huge pages no se pueden usar para procesos normales ni para la caché de disco. Baja `vm.nr_hugepages`, deja al menos un 20-25 % de la RAM fuera de la reserva, porque PostgreSQL también depende de la caché de disco del sistema. - **PostgreSQL arranca pero `HugePages_Rsvd` es 0.** `huge_pages` sigue en `try` o el cambio no se aplicó. Ejecuta `SHOW huge_pages;` y reinicia el servicio (no basta con recargarlo). - **Has cambiado `shared_buffers`.** Repite el paso 2: el número de páginas necesario cambia con él. ## Conclusión Has reservado huge pages en Ubuntu 24.04, has calculado la cantidad exacta a partir de `shared_memory_size_in_huge_pages` y has configurado PostgreSQL para que no arranque sin ellas, con MySQL como alternativa. Para medir el efecto, ejecuta una carga representativa con `pgbench` antes y después del cambio, vigila `HugePages_Free` en tu sistema de monitorización (node_exporter publica `node_memory_HugePages_Free`) y revisa el cálculo cada vez que cambies el tamaño de los buffers.