Ubuntu’s default repositories include MySQL, but the version varies by release. Ubuntu 22.04 LTS ships MySQL 8.0. Ubuntu 24.04 LTS ships MySQL 8.0 as well, though the minor version is newer. If you need a specific version or want to use MySQL’s official packages with the latest patches, you can add MySQL’s APT repository.
This guide covers installing MySQL on Ubuntu from the default repositories and from MySQL’s official repository, securing the installation, verifying it works, and configuring it for WordPress and other applications.
Installing MySQL from the default repositories#
The simplest approach uses Ubuntu’s built-in packages:
sudo apt update
sudo apt install mysql-server
This installs the MySQL server, the MySQL client, and the necessary dependencies. The service starts automatically after installation.
Verify it is running:
sudo systemctl status mysql
You should see
active (running)
. If the service did not start, check the logs:
sudo journalctl -u mysql --no-pager -n 50
What gets installed
The
mysql-server
package installs:
- mysqld – the MySQL server daemon that runs in the background and handles all database operations
- mysql – the command-line client for connecting to the server and running SQL queries
- mysql_secure_installation – a script that hardens the installation by setting a root password, removing test databases, and disabling anonymous access
- Configuration files at
/etc/mysql/includingmy.cnfand files inmysql.conf.d/ - Data directory at
/var/lib/mysql/where all databases are stored on disk
MySQL client only
If you do not need the server on this machine – you just need to connect to a MySQL server running elsewhere – install only the client:
sudo apt install mysql-client
This gives you the
mysql
command-line tool without starting a server process. See how to allow remote MySQL connections for the full setup on the server side.
Installing from MySQL's official APT repository#
Ubuntu’s packages are maintained by the Ubuntu team and may lag behind MySQL’s own releases. If you need the latest MySQL version or want patches directly from Oracle, use MySQL’s official APT repository.
Download the repository package
wget https://dev.mysql.com/get/mysql-apt-config_0.8.33-1_all.deb
Check the MySQL APT repository page for the latest version of this package – the version number in the filename changes over time.
Install the repository configuration
sudo dpkg -i mysql-apt-config_0.8.33-1_all.deb
A configuration dialog appears. Select the MySQL version you want (8.0, 8.4, or Innovation releases) and confirm. This adds MySQL’s APT repository to your system’s sources list.
Install MySQL
sudo apt update
sudo apt install mysql-server
The
apt update
is required after adding the new repository so apt knows about the new packages. If Ubuntu’s default MySQL was already installed, this will upgrade it to the version from MySQL’s repository.
During installation from the official repository, you may be prompted to set a root password and choose an authentication plugin. Select
caching_sha2_password
for MySQL 8.0+ unless you have a specific reason to use the older
mysql_native_password
.
Securing the installation#
A fresh MySQL installation has permissive defaults that are suitable for development but not for any server accessible from the network. The
mysql_secure_installation
script fixes the most common issues:
sudo mysql_secure_installation
The script walks through several prompts:
VALIDATE PASSWORD component. Optionally installs a plugin that enforces password strength requirements. On a development machine this is unnecessary. On a server that will host production data, enable it.
Root password. If you installed from Ubuntu’s default repositories, root authentication uses the
auth_socket
plugin by default – root can only connect from the local system user
root
without a password. The script offers to set a password-based authentication method instead. On a single-user development machine,
auth_socket
is fine. On a shared server, set a password.
Remove anonymous users. Yes. Anonymous users can connect to MySQL without a username, which is a security risk on any machine that is not purely local development.
Disallow root login remotely. Yes. Root should only connect from localhost. Create separate, limited users for application access. See how to show and manage MySQL users for the full guide on creating users with appropriate privileges.
Remove test database. Yes. The test database is accessible to anonymous users and serves no purpose on a production system.
Reload privilege tables. Yes. This applies the changes immediately.
Connecting to MySQL#
auth_socket (Ubuntu default)
On Ubuntu’s default MySQL installation, root uses the
auth_socket
plugin. This means you connect as root by running the MySQL client as the system’s root user:
sudo mysql
No password is needed. The
auth_socket
plugin verifies that the system user running the MySQL client matches the MySQL username. This is more secure than password authentication for local root access because there is no password to steal or brute force.
Password authentication
If you set a root password during
mysql_secure_installation
or installed from MySQL’s official repository:
mysql -u root -p
Enter the password when prompted. You see the MySQL prompt:
mysql>
Verify the version
From inside the MySQL shell:
SELECT VERSION();
Or from the command line without entering the shell:
mysql --version
Post-installation configuration#
Configuration file locations
MySQL on Ubuntu reads configuration from multiple files in a specific order:
| File | Purpose |
|---|---|
/etc/mysql/my.cnf
| Main configuration file (usually just includes other files) |
/etc/mysql/mysql.conf.d/mysqld.cnf
| Server configuration (bind-address, port, data directory) |
/etc/mysql/conf.d/
| Additional configuration files |
~/.my.cnf
| Per-user client configuration |
The main file to edit for server settings is
/etc/mysql/mysql.conf.d/mysqld.cnf
. After making changes, restart MySQL:
sudo systemctl restart mysql
Bind address
By default, MySQL listens only on
127.0.0.1
(localhost). This means only applications running on the same machine can connect. For most WordPress installations where the web server and database run on the same machine, this is correct and should not be changed.
If you need to accept connections from other machines, change the
bind-address
in the configuration file. See how to allow remote MySQL connections for the full process including user grants and firewall rules – changing the bind address alone is not sufficient and leaves the database exposed without the other steps.
Character set
MySQL 8.0 defaults to
utf8mb4
with the
utf8mb4_0900_ai_ci
collation. This is the correct default for WordPress and most web applications. It supports the full Unicode character set including emojis, CJK characters, and special symbols.
If you are running an older MySQL version or your configuration has a different default, set it explicitly:
[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_0900_ai_ci
Using
utf8
instead of
utf8mb4
limits you to 3-byte UTF-8, which cannot store characters outside the Basic Multilingual Plane. WordPress specifically requires
utf8mb4
for full compatibility.
InnoDB buffer pool
The InnoDB buffer pool is the most impactful MySQL performance setting. It caches table data and indexes in memory, reducing disk reads. The default is 128 MB, which is conservative.
For a dedicated database server, set it to 50-70% of available RAM. For a server that also runs the web server and PHP, 25-40% is more appropriate:
[mysqld]
innodb_buffer_pool_size = 512M
On a VPS with 2 GB of RAM running WordPress, Nginx, and PHP-FPM, 256-512 MB is a reasonable starting point. Monitor memory usage after the change to ensure you are not starving other services.
Max connections
The default
max_connections
is 151. Each connection consumes memory (roughly 10-20 MB depending on configuration and queries). For a WordPress site, the number of simultaneous MySQL connections roughly tracks the number of concurrent PHP-FPM workers, since each PHP worker holds one database connection during request processing.
If you see “Too many connections” errors, either increase the limit or investigate why connections are not being released. Connection pooling issues and slow queries that hold connections open are common causes.
[mysqld]
max_connections = 200
Setting up MySQL for WordPress#
WordPress needs a database, a user with privileges on that database, and the connection details stored in
wp-config.php
. Here is the complete setup.
Create the database and user
sudo mysql
CREATE DATABASE wordpress CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
CREATE USER 'wp_user'@'localhost' IDENTIFIED BY 'strong_password_here';
GRANT ALL PRIVILEGES ON wordpress.* TO 'wp_user'@'localhost';
FLUSH PRIVILEGES;
EXIT;
Replace
wordpress
with your preferred database name,
wp_user
with your preferred username, and use a strong, unique password. For a detailed walkthrough of database creation including character set choices and verification steps, see how to create a database in MySQL.
The
GRANT ALL PRIVILEGES ON wordpress.*
gives the user full control over the
wordpress
database but no access to any other database on the server. This follows the principle of least privilege – the WordPress user should never have access to system databases or other application databases. For more on MySQL privilege management, see how to show and manage MySQL users.
Configure wp-config.php
In your WordPress installation directory, edit
wp-config.php
and set the database credentials:
define('DB_NAME', 'wordpress');
define('DB_USER', 'wp_user');
define('DB_PASSWORD', 'strong_password_here');
define('DB_HOST', 'localhost');
define('DB_CHARSET', 'utf8mb4');
define('DB_COLLATE', '');
DB_HOST
is
localhost
when MySQL runs on the same machine as the web server, which is the typical setup. If your database is on a separate server, use that server’s hostname or IP address.
Test the connection
Verify WordPress can connect to the database:
wp db check
If this returns the status of each table, the connection is working. If it fails with “Error establishing a database connection,” one of the credentials in
wp-config.php
does not match what was configured in MySQL. See error establishing a database connection in WordPress: how to fix it for the full diagnostic process.
MySQL vs MariaDB on Ubuntu#
Ubuntu’s repositories offer both MySQL and MariaDB. They are not the same software. MariaDB was forked from MySQL in 2009 and has diverged significantly since then.
Key differences that affect installation and operation:
- Authentication. MySQL 8.0 defaults to
caching_sha2_password. MariaDB usesmysql_native_password. Applications and client libraries that work with one may fail to authenticate with the other. - JSON handling. MySQL has a native JSON data type with dedicated functions. MariaDB stores JSON as a LONGTEXT alias.
- System tables. The
mysql.usertable structure differs between them. Scripts and tools that query system tables directly may need adjustments. - Package conflicts. You cannot install both on the same system. Installing one removes the other.
For WordPress, both work equally well. The choice matters more for applications that use MySQL-specific features like the JSON column type or window function syntax that differs between the two. For a deeper comparison, see MySQL vs MariaDB: which should you use.
If you are setting up a fresh server and have no existing preference, MySQL is the standard choice for WordPress. MariaDB is the default on some hosting platforms and Linux distributions (RHEL/Rocky Linux ship MariaDB by default), so check what your target environment uses.
Enabling MySQL to start on boot#
On Ubuntu with systemd, MySQL is enabled by default after installation. Verify:
sudo systemctl is-enabled mysql
If it returns
enabled
, MySQL starts automatically on boot. If not:
sudo systemctl enable mysql
This is important for servers that may be rebooted during maintenance. Without the
enable
flag, MySQL stays stopped after a reboot and every application depending on it fails until someone manually starts it.
Checking MySQL logs#
MySQL logs to the systemd journal by default on Ubuntu. View recent log entries:
sudo journalctl -u mysql --no-pager -n 100
The error log is also written to a file. The default location on Ubuntu:
sudo tail -100 /var/log/mysql/error.log
Common log entries to watch for:
- “Access denied for user” – wrong username, password, or the user does not exist for the connecting host. Check credentials and verify the user exists with the correct host component.
- “Too many connections” – the
max_connectionslimit has been reached. Either increase it or investigate connection leaks. - “InnoDB: Unable to lock ./ibdata1” – another MySQL process is already running, or a previous shutdown left a lock file behind.
- “Server has gone away” – the connection between the client and server was dropped, typically due to a timeout or a packet that exceeded
max_allowed_packet. See MySQL server has gone away: what it means and how to fix it for the full walkthrough.
Uninstalling MySQL#
If you need to remove MySQL completely and start fresh:
sudo apt purge mysql-server mysql-client mysql-common
sudo apt autoremove
sudo rm -rf /etc/mysql /var/lib/mysql /var/log/mysql
The
purge
command removes the packages and their configuration files. The
rm -rf
commands remove the data directory and logs. This is destructive and irreversible – all databases and configuration are deleted. Back up anything you need before running these commands.
If you are removing MySQL to install MariaDB (or vice versa), the purge step is required. The packages conflict with each other and apt will not install one while the other’s files remain.
Troubleshooting#
MySQL will not start
Check the error log:
sudo journalctl -u mysql --no-pager -n 50
Common causes:
- Port 3306 already in use. Another MySQL or MariaDB instance is running. Check with
ss -tlnp | grep 3306. - Data directory permissions. The
/var/lib/mysqldirectory must be owned bymysql:mysql. Fix withsudo chown -R mysql:mysql /var/lib/mysql. - Configuration error. A typo in the configuration file prevents MySQL from starting. Check the error log for the specific directive that caused the failure.
- Insufficient disk space. MySQL needs space for temporary tables and the InnoDB redo log during startup. Check available disk with
df -h. - AppArmor blocking access. Ubuntu uses AppArmor to restrict which files MySQL can access. If you moved the data directory to a non-standard location, AppArmor may block it. Check
sudo aa-statusand the AppArmor logs.
Cannot connect as root
On Ubuntu’s default installation, root uses
auth_socket
authentication. Use
sudo mysql
instead of
mysql -u root -p
. If you need password authentication for root:
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_password';
FLUSH PRIVILEGES;
After this change,
mysql -u root -p
works but
sudo mysql
without a password no longer does.
Package conflicts with MariaDB
If apt complains about conflicts during installation, a previous MariaDB installation (or its configuration files) may still be present:
sudo apt purge mariadb-server mariadb-client mariadb-common
sudo apt autoremove
sudo apt install mysql-server
Authentication plugin errors
If an application cannot connect with the error “Authentication plugin ‘caching_sha2_password’ cannot be loaded,” the client library does not support MySQL 8.0’s default authentication. Options:
- Update the client library. This is the correct long-term fix.
- Create the user with the older plugin:
CREATE USER 'app_user'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';
- Change the server default (affects all new users):
[mysqld]
default-authentication-plugin = mysql_native_password
This is a compatibility workaround, not a recommendation.
caching_sha2_password
is more secure and should be used when the client supports it.
Summary#
Installing MySQL on Ubuntu is
sudo apt install mysql-server
followed by
sudo mysql_secure_installation
to harden the defaults. For the latest versions, add MySQL’s official APT repository before installing. After installation, create application-specific databases and users with limited privileges rather than using root for everything.
The key post-installation steps are: secure the installation with
mysql_secure_installation
, set the InnoDB buffer pool size based on available memory, and create properly scoped database users for each application. For WordPress specifically, create a dedicated database and user, configure the credentials in
wp-config.php
, and verify the connection with
wp db check
.
For related MySQL operations, see how to show databases in MySQL for navigating your databases, how to create a database in MySQL for detailed database setup, and WordPress database optimization for keeping your databases healthy over time.