How to Install MySQL on Windows Server 2025

MySQL Community Server remains one of the most widely deployed open-source relational databases in the world, and Windows Server 2025 is a fully supported host platform for it. While MySQL is more commonly associated with Linux environments, the Windows version is mature, production-ready, and deeply integrated with the Windows Service Control Manager, Windows authentication, and the Windows Event Log. Installing MySQL on Windows Server 2025 requires understanding the MySQL Installer for Windows — a graphical bundle that handles component selection, initial configuration, service registration, and root account setup in a single workflow. This guide covers the complete installation process: downloading MySQL Community Server, running the MySQL Installer, selecting and configuring components (MySQL Server, MySQL Workbench, Connector/NET), configuring the Windows service, securing the root account, opening the firewall on port 3306, testing the connection, and tuning the essential my.ini configuration parameters for production workloads.

Prerequisites

  • Windows Server 2025 Standard or Datacenter, fully patched.
  • Microsoft Visual C++ 2019 Redistributable (x64) — MySQL 8.0+ requires it. Download from aka.ms/vs/17/release/vc_redist.x64.exe.
  • A local administrator account.
  • At least 1 GB free on the system drive for MySQL binaries (data directory should be on a separate volume).
  • MySQL Community installer downloaded from dev.mysql.com/downloads/installer.
# Verify Visual C++ Redistributable is installed
Get-WmiObject -Class Win32_Product |
    Where-Object { $_.Name -like "*Visual C++*2019*" -or $_.Name -like "*Visual C++*2022*" } |
    Select-Object Name, Version

# If missing, download and install silently
$vcRedistUrl = "https://aka.ms/vs/17/release/vc_redist.x64.exe"
$vcRedistPath = "C:Installersvc_redist.x64.exe"
Invoke-WebRequest -Uri $vcRedistUrl -OutFile $vcRedistPath
Start-Process -FilePath $vcRedistPath -ArgumentList "/install /quiet /norestart" -Wait
Write-Host "Visual C++ Redistributable installed"

Step 1 — Download MySQL Installer for Windows

MySQL provides two installer packages:

  • mysql-installer-web-community-8.x.x.msi (~2 MB) — downloads selected components at install time. Requires internet access.
  • mysql-installer-community-8.x.x.msi (~300 MB) — all components bundled offline. Best for servers without direct internet access.
# Download the full offline installer (adjust version as needed)
$mysqlUrl = "https://dev.mysql.com/get/Downloads/MySQLInstaller/mysql-installer-community-8.0.41.0.msi"
$mysqlInstaller = "C:Installersmysql-installer-community-8.0.41.0.msi"

Invoke-WebRequest -Uri $mysqlUrl -OutFile $mysqlInstaller -UseBasicParsing
Write-Host "MySQL Installer downloaded: $(Get-Item $mysqlInstaller | Select-Object -Expand Length) bytes"

# Verify the download (compare SHA256 with the hash shown on dev.mysql.com)
Get-FileHash -Path $mysqlInstaller -Algorithm SHA256

Step 2 — Run the MySQL Installer — Setup Type

Launch the installer as Administrator and choose the Custom setup type for precise control over which components are installed:

# Launch the installer (GUI)
Start-Process -FilePath "msiexec.exe" -ArgumentList "/i C:Installersmysql-installer-community-8.0.41.0.msi" -Wait

On the Choosing a Setup Type screen select Custom. From the Select Products tree, add:

  • MySQL Servers → MySQL Server 8.0.x → MySQL Server 8.0.x — X64
  • Applications → MySQL Workbench 8.0.x (GUI query and administration tool)
  • Connectors → Connector/NET 8.0.x (for .NET application connectivity)
  • Optionally: MySQL Shell 8.0.x for the modern command-line client with JavaScript and Python support.

Step 3 — Configure MySQL Server

After products are installed, the installer launches the configuration wizard for MySQL Server.

Group Replication Config

Select Standalone MySQL Server / Classic MySQL Replication unless you are setting up InnoDB Cluster.

Type and Networking

  • Config Type: Select Server Computer for a dedicated MySQL host, or Dedicated Computer for maximum performance on a single-purpose server.
  • Port: Leave as 3306 (the MySQL default). If another service uses 3306, change it here — this becomes the port value in my.ini.
  • X Protocol Port: 33060 — used by MySQL Shell and Document Store features. Enable if using mysqlx.
  • Enable Open Windows Firewall port for network access in the installer (or add it manually — see Step 7).

