How to Install MySQL on Linux
Install MySQL on Debian, Ubuntu, Red Hat, Fedora, Rocky, AlmaLinux, and SUSE. Start, secure, verify, configure, and troubleshoot MySQL Server.
MySQL Server is a database service that stores structured data and processes SQL requests. This guide covers installation, service management, initial security, local and remote connections, application users, maintenance, troubleshooting, and cautious removal.
You will use a Linux terminal and administrative privileges, normally through sudo. The standard installation path also requires an internet-connected package manager. For background, review what MySQL is, what Linux is, and how to identify the operating system.
MySQL Server, the mysql Client, and Graphical Tools
MySQL Server is the background database service. Its daemon process is commonly called mysqld. It listens for local or network connections, authenticates accounts, executes SQL, and reads and writes database files.
The mysql client is a command-line program. It connects to a server and lets you run SQL and administrative commands; installing the server does not always install every client utility. Graphical database tools are separate applications that connect to MySQL and provide an interface for browsing schemas, writing queries, or managing users.
Choose an Installation Approach
- Distribution repository: Install the package maintained for Debian, Ubuntu, Fedora, Red Hat-family, or SUSE systems. This is usually the simplest option and integrates well with system updates.
- Official MySQL repository: Configure Oracle's MySQL repository when you need a particular Oracle MySQL release that the distribution does not provide.
- Package files: Install downloaded package files such as RPM or DEB packages. This requires careful dependency management and version planning, so it is less convenient than a repository.
Linux distributions may provide MariaDB, a MySQL-compatible database server, under a familiar package name. MariaDB is not Oracle MySQL; behavior, package names, service units, authentication, and supported features can differ.
Pre-installation Decisions and Checks
- Identify the distribution and release, for example Debian, Ubuntu, Fedora, Rocky Linux, AlmaLinux, RHEL, or openSUSE.
- Decide whether the distribution-provided compatible server is sufficient or whether the application requires Oracle MySQL.
- Choose a MySQL version supported by the application, operating system, and course or deployment requirements. Do not install an arbitrary older version merely because its command examples are familiar.
- Check for an existing MySQL or MariaDB service. A second server can conflict over the data directory, socket, or TCP port.
- Check available disk space, memory, package-manager access, and network connectivity. Leave room for database growth, binary logs, temporary files, and upgrades.
- Confirm that the expected local socket and TCP port are available. MySQL normally uses TCP port
3306, but it can be changed.
cat /etc/os-release
sudo ss -ltnp | grep 3306
sudo df -h
The Linux root user and the MySQL root account are different identities. Linux administrative access lets you install and manage the service; the MySQL root account has high privileges inside the database server.
Installation Commands by Linux Family
| Linux family | Package manager | Typical server package | Typical service name | Notes |
|---|---|---|---|---|
| Debian or Ubuntu | APT | mysql-server | mysql | The distribution package may have release-specific dependencies and defaults. |
| Fedora, RHEL, Rocky, AlmaLinux | DNF or YUM | mysql-server | mysqld | The default repository may provide MariaDB instead of Oracle MySQL. |
| SUSE family | Zypper | mysql-server | Release-dependent | Confirm the available package and unit name for the selected SUSE release. |
Install MySQL on Debian and Ubuntu
APT is the package-management tooling used by Debian and Ubuntu systems. Refresh package metadata before installing so the package manager knows the current repository contents.
sudo apt update
sudo apt install mysql-server
APT may install dependencies such as libraries, initialization tools, service files, and supporting utilities. If you need command-line connection tools separately, search for the distribution's MySQL client package and install it as well.
apt search mysql-client
mysql --version
A successful installation normally ends without an error and creates an installed package and service unit. Confirm the package and service:
dpkg -l | grep -i mysql
systemctl list-unit-files | grep -E 'mysql|mysqld'
If mysql-server cannot be found, refresh metadata, search available packages, confirm the release, and determine whether the distribution supplies MariaDB or requires another repository.
Install MySQL on Red Hat-Family Systems
Fedora, RHEL, Rocky Linux, and AlmaLinux commonly use DNF. Older systems may use YUM, which is also available as a compatibility command.
sudo dnf makecache
sudo dnf install mysql-server
# On systems using YUM:
sudo yum install mysql-server
Some Red Hat-family releases use their standard repositories or module streams to provide MariaDB by default. If you specifically require Oracle MySQL, use the official MySQL repository appropriate for the operating system and release, then select the intended enabled stream or package version. Do not enable repositories designed for a different release.
sudo dnf module list mysql
sudo dnf repolist
rpm -qa | grep -Ei 'mysql|mariadb'
mysql --version
When package availability is unclear, list enabled repositories, inspect module streams, and search the package index:
dnf search mysql-server
dnf info mysql-server
Installing a package named mysql-server does not by itself prove that the server is Oracle MySQL. Check the package vendor, installed packages, server version, and service name.
Install MySQL on SUSE-Family Systems
SUSE systems use Zypper. Refresh repository metadata, search for the package, and install the server and client packages when they are available separately.
sudo zypper refresh
zypper search mysql
sudo zypper install mysql-server mysql-client
rpm -qa | grep -i mysql
mysql --version
Package naming varies by SUSE release. If a package is unavailable, search the enabled repositories and verify the appropriate vendor repository before changing repository configuration. Find the service unit rather than assuming it is called mysql or mysqld.
systemctl list-unit-files | grep -E 'mysql|mysqld|mariadb'
Start and Enable the Database Service
systemd is the service manager commonly used on modern Linux systems. systemctl start starts a service now; systemctl enable configures it to start during boot.
# Use the unit name found on this host.
sudo systemctl start mysql
sudo systemctl enable mysql
sudo systemctl status mysql
# Common Red Hat-family alternative:
sudo systemctl start mysqld
sudo systemctl enable mysqld
sudo systemctl status mysqld
The unit may be named mysql, mysqld, or a distribution-specific equivalent. An active status containing active (running) indicates that systemd considers the service running.
Initial Security Configuration
Run the security utility when the package supplies it:
sudo mysql_secure_installation
Prompts differ by version and package. Review each choice rather than accepting blindly. Typical hardening actions include:
- Set or validate the administrative account password.
- Remove anonymous accounts unless there is a documented reason to keep them.
- Remove the test database and related unrestricted access where appropriate.
- Restrict administrative access to local connections unless remote administration is explicitly required.
Authentication defaults differ. Some packages create a temporary password that is recorded in an error log or installation output. Other packages configure the local MySQL root account for socket authentication, allowing a privileged local Linux user to connect with:
sudo mysql
On installations using password authentication, use:
mysql -u root -p
Do not assume that a failed password prompt means the server is broken. Determine whether the account expects a password or local socket authentication, and avoid weakening authentication simply to make one command work.
Connect and Validate the Installation
After connecting with an administrative account, run basic SQL checks. The semicolon terminates each SQL statement.
SELECT VERSION();
SHOW DATABASES;
CREATE DATABASE installation_test;
SHOW DATABASES;
DROP DATABASE installation_test;
EXIT;
SELECT VERSION() displays the server version. The test database confirms that the account can create and remove a schema. EXIT or quit leaves the interactive client.
Check the local socket and TCP listener:
sudo ss -lx | grep -i mysql
sudo ss -ltnp | grep 3306
A local socket is a filesystem endpoint used for local connections. A TCP listener on 127.0.0.1:3306 accepts local TCP connections; a listener on another address may accept connections from other hosts.
Common MySQL File and Directory Locations
| Purpose | Debian/Ubuntu example | Red Hat-family example | SUSE example | How to verify on the current host |
|---|---|---|---|---|
| Main configuration | /etc/mysql/my.cnf | /etc/my.cnf | /etc/my.cnf or release-specific path | mysql --help --verbose and package-file queries |
| Included configuration directory | /etc/mysql/mysql.conf.d/ or /etc/mysql/conf.d/ | /etc/my.cnf.d/ | Release-dependent | Inspect !includedir directives and package documentation |
| Data directory | Often /var/lib/mysql | Often /var/lib/mysql | Often /var/lib/mysql | Run SELECT @@datadir; |
| Error logging | systemd journal or a package-specific log directory | systemd journal or /var/log/mysqld.log | systemd journal or package-specific path | journalctl -u mysql or journalctl -u mysqld |
| Socket | Often /var/run/mysqld/mysqld.sock | Often /var/lib/mysql/mysql.sock | Release-dependent | Run SHOW VARIABLES LIKE 'socket'; |
Configuration can be split across several files. Before editing, make a backup and identify which file is actually included.
sudo cp -a /etc/mysql/my.cnf /etc/mysql/my.cnf.backup
Basic Post-install Configuration
Important server settings include:
bind-addresscontrols the network address on which TCP connections are accepted.portcontrols the TCP port, normally3306.datadiridentifies where database files are stored.socketidentifies the local Unix socket.character-set-serverand collation settings control default text encoding and comparison behavior.sql_modecontrols SQL behavior such as validation and handling of ambiguous or invalid data.
A common local-only configuration is:
[mysqld]
bind-address = 127.0.0.1
port = 3306
After changing server configuration, restart the service and check its status:
sudo systemctl restart mysql
sudo systemctl status mysql
Never expose every network interface without a specific requirement, restrictive firewall rules, appropriate accounts, and a plan for monitoring and updates.
Remote Access and Firewall Controls
Remote access is appropriate when an application server, reporting client, or administrator must connect from another host. It increases exposure because the database becomes reachable over a network, so use the smallest possible listening scope and source range.
For an intentional remote setup, bind to the required private address rather than all interfaces:
[mysqld]
bind-address = 192.0.2.10
port = 3306
sudo systemctl restart mysql
sudo ss -ltnp | grep 3306
Create a dedicated account with a limited host pattern and only the required grants. The example uses documentation-reserved addresses:
CREATE USER 'reportuser'@'198.51.100.%' IDENTIFIED BY 'replace-with-a-strong-password';
GRANT SELECT ON appdb.* TO 'reportuser'@'198.51.100.%';
SHOW GRANTS FOR 'reportuser'@'198.51.100.%';
Permit port 3306 only from the authorized source in the host firewall or cloud security rule:
sudo ufw allow from 198.51.100.25 to any port 3306 proto tcp
sudo firewall-cmd --permanent --add-rich-rule='rule family=ipv4 source address=198.51.100.25 port port=3306 protocol=tcp accept'
sudo firewall-cmd --reload
Do not use the MySQL root account for remote application connections. From an authorized client, test the intended address and port:
mysql -h 192.0.2.10 -P 3306 -u reportuser -p appdb
Create an Application Database and User
An application should normally use a dedicated account, not the administrative root account. MySQL accounts are identified by both a user name and a host, so 'appuser'@'localhost' and 'appuser'@'198.51.100.%' are different accounts.
CREATE DATABASE appdb;
CREATE USER 'appuser'@'localhost' IDENTIFIED BY 'replace-with-a-strong-password';
GRANT ALL PRIVILEGES ON appdb.* TO 'appuser'@'localhost';
SHOW GRANTS FOR 'appuser'@'localhost';
ALL PRIVILEGES is convenient for a development account but may be too broad for production. Prefer only the required permissions, such as:
GRANT SELECT, INSERT, UPDATE, DELETE ON appdb.*
TO 'appuser'@'localhost';
Modern MySQL applies account changes immediately. FLUSH PRIVILEGES is generally unnecessary after CREATE USER and GRANT, but may appear in older procedures.
mysql -u appuser -p appdb
SELECT DATABASE();
EXIT;
Use strong, unique passwords and do not place real passwords in shell history, scripts, or source-control files.
Service Management, Logs, and Maintenance
| Task | systemctl command | Expected result |
|---|---|---|
| Start | sudo systemctl start mysql | Starts the service immediately. |
| Stop | sudo systemctl stop mysql | Stops new database service activity. |
| Restart | sudo systemctl restart mysql | Stops and starts the service, applying configuration changes. |
| Reload | sudo systemctl reload mysql | Re-reads supported settings without a full restart; not every unit supports reload. |
| Enable at boot | sudo systemctl enable mysql | Starts the service during future boots. |
| Check status | sudo systemctl status mysql | Shows whether the unit is active and recent failure details. |
Substitute mysqld for mysql when that is the installed unit name.
sudo journalctl -u mysql -e
sudo journalctl -u mysqld -e
sudo df -h
sudo ss -ltnp | grep 3306
Also inspect the distribution-specific MySQL error log when the journal points to it. Routine administration includes checking data-directory ownership and permissions, monitoring disk usage, making tested backups, and planning upgrades. Before an upgrade, confirm version compatibility, read release notes, back up databases and configuration, and test the upgrade path on a non-production system.
Common Installation Differences: MySQL and MariaDB
| Area | Oracle MySQL | MariaDB | Why the difference matters |
|---|---|---|---|
| Provider | Oracle | MariaDB Foundation and community contributors | Release schedules, support, and packaging differ. |
| Default Linux package | May require an official repository | Often supplied by distribution repositories | The command may install a compatible server rather than Oracle MySQL. |
| Service unit | Often mysql or mysqld | Often mariadb | Use the installed unit name with systemd and journalctl. |
| Features and syntax | MySQL-specific features and defaults | Compatibility plus MariaDB-specific features | Applications and migrations must be tested against the selected server. |
| Authentication and files | Version and package dependent | Version and package dependent | Do not copy configuration or authentication instructions between products without checking. |
Troubleshooting
The package manager cannot find a server package
- Refresh package metadata.
- Search available packages with
apt search,dnf search, orzypper search. - List enabled repositories and module streams.
- Confirm the Linux distribution and release.
- Determine whether the default package is MariaDB or whether the intended MySQL repository must be enabled.
The service fails to start
Inspect the unit status and journal first:
sudo systemctl status mysql
sudo journalctl -u mysql -e
Common causes include a configuration syntax error, incorrect data-directory ownership, insufficient disk space, a port conflict, incomplete initialization, or an interrupted upgrade. Check recent edits, df -h, port use with ss, and the MySQL error log. Correct the reported cause, then restart and recheck status.
Access is denied
Check whether the password is correct, whether the account is defined for the connecting host, and whether socket authentication is expected. An account's host component matters: a local account does not automatically authorize a remote client. As an administrator, inspect the account and its grants rather than disabling authentication.
A remote client cannot connect
- Check
bind-addressand the listening socket. - Verify the client uses the correct address and port.
- Review host and cloud firewall rules.
- Confirm that the MySQL account permits the client's source host.
- Check that the server is reachable over the network.
The mysql command is missing
The server package may not include the client, or the client package may be separate. Query installed packages, locate the executable, and install the matching distribution client package if necessary.
Uninstallation and Cleanup
Removing packages is different from deleting database data. Removing the package may leave the data directory and configuration files. Deleting the data directory permanently removes databases unless they have been backed up.
Use this cautious sequence:
- Record the installed version, configuration, service name, and data-directory location.
- Make and verify backups of databases and configuration files.
- Stop the correct service.
- Remove packages using the distribution package manager.
- Only if the data is no longer needed, remove remaining configuration and data files after confirming the backup.
sudo systemctl stop mysql
# Debian/Ubuntu example:
sudo apt remove mysql-server mysql-client
# Review carefully before using purge or deleting data:
sudo apt purge mysql-server mysql-client
On RPM-based systems use dnf remove or yum remove; on SUSE use zypper remove. Do not run a recursive deletion against datadir until the business or learning data is intentionally retired and the backup has been tested.
Installation Checklist
- Distribution, release, server implementation, and supported version are confirmed.
- No conflicting MySQL or MariaDB instance is running.
- Package metadata is refreshed and the intended server and client packages are installed.
- The correct service unit is started, enabled, and active.
- Initial security configuration is complete.
- A local client connection displays the server version and databases.
- A temporary database was created and removed successfully.
- Configuration backups, data backups, disk capacity, and log locations are known.
- Remote access is disabled unless required; if enabled, it uses a restricted bind address, firewall rule, dedicated user, and least-privilege grants.