--- title: "Cómo instalar MySQL o MariaDB en Ubuntu 24.04" description: "Instala MySQL 8.0 o MariaDB en Ubuntu 24.04, asegura la instalación, crea una base de datos y un usuario, ajusta el rendimiento y programa copias de seguridad." category: "Gestión de Bases de Datos" language: es source: https://cubepath.com/es/docs/gestión-de-bases-de-datos/instalacion-y-configuracion-de-mysql-mariadb updated: 2026-09-25 --- # Cómo instalar MySQL o MariaDB en Ubuntu 24.04 MySQL y MariaDB son los servidores de bases de datos relacionales más usados en aplicaciones web: WordPress, Laravel, Magento o Nextcloud funcionan con cualquiera de los dos. En este tutorial instalarás uno de ellos en Ubuntu 24.04 desde los repositorios oficiales de Ubuntu, lo asegurarás, crearás una base de datos con su propio usuario, ajustarás los parámetros básicos de rendimiento y programarás copias de seguridad diarias. ## Requisitos previos - Un servidor con Ubuntu 24.04 LTS, por ejemplo un VPS de CubePath. - Un usuario no root con privilegios `sudo`. - Al menos 1 GB de RAM; 2 GB o más si la base de datos va a tener carga real. ### ¿MySQL o MariaDB? MariaDB nació como una bifurcación de MySQL y ambos son compatibles a nivel de cliente y de SQL básico, pero sus versiones actuales ya divergen en funciones avanzadas. En Ubuntu 24.04 los repositorios incluyen: | | MySQL | MariaDB | |---|---|---| | Paquete | `mysql-server` | `mariadb-server` | | Versión en Ubuntu 24.04 | 8.0 | 10.11 LTS | | Cliente | `mysql` | `mariadb` (también `mysql`) | | Configuración del servidor | `/etc/mysql/mysql.conf.d/` | `/etc/mysql/mariadb.conf.d/` | | Servicio systemd | `mysql` | `mariadb` | Si tu aplicación indica uno en concreto, instala ese. Si no, cualquiera sirve. No instales los dos en el mismo servidor: usan el mismo puerto y los mismos directorios. ## Paso 1: Instalar el servidor Actualiza el índice de paquetes: ```bash sudo apt update ``` Instala **MySQL**: ```bash sudo apt install mysql-server ``` O instala **MariaDB**: ```bash sudo apt install mariadb-server ``` El servicio se arranca y se habilita automáticamente. Compruébalo (usa `mariadb` en lugar de `mysql` si instalaste MariaDB): ```bash sudo systemctl status mysql ``` ```output ● mysql.service - MySQL Community Server Loaded: loaded (/usr/lib/systemd/system/mysql.service; enabled; preset: enabled) Active: active (running) since Thu 2026-09-25 10:02:11 UTC; 15s ago ``` Pulsa `q` para salir. Comprueba la versión instalada: ```bash mysql --version ``` ```output mysql Ver 8.0.43-0ubuntu0.24.04.1 for Linux on x86_64 ((Ubuntu)) ``` ## Paso 2: Asegurar la instalación Ambos servidores incluyen un script que elimina usuarios anónimos, la base de datos de prueba y el acceso remoto de root. En Ubuntu, el usuario `root` de la base de datos se autentica por socket: solo el usuario root del sistema (o con `sudo`) puede entrar como root en la base de datos, sin contraseña. Es más seguro que una contraseña y conviene mantenerlo así. En **MySQL**, ejecuta: ```bash sudo mysql_secure_installation ``` Responde a las preguntas: - **VALIDATE PASSWORD component**: si respondes `y`, MySQL rechazará contraseñas débiles para los nuevos usuarios. Elige el nivel `1` (MEDIUM) o `2` (STRONG). - El script indica que se omite la contraseña de root porque usa `auth_socket`. Es lo esperado. - **Remove anonymous users**, **Disallow root login remotely**, **Remove test database** y **Reload privilege tables**: responde `y` a todas. En **MariaDB**, el script se llama distinto: ```bash sudo mariadb-secure-installation ``` Pulsa `Enter` cuando pida la contraseña actual de root (no tiene). Responde `n` a **Switch to unix_socket authentication** (ya la usa) y a **Change the root password**, y `y` al resto de preguntas. Verifica que puedes entrar como root con `sudo`: ```bash sudo mysql ``` ```output Welcome to the MySQL monitor. Commands end with ; or \g. ... mysql> ``` Escribe `exit` para salir. Sin `sudo`, `mysql -u root` debe fallar con `ERROR 1698 (28000): Access denied`, lo que confirma que root solo es accesible localmente con privilegios del sistema. ## Paso 3: Crear una base de datos y un usuario Cada aplicación debe tener su propia base de datos y un usuario con permisos solo sobre ella, nunca usar root. Entra en la consola: ```bash sudo mysql ``` Crea la base de datos con `utf8mb4`, la codificación que admite todos los caracteres Unicode, incluidos los emojis: ```sql CREATE DATABASE app_db CHARACTER SET utf8mb4; ``` Crea el usuario. Sustituye `your_strong_password` por una contraseña larga y aleatoria (puedes generarla con `openssl rand -base64 24`): ```sql CREATE USER 'app_user'@'localhost' IDENTIFIED BY 'your_strong_password'; GRANT ALL PRIVILEGES ON app_db.* TO 'app_user'@'localhost'; FLUSH PRIVILEGES; exit ``` `'app_user'@'localhost'` significa que este usuario solo puede conectarse desde el propio servidor, que es lo correcto cuando la aplicación se ejecuta en la misma máquina. Comprueba que el usuario funciona: ```bash mysql -u app_user -p app_db -e "SELECT CURRENT_USER(), DATABASE();" ``` ```output +--------------------+------------+ | CURRENT_USER() | DATABASE() | +--------------------+------------+ | app_user@localhost | app_db | +--------------------+------------+ ``` ## Paso 4: Ajustar la configuración En lugar de modificar los archivos del paquete, crea uno propio con un nombre que se lea al final para que sus valores prevalezcan. Para **MySQL**: ```bash sudo nano /etc/mysql/mysql.conf.d/99-custom.cnf ``` Para **MariaDB**, crea el mismo archivo en `/etc/mysql/mariadb.conf.d/99-custom.cnf`. El contenido es igual para ambos: ```ini [mysqld] # Memoria para caché de datos e índices de InnoDB. # En un servidor dedicado a la base de datos, entre el 50 % y el 70 % de la RAM. # En un servidor compartido con la web, alrededor del 25 %. innodb_buffer_pool_size = 1G # Conexiones simultáneas máximas (el valor por defecto es 151) max_connections = 200 # Registrar consultas que tardan más de 1 segundo slow_query_log = 1 slow_query_log_file = /var/log/mysql/mysql-slow.log long_query_time = 1 # Codificación por defecto para bases de datos nuevas character-set-server = utf8mb4 ``` Los valores de ejemplo son para un servidor de 4 GB compartido con la aplicación; adáptalos a tu RAM. Un `innodb_buffer_pool_size` demasiado alto provoca que el sistema se quede sin memoria y el kernel mate el proceso. Reinicia el servicio para aplicar los cambios (`mariadb` si usas MariaDB): ```bash sudo systemctl restart mysql ``` Verifica que se han aplicado: ```bash sudo mysql -e "SHOW VARIABLES WHERE Variable_name IN ('innodb_buffer_pool_size','max_connections','slow_query_log');" ``` ```output +-------------------------+------------+ | Variable_name | Value | +-------------------------+------------+ | innodb_buffer_pool_size | 1073741824 | | max_connections | 200 | | slow_query_log | ON | +-------------------------+------------+ ``` Si el servicio no arranca, revisa el error con `sudo journalctl -u mysql -n 30` (o `-u mariadb`); normalmente es un nombre de variable mal escrito. ## Paso 5: Permitir conexiones remotas (opcional) Por defecto el servidor solo escucha en `127.0.0.1`, lo que impide cualquier conexión desde fuera. Si tu aplicación está en la misma máquina, sáltate este paso. Si está en otro servidor, abre el acceso solo para esa IP. Añade la dirección de escucha en tu archivo `99-custom.cnf`, dentro de `[mysqld]`: ```ini bind-address = 0.0.0.0 ``` Si el servidor tiene una red privada con la máquina de la aplicación, usa su IP privada en lugar de `0.0.0.0`. Reinicia el servicio y crea un usuario limitado a la IP de la aplicación, representada aquí como `203.0.113.10`: ```bash sudo systemctl restart mysql sudo mysql ``` ```sql CREATE USER 'app_user'@'203.0.113.10' IDENTIFIED BY 'your_strong_password'; GRANT ALL PRIVILEGES ON app_db.* TO 'app_user'@'203.0.113.10'; FLUSH PRIVILEGES; exit ``` Permite el puerto 3306 en el firewall solo para esa IP: ```bash sudo ufw allow from 203.0.113.10 to any port 3306 proto tcp ``` Nunca abras el puerto 3306 a todo Internet: los bots prueban contraseñas contra él continuamente. Comprueba que el servidor escucha en la nueva dirección: ```bash sudo ss -tlnp | grep 3306 ``` ```output LISTEN 0 151 0.0.0.0:3306 0.0.0.0:* users:(("mysqld",pid=4121,fd=23)) ``` Desde el servidor de la aplicación, prueba la conexión con `mysql -h your_server_ip -u app_user -p app_db`. > Nota: MySQL 8.0 genera un certificado autofirmado al instalarse y cifra las conexiones remotas con TLS si el cliente lo admite. En MariaDB 10.11 el cifrado no viene activado por defecto; si la conexión va por Internet y no por una red privada, configura TLS o usa un túnel SSH o WireGuard. ## Paso 6: Programar copias de seguridad `mysqldump` (en MariaDB también disponible como `mariadb-dump`) genera un volcado SQL que puedes restaurar en cualquier servidor. Con `--single-transaction` obtiene una copia coherente de las tablas InnoDB sin bloquearlas. Crea el directorio de copias, accesible solo para root: ```bash sudo install -d -m 700 /var/backups/mysql ``` Crea el script: ```bash sudo nano /usr/local/bin/mysql-backup.sh ``` ```bash #!/usr/bin/env bash set -euo pipefail BACKUP_DIR="/var/backups/mysql" RETENTION_DAYS=7 STAMP="$(date +%F_%H%M)" # Volcar cada base de datos de usuario en su propio archivo comprimido mysql -N -e "SHOW DATABASES" | grep -Ev '^(information_schema|performance_schema|mysql|sys)$' | while read -r db; do mysqldump --single-transaction --routines --triggers --events "$db" | gzip > "${BACKUP_DIR}/${db}_${STAMP}.sql.gz" done # Borrar copias más antiguas que la retención find "$BACKUP_DIR" -name '*.sql.gz' -mtime +"$RETENTION_DAYS" -delete ``` El script se ejecuta como root, que accede a la base de datos por socket, así que no necesita contraseñas en ningún archivo. Hazlo ejecutable y pruébalo: ```bash sudo chmod 700 /usr/local/bin/mysql-backup.sh sudo /usr/local/bin/mysql-backup.sh sudo ls -lh /var/backups/mysql ``` ```output -rw-r--r-- 1 root root 1.2K Sep 25 10:40 app_db_2026-09-25_1040.sql.gz ``` Prográmalo a diario a las 3:30 con cron: ```bash echo '30 3 * * * root /usr/local/bin/mysql-backup.sh' | sudo tee /etc/cron.d/mysql-backup ``` Para restaurar una copia en una base de datos existente: ```bash gunzip < /var/backups/mysql/app_db_2026-09-25_1040.sql.gz | sudo mysql app_db ``` > Importante: una copia guardada en el mismo disco que la base de datos no te protege si pierdes el servidor. Copia `/var/backups/mysql` a otro sistema, por ejemplo con `rsync` o `rclone` a un almacenamiento de objetos, y prueba la restauración de vez en cuando. ## Solución de problemas **ERROR 1698 (28000): Access denied for user 'root'@'localhost'.** Estás intentando entrar como root sin `sudo`. Usa `sudo mysql`. Para las aplicaciones, crea un usuario propio como en el paso 3. **ERROR 1045 (28000): Access denied for user 'app_user'@'...'.** La contraseña es incorrecta o el usuario no existe para ese host. Un usuario `'app_user'@'localhost'` no sirve para conexiones remotas. Lista los usuarios con `sudo mysql -e "SELECT user, host FROM mysql.user;"`. **ERROR 2003: Can't connect to MySQL server.** El servicio no está en marcha, escucha solo en `127.0.0.1` o el firewall bloquea el puerto. Revisa `systemctl status`, la salida de `ss -tlnp` y las reglas con `sudo ufw status`. **El servicio se reinicia solo o lo mata el sistema.** Busca `Out of memory` en `sudo journalctl -k | grep -i oom`. Reduce `innodb_buffer_pool_size` o añade RAM. **Consultas lentas.** Revisa `/var/log/mysql/mysql-slow.log` y analiza las consultas que aparecen con `EXPLAIN`. Casi siempre falta un índice. ## Conclusión Tienes MySQL o MariaDB instalado y asegurado, con root accesible solo por socket, un usuario dedicado para tu aplicación, parámetros de memoria adaptados al servidor, registro de consultas lentas y copias de seguridad diarias con rotación. Como siguientes pasos puedes: - Copiar las copias de seguridad fuera del servidor y documentar el procedimiento de restauración. - Usar `mysqldumpslow` sobre el log de consultas lentas para priorizar qué optimizar. - Configurar una réplica para alta disponibilidad o para descargar las consultas de lectura.