Authentication Method

Select Use Strong Password Encryption for Authentication (RECOMMENDED) — this uses the caching_sha2_password auth plugin. Only choose the legacy method (mysql_native_password) if connecting from very old clients that cannot be updated.

Accounts and Roles

Set a strong root password. The MySQL root account has full privileges over all databases — treat it like a sysadmin account:

  • Minimum 16 characters, mixed case, numbers, symbols.
  • Consider adding a named DBA user here instead of using root for day-to-day administration.
# After installation, connect as root and create a named DBA account
# (run this in MySQL Shell or mysql.exe)
# mysql -u root -p
-- Create a named admin user instead of using root
CREATE USER 'dbadmin'@'%' IDENTIFIED BY 'Dbadm!n2025Secure#88';
GRANT ALL PRIVILEGES ON *.* TO 'dbadmin'@'%' WITH GRANT OPTION;
FLUSH PRIVILEGES;

-- Restrict root to localhost only (security hardening)
UPDATE mysql.user SET Host = 'localhost' WHERE User = 'root';
FLUSH PRIVILEGES;

Step 4 — Windows Service Configuration

The installer registers MySQL as a Windows service named MySQL80 (the number matches the major version):

  • Service Name: MySQL80
  • Start the MySQL Server at System Startup: Enabled (recommended for production).
  • Run Windows Service as: Choose Standard System Account (Network Service) for most deployments.
# Verify the service is running after installation
Get-Service -Name MySQL80

# Start, stop, or restart MySQL using PowerShell
Start-Service   -Name MySQL80
Stop-Service    -Name MySQL80
Restart-Service -Name MySQL80

# Check service startup type (should be Automatic)
Get-Service -Name MySQL80 | Select-Object Name, Status, StartType

# Set startup type to Automatic Delayed Start (recommended for servers with many services)
Set-Service -Name MySQL80 -StartupType AutomaticDelayedStart

You can also use the classic net commands:

net start MySQL80
net stop MySQL80

Step 5 — Test the Connection

# Test using the mysql command-line client
# The mysql.exe client is in C:Program FilesMySQLMySQL Server 8.0bin
$env:PATH += ";C:Program FilesMySQLMySQL Server 8.0bin"

# Connect as root (will prompt for password)
mysql -u root -p

# Non-interactive test (returns server version)
mysql -u root -p"YourRootPass" -e "SELECT VERSION(), NOW(), USER();"

# Connect to a specific database
mysql -u root -p --database=information_schema -e "SHOW TABLES;"
-- Inside the MySQL shell: verify key server variables
SHOW VARIABLES LIKE 'version%';
SHOW VARIABLES LIKE 'port';
SHOW VARIABLES LIKE 'datadir';
SHOW VARIABLES LIKE 'socket';

-- Show all databases
SHOW DATABASES;

-- Show process list (active connections)
SHOW PROCESSLIST;

Step 6 — Create a Database and Application User

-- Create an application database
CREATE DATABASE appdb
    CHARACTER SET utf8mb4
    COLLATE utf8mb4_unicode_ci;

-- Create an application user restricted to a specific IP subnet
CREATE USER 'appuser'@'192.168.10.%' IDENTIFIED BY 'App$vc2025!MySQL#31';

-- Grant only necessary privileges (principle of least privilege)
GRANT SELECT, INSERT, UPDATE, DELETE, EXECUTE ON appdb.* TO 'appuser'@'192.168.10.%';
FLUSH PRIVILEGES;

-- Verify grants
SHOW GRANTS FOR 'appuser'@'192.168.10.%';

Step 7 — Configure Windows Firewall for Port 3306

