Ajustar MySQL/MariaDB con my.cnf para mejor rendimiento
Dedicados & VPS
24

Por qué ajustar MySQL

La configuración por defecto de MySQL/MariaDB está pensada para funcionar en cualquier máquina — incluso una con 512 MB de RAM. Eso significa que en un servidor con 4, 8 o 16 GB, MySQL está desaprovechando recursos. Ajustando unos pocos parámetros clave puedes duplicar o triplicar el rendimiento de consultas sin cambiar nada del código de la aplicación.

Dónde está la configuración

  • Debian/Ubuntu: /etc/mysql/mariadb.conf.d/50-server.cnf o /etc/mysql/my.cnf
  • CentOS/Rocky: /etc/my.cnf.d/server.cnf o /etc/my.cnf
  • cPanel: /etc/my.cnf

Los cambios van dentro de la sección [mysqld]. Después de editar hay que reiniciar el servicio:

sudo systemctl restart mariadb   # o mysql

El parámetro más importante: innodb_buffer_pool_size

InnoDB es el motor de almacenamiento por defecto. Usa un "buffer pool" — un área de memoria RAM donde guarda datos e índices accedidos recientemente para evitar leerlos del disco constantemente. Este parámetro define cuánta RAM se le asigna.

Regla general:

  • Servidor dedicado a MySQL: asigna 70% de la RAM al buffer pool.
  • Servidor compartido con aplicación: asigna 30-50%.
  • Servidor pequeño o VPS con 1-2 GB: 25-35%.
innodb_buffer_pool_size = 2G

Si el buffer pool puede contener toda tu base de datos, las consultas casi nunca tocan el disco y el rendimiento es excelente.

innodb_log_file_size

Tamaño del archivo de transacciones. Más grande = mejor rendimiento en escrituras, pero más tiempo de recuperación si el servidor se cae. Valores razonables:

innodb_log_file_size = 256M

Para servidores con mucho tráfico de escrituras, puedes subir a 512M o 1G.

innodb_flush_log_at_trx_commit

Determina cuándo se escribe al disco físico el log de transacciones:

  • 1 (por defecto) — flush en cada transacción. Máxima durabilidad, mínima pérdida en caída.
  • 2 — flush cada segundo. Rendimiento mucho mejor, pérdida máxima de 1 segundo de datos en caída del servidor.
  • 0 — flush cada segundo sin importar transacciones. Máximo rendimiento, pérdida potencial de 1 segundo.

Para aplicaciones donde perder 1 segundo de datos no es crítico (blogs, tiendas pequeñas), el valor 2 acelera notablemente las escrituras:

innodb_flush_log_at_trx_commit = 2

max_connections

Número máximo de conexiones simultáneas permitidas. Por defecto suele ser 150. Cada conexión consume memoria propia — calcula cuánto necesitan tus aplicaciones:

max_connections = 200

Subirlo mucho (a 1000, 2000) no mejora rendimiento — solo consume más RAM. Si llegas al límite, el problema suele ser consultas lentas que mantienen conexiones ocupadas, no falta de conexiones.

query_cache_type y query_cache_size

Nota importante: en MySQL 8.0+ el query cache fue eliminado. En MariaDB sigue disponible pero se recomienda no usarlo en servidores con concurrencia alta porque genera contención. Para versiones donde está disponible y el tráfico es moderado:

query_cache_type = 1
query_cache_size = 64M
query_cache_limit = 2M

Si tienes mucha concurrencia (muchos usuarios escribiendo simultáneamente), mejor desactivarlo:

query_cache_type = 0
query_cache_size = 0

tmp_table_size y max_heap_table_size

Tamaño máximo de tablas temporales en memoria. Si una query necesita una tabla temporal más grande, MySQL la crea en disco — mucho más lento.

tmp_table_size = 64M
max_heap_table_size = 64M

Mantén ambos valores iguales — MySQL usa el menor de los dos.

innodb_file_per_table

Por defecto ya activo en versiones modernas. Hace que cada tabla InnoDB viva en su propio archivo .ibd en lugar de estar todas metidas en el fichero común ibdata1. Permite recuperar espacio al eliminar tablas y simplifica backups.

innodb_file_per_table = 1

slow_query_log

Registra las consultas que tardan más de X segundos — oro puro para detectar queries problemáticas:

slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 2
log_queries_not_using_indexes = 1

Activar logging de consultas sin índice (la última línea) te muestra cualquier query que haga un full table scan — casi siempre indica una optimización pendiente.

Ejemplo completo para 4 GB de RAM

[mysqld]
# Buffer pool — 40% de la RAM disponible
innodb_buffer_pool_size = 1536M
innodb_log_file_size = 256M
innodb_flush_log_at_trx_commit = 2
innodb_file_per_table = 1

# Conexiones
max_connections = 150
max_allowed_packet = 64M

# Tablas temporales
tmp_table_size = 64M
max_heap_table_size = 64M

# Threads
thread_cache_size = 50
table_open_cache = 4000

# Logs
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 2

# Seguridad
local_infile = 0

# Charset por defecto
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci

MySQLTuner — herramienta de recomendaciones

Un script perl gratuito que analiza tu instalación y sugiere ajustes basándose en uso real:

wget http://mysqltuner.pl/ -O mysqltuner.pl
perl mysqltuner.pl

Léelo con calma — te da recomendaciones sobre buffer pool, conexiones, queries lentas y más. Ejecútalo después de al menos 24 horas de uso normal para que las estadísticas sean representativas.

Precauciones al modificar my.cnf

  • Haz backup del archivo antes de editar. cp my.cnf my.cnf.bak
  • Cambia un parámetro por vez cuando estás aprendiendo. Así sabes cuál causó mejora o problema.
  • Verifica que el servicio reinicia limpio después del cambio: systemctl status mariadb
  • Si MySQL no arranca tras un cambio, revisa /var/log/mysql/error.log — te dirá exactamente qué línea está mal.

Qué NO hacer

  • No copiar configuraciones "mágicas" de internet sin entender qué hacen. Cada servidor tiene distinto hardware y cargas.
  • No poner valores altísimos "por las dudas" — consume RAM que no vas a usar y puedes llegar a causar OOM (out of memory) del sistema.
  • No desactivar InnoDB. Es el motor por defecto por buenas razones.
  • No ignorar el slow query log — ahí están tus optimizaciones reales pendientes.