Instalar MySQL en un VPS Windows Server
Para descargar el servidor MySQL 8 para Windows e instalarlo en un VPS Windows Server, Oracle ofrece un paquete MSI que instala el servidor y MySQL Configurator, la herramienta de configuración. Esta guía sigue ese método oficial, con la interfaz o desde la línea de comandos, y después abre el acceso remoto, ajusta el rendimiento, protege y hace copias de MySQL. MySQL Installer, que aún citan tutoriales antiguos, se queda en la rama 8.0.
Elegir la versión de MySQL
Oracle publica versiones LTS, mantenidas durante mucho tiempo, y versiones Innovation, que cambian rápido. En un servidor, elige una LTS.
| Rama | Tipo | Estado | Para quién |
|---|---|---|---|
| MySQL 8.0 | Antigua | Fin de vida desde abril de 2026 | Migra a 8.4 o 9.7 |
| MySQL 8.4 | LTS | Mantenida | La opción más segura, la mejor soportada por las herramientas |
| MySQL 9.7 | LTS | Publicada el 21 de abril de 2026 | Proyectos nuevos que quieren la rama más reciente |
Esta guía toma MySQL 8.4 LTS como ejemplo. Instala el último parche de la rama, indicado en la página de descargas de MySQL. Para 9.7, el procedimiento es el mismo, con 9.7 en lugar de 8.4 en las rutas.
Preparar el VPS
Windows Server 2025, o 2019 y 2022 en un servidor más antiguo.
2 GB de memoria como mínimo, 4 GB para un uso real.
Un acceso de administrador por Escritorio remoto.
El redistribuible de Microsoft Visual C++ x64, que exige MySQL 8.4. Instálalo desde la web de Microsoft si falta.
Comprueba que el puerto 3306 está libre. Si el comando no muestra nada, ningún programa lo usa.
netstat -ano | findstr :3306
Instalar MySQL con el MSI y MySQL Configurator
Los textos de MySQL Configurator están en inglés.
En la página de descargas, elige la versión 8.4 LTS y Microsoft Windows, y descarga el MSI Installer de 64 bits.
Ejecuta el MSI y elige la instalación Typical. El servidor se instala en
C:\Program Files\MySQL\MySQL Server 8.4.Al final, deja marcada la apertura de MySQL Configurator. El servidor no arranca hasta que está configurado.
En Type and Networking, elige el tipo Dedicated si MySQL está solo en el VPS, o Server si comparte el VPS con IIS o una aplicación. Mantén TCP/IP en el puerto
3306. Desmarca Open Windows Firewall port for network access si ninguna máquina externa debe conectarse.En Accounts and Roles, da a la cuenta
rootuna contraseña larga y compleja, y guárdala en un gestor de contraseñas.En Windows Service, mantén Configure MySQL server as a Windows service y llama al servicio
MySQL84, el nombre que usa el resto de la guía. Mantén Start the MySQL Server at System Startup.Mantén los permisos por defecto en Server File Permissions y haz clic en Execute en Apply Configuration.
MySQL 8.4 usa la autenticación caching_sha2_password. El antiguo mysql_native_password está desactivado por defecto. Si un cliente antiguo lo necesita, añade mysql_native_password=ON en my.ini.
Comprueba después el servicio y conéctate como root.
Get-Service MySQL84
cd "C:\Program Files\MySQL\MySQL Server 8.4\bin"
.\mysql.exe -u root -p
En el prompt mysql>, este comando muestra la versión instalada.
SELECT VERSION();
Instalar MySQL desde la línea de comandos
Para automatizar la instalación, encadena el MSI en modo silencioso y MySQL Configurator en modo consola. Sustituye 8.4.x por el último parche de la página de descargas, y la contraseña de root por la tuya.
# Versión exacta que copiar de dev.mysql.com/downloads/mysql/
$version = "8.4.x"
$msi = "C:\Temp\mysql-$version-winx64.msi"
New-Item -ItemType Directory -Force -Path "C:\Temp" | Out-Null
Invoke-WebRequest -Uri "https://dev.mysql.com/get/Downloads/MySQL-8.4/mysql-$version-winx64.msi" -OutFile $msi -UseBasicParsing
# Instalación silenciosa del servidor y de MySQL Configurator
Start-Process msiexec.exe -ArgumentList "/i", $msi, "/qn", "/lv", "C:\Temp\mysql_install.log" -Wait
# Configuración: contraseña de root, puerto y servicio de Windows
$bin = "C:\Program Files\MySQL\MySQL Server 8.4\bin"
& "$bin\mysql_configurator.exe" --console --action=configure --password="Ch@ngeMe-Now!" --port=3306 --windows-service-name=MySQL84
# Comprobación
Get-Service MySQL84
& "$bin\mysql.exe" -u root -p -e "SELECT VERSION();"
MySQL Configurator está en la carpeta bin, junto a mysqld.exe. Si rechaza la opción --console, su versión es demasiado antigua: ábrelo sin opciones y sigue el asistente gráfico.
Abrir el acceso remoto
Para que otro servidor o una herramienta como MySQL Workbench se conecte, hacen falta un puerto abierto, un servidor que escuche en la red y una cuenta autorizada en remoto.
Abrir el puerto 3306
Si desmarcaste la opción del firewall en MySQL Configurator, crea la regla tú mismo. Resérvala, si puedes, a la dirección del cliente.
# Puerto 3306 abierto a todos
New-NetFirewallRule `
-DisplayName "MySQL 3306" `
-Direction Inbound `
-Protocol TCP `
-LocalPort 3306 `
-Action Allow `
-Profile Any
# Puerto 3306 reservado a una dirección (recomendado)
New-NetFirewallRule -DisplayName "MySQL 3306 - Allowed IP" -Direction Inbound -Protocol TCP -LocalPort 3306 -RemoteAddress "203.0.113.10" -Action Allow
# Comprobar la regla
Get-NetFirewallRule -DisplayName "MySQL 3306*"
La guía Cómo abrir un puerto en el firewall de un VPS Windows explica estas reglas. Entre dos de tus VPS, la red privada entre VPS evita pasar por Internet.
Crear una cuenta remota
No des nunca acceso remoto a root. Crea una cuenta propia, limitada a la dirección del cliente y a una base.
-- Cuenta limitada a una dirección
CREATE USER 'appuser'@'203.0.113.10' IDENTIFIED BY 'Ch@ngeMe-Now!';
-- Variante para todas las direcciones (menos segura)
CREATE USER 'appuser'@'%' IDENTIFIED BY 'Ch@ngeMe-Now!';
-- Permisos sobre una sola base
GRANT SELECT, INSERT, UPDATE, DELETE ON appdb.* TO 'appuser'@'203.0.113.10';
Comprueba también que MySQL escucha en la red. El comando SHOW VARIABLES LIKE 'bind_address'; debe devolver * o 0.0.0.0. Si no, añade esto en my.ini y reinicia el servicio.
[mysqld]
bind-address = 0.0.0.0
Cifrar las conexiones remotas
MySQL 8.4 crea sus certificados TLS en el primer arranque. Las variables ssl_ca, ssl_cert y ssl_key indican sus archivos. Exige después TLS para la cuenta remota y conecta el cliente con --ssl-mode=REQUIRED.
SHOW VARIABLES LIKE '%ssl%';
ALTER USER 'appuser'@'203.0.113.10' REQUIRE SSL;
mysql -u appuser -p -h 203.0.113.50 --ssl-mode=REQUIRED
Ajustar el rendimiento
La configuración está en C:\ProgramData\MySQL\MySQL Server 8.4\my.ini. Ajusta estos parámetros según la memoria del VPS.
[mysqld]
# Caché de InnoDB, el ajuste más importante
innodb_buffer_pool_size = 2G
# Conexiones simultáneas como máximo
max_connections = 150
# Capacidad del registro de rehacer de InnoDB
innodb_redo_log_capacity = 512M
# Hilos de E/S de InnoDB (número de núcleos)
innodb_read_io_threads = 4
innodb_write_io_threads = 4
| Memoria del VPS | innodb_buffer_pool_size | max_connections | innodb_redo_log_capacity |
|---|---|---|---|
| 2 GB | 1G | 75 | 256M |
| 4 GB | 2,5G | 150 | 512M |
| 8 GB | 5G | 300 | 1G |
| 16 GB | 11G | 500 | 2G |
Estos valores suponen un VPS dedicado sobre todo a MySQL. En un VPS que también ejecuta IIS o una aplicación, reduce la caché de InnoDB. Reinicia después el servicio.
Restart-Service MySQL84
No añadas
query_cache_sizeniquery_cache_type, que aún citan tutoriales antiguos. La caché de consultas desapareció en MySQL 8.0, y esas líneas impiden que el servidor arranque.
Proteger MySQL
Empieza por la herramienta de protección incluida. Propone la política de contraseñas, borra las cuentas anónimas, bloquea el acceso remoto de root y elimina la base test. Responde Y a cada pregunta.
cd "C:\Program Files\MySQL\MySQL Server 8.4\bin"
.\mysql_secure_installation.exe
Las mismas comprobaciones se hacen a mano. Borra con DROP USER cada cuenta anónima o root remota que muestre la primera consulta.
-- Cuentas anónimas y root con acceso remoto
SELECT User, Host FROM mysql.user WHERE User = '' OR (User = 'root' AND Host NOT IN ('localhost', '127.0.0.1', '::1'));
-- Ejemplos de borrado
DROP USER IF EXISTS ''@'localhost';
DROP USER IF EXISTS 'root'@'%';
-- Base de pruebas
DROP DATABASE IF EXISTS test;
Activa la política de contraseñas, un componente en MySQL 8.4.
INSTALL COMPONENT 'file://component_validate_password';
SET GLOBAL validate_password.policy = STRONG;
SET GLOBAL validate_password.length = 12;
Da a cada aplicación solo los permisos que necesita sobre su base, nunca ALL PRIVILEGES ON *.*.
-- Buen ejemplo
GRANT SELECT, INSERT, UPDATE ON appdb.* TO 'appuser'@'localhost';
-- A evitar
-- GRANT ALL PRIVILEGES ON *.* TO 'appuser'@'%';
Para guardar un rastro, añade los registros en my.ini. El registro general guarda todas las consultas y crece rápido: actívalo solo durante un diagnóstico.
[mysqld]
general_log = 1
general_log_file = "C:/ProgramData/MySQL/MySQL Server 8.4/Data/mysql_general.log"
log_error = "C:/ProgramData/MySQL/MySQL Server 8.4/Data/mysql_error.log"
Exige TLS en todas las cuentas remotas, como se vio antes. Por último, instala los parches de la rama en cuanto salgan y sigue los avisos de seguridad de MySQL.
Hacer copias de las bases
Para no escribir la contraseña en el script, guárdala en un archivo de opciones que solo puedan leer los administradores. Crea C:\Scripts\mysql-backup.cnf con este contenido.
[client]
user=root
password=Ch@ngeMe-Now!
icacls "C:\Scripts\mysql-backup.cnf" /inheritance:r /grant:r "Administrators:F" "SYSTEM:F"
Guarda después este script como C:\Scripts\mysql_backup.ps1. Copia cada base en un archivo con fecha y borra los archivos de más de 7 días.
# Copia de MySQL con rotación, para programar
$mysqlBin = "C:\Program Files\MySQL\MySQL Server 8.4\bin"
$cnf = "C:\Scripts\mysql-backup.cnf"
$backupDir = "C:\Backups\MySQL"
$retention = 7
New-Item -ItemType Directory -Force -Path $backupDir | Out-Null
$timestamp = Get-Date -Format "yyyy-MM-dd_HH-mm"
# Todas las bases salvo las del sistema
$databases = & "$mysqlBin\mysql.exe" --defaults-extra-file="$cnf" -e "SHOW DATABASES;" --batch --skip-column-names |
Where-Object { $_ -notin @('information_schema','performance_schema','sys','mysql') }
foreach ($db in $databases) {
$dbFile = "$backupDir\${db}_$timestamp.sql"
& "$mysqlBin\mysqldump.exe" --defaults-extra-file="$cnf" `
--single-transaction `
--routines `
--triggers `
--databases $db `
--result-file=$dbFile
if ($LASTEXITCODE -eq 0) { Write-Host "Backup OK: $db" } else { Write-Host "Backup ERROR: $db" }
}
# Rotación
Get-ChildItem -Path $backupDir -Filter "*.sql" |
Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-$retention) } |
Remove-Item -Force
Prográmalo cada noche a las 2:00, con la cuenta SYSTEM, para que funcione sin sesión abierta.
$action = New-ScheduledTaskAction `
-Execute "PowerShell.exe" `
-Argument "-NonInteractive -ExecutionPolicy Bypass -File C:\Scripts\mysql_backup.ps1"
$trigger = New-ScheduledTaskTrigger -Daily -At "02:00"
$settings = New-ScheduledTaskSettingsSet `
-ExecutionTimeLimit (New-TimeSpan -Hours 1) `
-RestartCount 3 `
-RestartInterval (New-TimeSpan -Minutes 5)
Register-ScheduledTask `
-TaskName "MySQL Backup Daily" `
-Action $action `
-Trigger $trigger `
-Settings $settings `
-User "SYSTEM" `
-RunLevel Highest `
-Force
Estos archivos se quedan en el VPS. Para guardar una copia en otro sitio, sigue la guía Copia de seguridad de un VPS Windows. Para un sitio PHP bajo IIS, el artículo Alojar sitios PHP/MySQL en un VPS Windows une las dos cosas.
Resolver los errores habituales
El servicio MySQL no arranca
Lee el final del registro de errores, en la carpeta de datos. Las causas frecuentes son un puerto 3306 ya ocupado, permisos que faltan en la carpeta Data y una línea no válida en my.ini, como query_cache_size.
Get-ChildItem "C:\ProgramData\MySQL\MySQL Server 8.4\Data\*.err" | Get-Content -Tail 50
Access denied for user 'root', o contraseña olvidada
Arranca MySQL sin control de permisos, el tiempo justo de cambiar la contraseña. --skip-networking bloquea toda conexión de red mientras tanto.
# Detener el servicio
Stop-Service MySQL84
# Arrancar MySQL sin control de permisos, con su archivo de configuración
& "C:\Program Files\MySQL\MySQL Server 8.4\bin\mysqld.exe" --defaults-file="C:\ProgramData\MySQL\MySQL Server 8.4\my.ini" --skip-grant-tables --skip-networking
# En otra ventana de PowerShell, conectarse sin contraseña
& "C:\Program Files\MySQL\MySQL Server 8.4\bin\mysql.exe" -u root
FLUSH PRIVILEGES;
ALTER USER 'root'@'localhost' IDENTIFIED BY 'Ch@ngeMe-Now!';
EXIT;
# Detener este mysqld y arrancar el servicio con normalidad
Stop-Process -Name mysqld -Force
Start-Service MySQL84
El puerto 3306 ya está en uso
# Proceso que ocupa el puerto 3306
netstat -ano | findstr :3306
# Nombre del proceso a partir de su PID
Get-Process -Id 1234
Sustituye 1234 por el PID encontrado. Detén ese programa, o cambia el puerto de MySQL en my.ini (port=3307) y en la regla del firewall.
No hay conexión remota
La regla del firewall existe:
Get-NetFirewallRule -DisplayName "MySQL 3306*".MySQL escucha en la red:
SHOW VARIABLES LIKE 'bind_address';devuelve*o0.0.0.0.La cuenta está autorizada desde la dirección del cliente:
SELECT User, Host FROM mysql.user;.La red del cliente deja salir el puerto 3306.
Error «The table is full»
Casi siempre el disco está lleno o una tabla temporal ha llegado a su límite. Comprueba el espacio libre en C: y el tamaño de cada base.
-- Tamaño de cada base
SELECT table_schema, ROUND(SUM(data_length+index_length)/1024/1024,1) AS "Size (MB)"
FROM information_schema.tables
GROUP BY table_schema;
-- Archivo de datos de InnoDB y su posible límite
SHOW VARIABLES LIKE 'innodb_data_file_path';
¿Necesitas ayuda?
Abre un ticket desde Tickets › Abrir un ticket, o desde el recuadro Contactar con el soporte al pie de la ficha del VPS. En el campo Servicio afectado, elige el VPS para que el equipo gane tiempo. También puedes preguntar en el Discord de OuiHeberg.
Windows Server 2025 con licencia incluida, Escritorio remoto y gestión desde el área de cliente.
Ver ofertas →