# Create an inbound rule allowing MySQL traffic on port 3306
New-NetFirewallRule `
    -DisplayName "MySQL Server 8.0 - Port 3306" `
    -Direction Inbound `
    -Protocol TCP `
    -LocalPort 3306 `
    -Action Allow `
    -Profile Domain, Private `
    -Description "Allow MySQL client connections on the standard port"

# If using MySQL X Protocol (MySQL Shell / Document Store)
New-NetFirewallRule `
    -DisplayName "MySQL X Protocol - Port 33060" `
    -Direction Inbound `
    -Protocol TCP `
    -LocalPort 33060 `
    -Action Allow `
    -Profile Domain, Private

# Verify the rules are active
Get-NetFirewallRule -DisplayName "MySQL*" | Select-Object DisplayName, Enabled, Direction, Action

Step 8 — Tune my.ini for Production

The MySQL configuration file on Windows is C:ProgramDataMySQLMySQL Server 8.0my.ini. Key parameters to adjust for a production server:

[mysqld]
# ------- Paths -------
datadir     = D:/MySQLData/            # Move data off the system drive
tmpdir      = F:/MySQLTmp/             # Temp tables on fast storage

# ------- Networking -------
port        = 3306
bind-address = 0.0.0.0                # Listen on all interfaces; restrict via firewall
max_connections = 500                  # Default 151; increase for busy servers

# ------- InnoDB / Memory -------
# innodb_buffer_pool_size: 60-80% of total RAM for a dedicated MySQL server
# Example for a 32 GB server: 20 GB
innodb_buffer_pool_size = 20G
innodb_buffer_pool_instances = 8      # 1 per GB of buffer pool (max 64)

# Redo log size — larger = fewer checkpoints, better write throughput
innodb_redo_log_capacity = 4G         # MySQL 8.0.30+ replaces innodb_log_file_size

# Write performance — O_DIRECT bypasses OS cache (beneficial when buffer pool is large)
innodb_flush_method = O_DIRECT

# Flush behaviour — 1 = fully ACID (default); 2 = may lose 1 second of data on crash
innodb_flush_log_at_trx_commit = 1

# ------- Query Cache (disabled in MySQL 8.0) -------
# query_cache_type = 0                 # Removed in 8.0; leave commented out

# ------- Logging -------
general_log          = 0              # Disable in production (performance impact)
general_log_file     = C:/ProgramData/MySQL/MySQL Server 8.0/Logs/general.log
slow_query_log       = 1              # Enable slow query log
slow_query_log_file  = C:/ProgramData/MySQL/MySQL Server 8.0/Logs/slow_queries.log
long_query_time      = 2              # Log queries taking more than 2 seconds
log_queries_not_using_indexes = 1     # Also log queries missing indexes

# ------- Binary Logging (required for replication and point-in-time recovery) -------
log_bin              = mysql-bin
binlog_format        = ROW            # Row-based replication (safest)
expire_logs_days     = 7              # Auto-purge binary logs older than 7 days
sync_binlog          = 1              # Synchronize binary log on each commit (ACID)

# ------- Character Set -------
character-set-server = utf8mb4
collation-server     = utf8mb4_unicode_ci

[client]
default-character-set = utf8mb4

After editing my.ini, restart the MySQL service for changes to take effect:

Restart-Service -Name MySQL80 -Force

# Verify new values are loaded
mysql -u root -p -e "SHOW VARIABLES LIKE 'innodb_buffer_pool_size';"
mysql -u root -p -e "SHOW VARIABLES LIKE 'max_connections';"

Step 9 — Monitor MySQL Status

-- Show server status counters
SHOW GLOBAL STATUS LIKE 'Connections';
SHOW GLOBAL STATUS LIKE 'Threads_connected';
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_read_requests';
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_reads';   -- Cache misses

-- Calculate InnoDB buffer pool hit rate (should be > 99%)
SELECT
    (1 - (
        (SELECT VARIABLE_VALUE FROM performance_schema.global_status WHERE VARIABLE_NAME = 'Innodb_buffer_pool_reads') /
        (SELECT VARIABLE_VALUE FROM performance_schema.global_status WHERE VARIABLE_NAME = 'Innodb_buffer_pool_read_requests')
    )) * 100 AS buffer_pool_hit_rate_pct;

-- View current slow queries
SELECT * FROM performance_schema.events_statements_summary_by_digest
ORDER BY SUM_TIMER_WAIT DESC
LIMIT 10;

Conclusion

MySQL 8.0 on Windows Server 2025 is a capable and well-supported database platform suitable for web applications, internal tools, and workloads that require the MySQL ecosystem — including frameworks like Laravel, Django, and Ruby on Rails. The MySQL Installer for Windows simplifies the initial setup considerably, bundling server, workbench, and connectors into a single guided workflow. After installation, the highest-impact configuration changes are setting innodb_buffer_pool_size to 60–80% of available RAM, enabling the slow query log to identify performance bottlenecks, enabling binary logging for point-in-time recovery, and restricting user privileges to specific IP ranges through MySQL’s user@host account model. Pair these settings with Windows Firewall rules that limit port 3306 access to known application server IP addresses, and your MySQL installation is ready for production use.