1. Overview

While one rarely looks forward to it, sometimes databases and the database management system (DBMS) can get corrupted. Unfortunately, when this happens, we might have to completely reinstall the database management system.

Ordinarily, if we’re trying to reinstall MySQL on Linux, we can uninstall and install using the distro’s package manager. Still, if the current installation is corrupted, the usual way may not work for us. So, our best bet could be a purge and clean reinstall.

In this tutorial, we’ll learn how to do a complete clean reinstall of MySQL on Debian and Red Hat Linux distros. For each distro, we’ll go over what to expect as we run the commands. Finally, we look at a scenario, where the uninstall doesn’t work as expected.

2. Using the apt Command

The apt command is the default package manager for Debian-based distros. Thus, we use it to perform a clean reinstall of most packages.

2.1. Uninstalling MySQL

When trying to remove MySQL or any other package completely, we usually uninstall it.

However, the normal uninstall commands can leave some files and metadata. Yet, leftover data might prevent us from successfully setting up MySQL after removing it. For example, a corrupt database could persist.

So, we can include the –purge switch in the regular apt remove command:

$ sudo apt remove --purge mysql\* -y
...truncated...
The following packages will be REMOVED:
mysql-apt-config* mysql-client* mysql-common* mysql-community-client* mysql-community-client-core*
mysql-community-client-plugins* mysql-community-server* mysql-community-server-core* mysql-server*
0 upgraded, 0 newly installed, 9 to remove and 48 not upgraded.
After this operation, 298 MB disk space will be freed.
...truncated...
Removing mysql-common (8.0.31-1debian11) ...
...truncated...
Purging configuration files for mysql-community-server (8.0.31-1debian11) ...

Critically this command thoroughly cleans the MySQL installation. Because of this, we should only use this method when we have a backup of our databases or when we have no means of retrieving any corrupt data.

After running the command above, we check for leftovers with find:

$ sudo find / -name mysql
/etc/apparmor.d/abstractions/mysql
/usr/lib/python3/dist-packages/ansible_collections/community/mysql
/usr/share/bash-completion/completions/mysql
/usr/share/php8.1-mysql/mysql

This find command is a basic way to verify whether we still have MySQL files and directories. In our case, it returns some MySQL files and directories, but they aren’t directly related to the MySQL package. So, we’ll ignore them.

2.2. Installing or Reinstalling MySQL

After confirming that we’ve successfully done a clean removal of MySQL, we can move to the next step – reinstallation.

To set up MySQL again, we could use the regular install subcommand:

$ sudo apt install mysql mysql-server
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
Package mysql-server is not available, but is referred to by another package.
This may mean that the package is missing, has been obsoleted, or
is only available from another source

E: Unable to locate package mysql
E: Package 'mysql-server' has no installation candidate

Yet, as our output shows, that command might not work on some Debian distros.

Instead, we can set up MySQL by downloading the MySQL repo setup package for Debian distros, which we can find on the official MySQL website:

$ wget http://repo.mysql.com/mysql-apt-config_0.8.24-1_all.deb
--2022-12-28 16:58:55-- http://repo.mysql.com/mysql-apt-config_0.8.24-1_all.deb
Resolving repo.mysql.com (repo.mysql.com)... 104.123.44.225
Connecting to repo.mysql.com (repo.mysql.com)|104.123.44.225|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 18048 (18K) [application/x-debian-package]
Saving to: ‘mysql-apt-config_0.8.24-1_all.deb.2’ mysql-apt-config_0.8.24-1_all
  100%[=================================================>] 17.62K --.-KB/s in 0.005s
2022-12-28 16:58:57 (3.38 MB/s) - ‘mysql-apt-config_0.8.24-1_all.deb.2’ saved [18048/18048]

After that, we install the .deb file via dpkg:

$ sudo dpkg -i mysql-apt-config_0.8.24-1_all.deb
(Reading database ... 90853 files and directories currently installed.)
Preparing to unpack mysql-apt-config_0.8.24-1_all.deb ...
Unpacking mysql-apt-config (0.8.24-1) over (0.8.24-1) ...
Setting up mysql-apt-config (0.8.24-1) ...
Warning: apt-key should not be used in scripts (called from postinst maintainerscript of the package mysql-apt-config)
Warning: apt-key is deprecated. Manage keyring files in trusted.gpg.d instead (see apt-key(8)).
OK

Next, let’s update the package information:

$ sudo apt update
Hit:1 http://repo.mysql.com/apt/debian bullseye InRelease
Hit:2 http://deb.debian.org/debian bullseye InRelease
Hit:3 http://security.debian.org/debian-security bullseye-security InRelease
Get:4 http://deb.debian.org/debian bullseye-updates InRelease [44.1 kB]
Get:5 https://packages.sury.org/php bullseye InRelease [6,841 B]
Fetched 50.9 kB in 6s (8,062 B/s)
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
48 packages can be upgraded. Run 'apt list --upgradable' to see them.

Finally, we can install MySQL:

$ sudo apt install mysql-server -y
...truncated...
 mysql-community-server mysql-community-server-core mysql-server
0 upgraded, 8 newly installed, 0 to remove and 48 not upgraded.
Need to get 0 B/35.1 MB of archives.
After this operation, 298 MB of additional disk space will be used.
Preconfiguring packages ...
Selecting previously unselected package mysql-common.
...truncated...
Setting up mysql-community-client (8.0.31-1debian11) ...
...truncated...
Processing triggers for libc-bin (2.31-13+deb11u4) ...

At this time, the latest version of the MySQL apt repo is 0.8.24-1. When running these commands, we can adjust the repository configuration package version accordingly, if necessary.

After we run the installation commands, we can check whether MySQL is up and running.

3. Using the yum Command

When trying to do a clean MySQL reinstall on a Red Hat Linux distro, we can use yum or dnf.

3.1. Uninstalling MySQL

To ensure we remove MySQL and its dependencies, we use the autoremove subcommand of yum or dnf:

$ sudo yum autoremove mysql\* -y
Loaded plugins: fastestmirror
Resolving Dependencies
--> Running transaction check
---> Package mysql-community-client.x86_64 0:8.0.31-1.el7 will be erased
--> Processing Dependency: mysql-community-client(x86-64) >= 8.0.11 for package: mysql-community-server-8.0.31-1.el7.x86_64
...truncated...
Removed: mysql-community-client.x86_64 0:8.0.31-1.el7
  Dependency Removed: libaio.x86_64 0:0.3.109-13.el7 mysql-community-client-plugins.x86_64 0:8.0.31-1.el7
  mysql-community-common.x86_64 0:8.0.31-1.el7 mysql-community-icu-data-files.x86_64 0:8.0.31-1.el7
...truncated...
Complete!

Since using yum remove alone doesn’t remove dependencies, we use autoremove to remove any trace of MySQL completely.

After running the command above, we can again use find to check for any related files we don’t expect:

$ sudo find / -name mysql
/etc/selinux/targeted/active/modules/100/mysql
/var/lib/mysql
/var/lib/mysql/mysql
/usr/lib64/mysql

In this case, the output reveals we have three leftover MySQL files. Let’s delete them manually using the rm command:

$ sudo rm -rf /var/lib/mysql /usr/lib64/mysql

At this time, we should be ready for a reinstall.

3.2. Installing or Reinstalling MySQL

To install MySQL, we can use yum install:

$ sudo yum install mysql

However, in the absence of the MySQL yum repo, this may pick the MariaDB package.

To avoid that, we add the MySQL RPM repo as we did for apt:

$ wget https://dev.mysql.com/get/mysql80-community-release-el7-7.noarch.rpm
--2022-12-28 16:37:32--  https://dev.mysql.com/get/mysql80-community-release-el7-7.noarch.rpm
Resolving dev.mysql.com (dev.mysql.com)... 23.39.113.250, 2a02:26f0:e0:5bd::2e31, 2a02:26f0:e0:594::2e31
Connecting to dev.mysql.com (dev.mysql.com)|23.39.113.250|:443... connected.
HTTP request sent, awaiting response... 302 Moved Temporarily
Location: https://repo.mysql.com//mysql80-community-release-el7-7.noarch.rpm [following]
--2022-12-28 16:37:35--  https://repo.mysql.com//mysql80-community-release-el7-7.noarch.rpm
Resolving repo.mysql.com (repo.mysql.com)... 23.215.180.253
Connecting to repo.mysql.com (repo.mysql.com)|23.215.180.253|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 11196 (11K) [application/x-redhat-package-manager]
Saving to: ‘mysql80-community-release-el7-7.noarch.rpm.1’

100%[======================================================================================================>] 11,196      --.-K/s   in 0s

2022-12-28 16:37:36 (98.9 MB/s) - ‘mysql80-community-release-el7-7.noarch.rpm.1’ saved [11196/11196]

Then, we’ll install the repo configuration:

$ sudo yum install mysql80-community-release-el7-7.noarch.rpm -y
Loaded plugins: fastestmirror
Examining mysql80-community-release-el7-7.noarch.rpm: mysql80-community-release-el7-7.noarch
Marking mysql80-community-release-el7-7.noarch.rpm to be installed
...truncated...
Dependencies Resolved
...truncated...
Running transaction
  Installing : mysql80-community-release-el7-7.noarch                                              1/1
  Verifying  : mysql80-community-release-el7-7.noarch                                              1/1
Installed:
  mysql80-community-release.noarch 0:el7-7
Complete!

Finally, we can deploy MySQL with the new repo in place:

$ sudo yum install mysql-community-server -y
Loaded plugins: fastestmirror
...truncated...
Resolving Dependencies
--> Running transaction check
---> Package mysql-community-server.x86_64 0:8.0.31-1.el7 will be installed
--> Processing Dependency: mysql-community-common(x86-64) = 8.0.31-1.el7 for package: mysql-community-server-8.0.31-1.el7.x86_64
...truncated...
Installed:
  mysql-community-server.x86_64 0:8.0.31-1.el7
Dependency Installed:
libaio.x86_64 0:0.3.109-13.el7
...truncated...
mysql-community-client.x86_64 0:8.0.31-1.el7
...truncated...
perl-threads-shared.x86_64 0:1.43-6.el7
Complete!

Now, we can start MySQL:

$ sudo systemctl start mysqld

MySQL yum repos are available for various RHEL versions and other distros.

4. MySQL Reinstallation Issues

In some cases, MySQL installations get corrupt beyond repair. This is usually a result of no configuration, misconfiguration, or data corruption.

Importantly, these issues are mainly prevalent in older versions of the MySQL server and client packages such as 5.7 and below.

4.1. Problem Description

The problem manifests itself either when attempting to uninstall and purge or when trying to reinstall the package:

$ apt-get install mysql-server
...
dpkg: error processing package mysql-server (--configure):
 dependency problems - leaving unconfigured
No apport report written because the error message indicates its a followup error from a previous failure.
Errors were encountered while processing:
 mysql-server-5.7
 mysql-server
E: Sub-process /usr/bin/dpkg returned an error code (1)

This is one example, in which the reinstallation fails due to a problem during the configure phase.

However, we can encounter issues during removal attempts as well:

$ apt-get remove mysql-server
...
dpkg: error processing package mysql-server-5.7 (--configure):
subprocess installed post-installation script returned error exit status 1
Errors were encountered while processing:
mysql-server-5.7
E: Sub-process /usr/bin/dpkg returned an error code (1)

In other words, we are in a limbo state that prevents us from fully installing and configuring, but also completely removing the package.

4.2. Root Cause

How the configuration gets incomplete or corrupt may not matter, but there is a common case:

  1. Install MySQL Server, e.g., via apt-get install mysql-server
  2. Create a new database, e.g., via mysql -uroot -pPASSWORD -e ‘CREATE DATABASE xdb;’
  3. Decide to remove MySQL Server via apt-get remove mysql-server without purging
  4. Try to apt-get –purge remove mysql-server after the package has already been removed

At this point, as we already saw, there are leftover packages and files from the main installation. The apt autoremove command should be able to remove these packages and files:

$ apt autoremove

However, we may decide to perform a manual cleanup before or instead of that:

$ rm -rf /usr/sbin/mysqld /usr/share/man/man8/mysql* /usr/share/man/man1/mysql* /usr/bin/mysql*
  /usr/share/doc/mysql* /usr/share/lintian/overrides/mysql* /usr/share/mysql* /usr/lib/mysql*

Manual package file removal should only be performed after using apt autoremove and ensuring the relevant packages are marked as not installed. Otherwise, it can lead to corrupt packages and configurations.

To check for leftovers, we can also use dpkg-query:

$ dpkg-query -l <PACKAGE_NAME>

In the output, un means the package installation is corrupt or unknown, while rc indicates a removal without proper configuration file purging.

Another way to end up in this situation is with a misconfigured mysqld service which can’t start. Since the scripts that run when installing and uninstalling the package may attempt to execute the MySQL service, this failure results in a halt of the process.

4.3. Fix Broken Installation

Often, apt is aware of corruption or half-installed packages. So, we can attempt to fix such instances via the –fix-broken and –fix-missing flags:

$ apt-get update && apt-get install --fix-broken --fix-missing mysql-server

This way, we attempt to let the package manager handle the issue.

4.4. Purge Version Package

The mysql-server metapackage points to the current mysql-server- package. Because of this, we can try to purge the version package:

$ apt-get purge mysql-server mysql-server-5.7

If this doesn’t work, we turn to the mysql service as the possible culprit.

4.5. Resolving mysql Service Issues

Service checks are done via the service or systemctl command:

$ systemctl status mysql
● mysql.service - MySQL Community Server
   Loaded: loaded (/lib/systemd/system/mysql.service; enabled; vendor preset: enabled)
   Active: active (running) since Tue 2017-05-10 21:10:05 EST; 1h 1min ago
 Main PID: 6616 (mysqld)
   CGroup: /system.slice/mysql.service
           └─6616 /usr/sbin/mysqld

In this case, it’s active. This means we won’t have a problem with running the service. In case of errors, we get the appropriate output. Attempting to resolve the errors can be a viable solution. However, how we can do that is outside the scope of this article.

If the service is running, let’s stop it and ensure it goes down:

$ systemctl stop mysql
$ systemctl kill mysql

At this point, we can retry the purge and reinstall.

5. Conclusion

In this article, we learned how to do a complete clean reinstall of MySQL on two major Linux distributions: Debian and Red Hat. Further, we saw how to attempt to resolve potential issues during the installation and removal of the mysql-server package.

Overall, the installation and uninstallation processes and commands for both distros are pretty similar. However, the discrepancies between the package manager and the filesystem remain. So, in the end, we can’t use the same exact files and commands to pull off a clean reinstall of MySQL on all Linux distros.