Infiniroot Blog: We sometimes write, too.

Of course we cannot always share details about our work with customers, but nevertheless it is nice to show our technical achievements and share some solutions.

Install MySQL 5.7 on Ubuntu 20.04 focal (and properly avoid MySQL 8.0 packages)

Published on August 31st 2020 - see original post


The new Ubuntu 20.04 LTS release ships with MySQL 8.0 from the Ubuntu repositories. In many cases this is great news, as MySQL 8.0 is a very recent release of the popular database server. However not all applications might be compatible with MySQL 8.0 just yet. In such a situation the previous release MySQL 5.7 should be installed. But how?

MySQL APT repository

Yes, MySQL run their own package repositories, too. On their MySQL APT repository download page a deb package (mysql-apt-config) can be downloaded and installed. As of this writing, the latest available version of mysql-apt-config is 0.8.15.

root@inf-mysql01-p:~# wget http://repo.mysql.com/mysql-apt-config_0.8.15-1_all.deb

The package can now be installed using dpkg -i. In interactive mode (the default), a ncurses window will show up:

root@inf-mysql01-p:~# dpkg -i mysql-apt-config_0.8.15-1_all.deb

MySQL APT configuration

Inside the first option (MySQL Server & Cluster), a specific version can be selected:

MySQL APT version selection

Here mysql-5.7 was selected. Afterwards the installation was finished by selecting twice Ok.

This creates an apt source in /etc/apt/sources.list.d/:

root@inf-mysql01-p:~# cat /etc/apt/sources.list.d/mysql.list
### THIS FILE IS AUTOMATICALLY CONFIGURED ###
# You may comment out entries below, but any other modifications may be lost.
# Use command 'dpkg-reconfigure mysql-apt-config' as root for modifications.
deb http://repo.mysql.com/apt/ubuntu/ bionic mysql-apt-config
deb http://repo.mysql.com/apt/ubuntu/ bionic mysql-5.7
deb http://repo.mysql.com/apt/ubuntu/ bionic mysql-tools
#deb http://repo.mysql.com/apt/ubuntu/ bionic mysql-tools-preview
deb-src http://repo.mysql.com/apt/ubuntu/ bionic mysql-5.7

An apt-get update (or apt update) activates the repository.

root@inf-mysql01-p:~# apt-get update
Get:1 http://repo.mysql.com/apt/ubuntu bionic InRelease [19.4 kB]
Hit:2 http://ch.archive.ubuntu.com/ubuntu focal InRelease                       
Get:3 http://ch.archive.ubuntu.com/ubuntu focal-updates InRelease [111 kB]      
Get:4 http://ch.archive.ubuntu.com/ubuntu focal-backports InRelease [98.3 kB]
Get:5 http://ch.archive.ubuntu.com/ubuntu focal-updates/main amd64 c-n-f Metadata [8,780 B]
Get:6 http://repo.mysql.com/apt/ubuntu bionic/mysql-5.7 Sources [927 B]              
Get:7 http://security.ubuntu.com/ubuntu focal-security InRelease [107 kB]
Get:8 http://repo.mysql.com/apt/ubuntu bionic/mysql-apt-config amd64 Packages [563 B]
Get:9 http://repo.mysql.com/apt/ubuntu bionic/mysql-apt-config i386 Packages [563 B]
Get:10 http://repo.mysql.com/apt/ubuntu bionic/mysql-5.7 i386 Packages [5,656 B]
Get:11 http://repo.mysql.com/apt/ubuntu bionic/mysql-5.7 amd64 Packages [5,665 B]
Get:12 http://repo.mysql.com/apt/ubuntu bionic/mysql-tools amd64 Packages [7,067 B]
Get:13 http://repo.mysql.com/apt/ubuntu bionic/mysql-tools i386 Packages [5,195 B]
Fetched 370 kB in 3s (144 kB/s)      
Reading package lists... Done

Repository pinning / making the mysql repository the preferred repo

So far so good, but without additional configuration, Ubuntu would still chose to install MySQL 8.0:

root@inf-mysql01-p:~# apt-get install mysql-server
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following additional packages will be installed:
  libhtml-template-perl libmecab2 mecab-ipadic mecab-ipadic-utf8 mecab-utils mysql-client-8.0 mysql-client-core-8.0
  mysql-server-8.0 mysql-server-core-8.0

Suggested packages:
  libipc-sharedcache-perl mailx tinyca
The following NEW packages will be installed:
  libhtml-template-perl libmecab2 mecab-ipadic mecab-ipadic-utf8 mecab-utils mysql-client-8.0 mysql-client-core-8.0
  mysql-server mysql-server-8.0 mysql-server-core-8.0

0 upgraded, 10 newly installed, 0 to remove and 23 not upgraded.
Need to get 29.9 MB of archives.
After this operation, 246 MB of additional disk space will be used.
Do you want to continue? [Y/n] n
Abort.

Note: The installation was manually aborted.

apt needs to be told that the packages from the MySQL repository has precedence and are preferred over the Ubuntu repositories. This can be achieved by using repository pinning (see older article Set higher preference/priority to a apt repository over another for more information). A new apt preference configuration was added into /etc/apt/preferences.d/mysql with the following content:

root@inf-mysql01-p:~# cat /etc/apt/preferences.d/mysql
Package: *
Pin: origin repo.mysql.com
Pin-Priority: 900

Package: *
Pin: origin ch.archive.ubuntu.com
Pin-Priority: 700

Package: *
Pin: origin security.ubuntu.com
Pin-Priority: 800

In this case the packages originating from repo.mysql.com (the domain of the MySQL repository) have the highest pin-priority (900). The second-highest priority (800) come from packages of the Ubuntu Security repos (for security patches) and finally the local Ubuntu mirror, where all the other packages are installed from, has the lowest pin-priority (700). Apt will install packages from the repository with the highest priority first.

After another apt-get update, the local apt settings should be activated.

When the mysql-server install command is again executed, the package names now differ (compared to the first installation attempt):

root@inf-mysql01-p:~# apt-get install mysql-server
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following additional packages will be installed:
  libmecab2 libtinfo5 mysql-client mysql-community-client mysql-community-server
The following NEW packages will be installed:
  libmecab2 libtinfo5 mysql-client mysql-community-client mysql-community-server mysql-server
0 upgraded, 6 newly installed, 0 to remove and 23 not upgraded.
Need to get 51.2 MB of archives.
After this operation, 315 MB of additional disk space will be used.
Do you want to continue? [Y/n] Y

But dpkg returned an error code (1)

Following the above installation, the packages are downloaded and installed - but they (could) fail:

Do you want to continue? [Y/n] Y
Get:1 http://ch.archive.ubuntu.com/ubuntu focal/universe amd64 libtinfo5 amd64 6.2-0ubuntu2 [83.0 kB]
[...]
Setting up mysql-community-server (5.7.31-1ubuntu18.04) ...
update-alternatives: using /etc/mysql/mysql.cnf to provide /etc/mysql/my.cnf (my.cnf) in auto mode
Created symlink /etc/systemd/system/multi-user.target.wants/mysql.service -> /lib/systemd/system/mysql.service.
Job for mysql.service failed because the control process exited with error code.
See "systemctl status mysql.service" and "journalctl -xe" for details.
invoke-rc.d: initscript mysql, action "start" failed.
 mysql.service - MySQL Community Server
     Loaded: loaded (/lib/systemd/system/mysql.service; enabled; vendor preset: enabled)
     Active: activating (auto-restart) (Result: exit-code) since Mon 2020-08-31 13:09:33 CEST; 4ms ago
    Process: 24415 ExecStartPre=/usr/share/mysql/mysql-systemd-start pre (code=exited, status=0/SUCCESS)
    Process: 24505 ExecStart=/usr/sbin/mysqld --daemonize --pid-file=/var/run/mysqld/mysqld.pid (code=exited, status=1/FAILURE)
dpkg: error processing package mysql-community-server (--configure):
 installed mysql-community-server package post-installation script subprocess returned error exit status 1
dpkg: dependency problems prevent configuration of mysql-server:
 mysql-server depends on mysql-community-server (= 5.7.31-1ubuntu18.04); however:
  Package mysql-community-server is not configured yet.

dpkg: error processing package mysql-server (--configure):
 dependency problems - leaving unconfigured

Processing triggers for systemd (245.4-4ubuntu3.2) ...
No apport report written because the error message indicates its a followup error from a previous failure.
Processing triggers for libc-bin (2.31-0ubuntu9) ...
Errors were encountered while processing:
 mysql-community-server
 mysql-server
E: Sub-process /usr/bin/dpkg returned an error code (1)

From the output it is not possible to spot the reason for the error. However when checking the installed mysql packages, something catches the eye:

root@inf-mysql01-p:~# dpkg -l|grep mysql
ii  libmysqlclient21:amd64               8.0.21-0ubuntu0.20.04.4           amd64        MySQL database client library
ii  mysql-apt-config                     0.8.15-1                          all          Auto configuration for MySQL APT Repo.
ii  mysql-client                         5.7.31-1ubuntu18.04               amd64        MySQL Client meta package depending on latest version
ii  mysql-common                         5.8+1.0.5ubuntu2                  all          MySQL database common files, e.g. /etc/mysql/my.cnf
ii  mysql-community-client               5.7.31-1ubuntu18.04               amd64        MySQL Client
iF  mysql-community-server               5.7.31-1ubuntu18.04               amd64        MySQL Server
iU  mysql-server                         5.7.31-1ubuntu18.04               amd64        MySQL Server meta package depending on latest version

The packages libmysqlclient and mysql-common both seem to have the MySQL 8.0 version installed. 

For the libmysqlclient package, this can be verified:

root@inf-mysql01-p:~# apt-cache search libmysqlclient
default-libmysqlclient-dev - MySQL database development files (metapackage)
libmysqlclient21 - MySQL database client library
libcrypt-mysql-perl - Perl module to emulate the MySQL PASSWORD() function
libglpk40 - linear programming kit with integer (MIP) support
librust-mysqlclient-sys-dev - Auto-generated rust bindings for libmysqlclient - Rust source code
libmysqlclient-dev - MySQL development headers
libmysqlclient20 - MySQL shared client libraries
libmysqlclient20-dbgsym - debug symbols for libmysqlclient20

There are two different package names available: libmysqlclient21 and libmysqlclient20. The package with the higher name was installed. Let's look at the package details and see the exact version:

root@inf-mysql01-p:~# apt-cache show libmysqlclient20 | grep Version
Version: 5.7.31-1ubuntu18.04

root@inf-mysql01-p:~# apt-cache show libmysqlclient21 | grep Version
Version: 8.0.21-0ubuntu0.20.04.4
Version: 8.0.19-0ubuntu5

Obviously the libmysqlclient20 package should have been installed for MySQL 5.7 - but the newer libmysqlclient21 was installed.

To deal with this, the pinning needs to be adjusted once more.

Completely avoid mysql packages from Ubuntu repositories

Although the MySQL repository was given a higher pin-priority, mysql-common and libmysqlclient packages were installed from the Ubuntu repositories. Another way to handle this is to turn the pinning around and tell apt to not install any mysql packages at all from the Ubuntu repositories:

root@inf-mysql01-p:~# cat /etc/apt/preferences.d/mysql
Package: *
Pin: origin repo.mysql.com
Pin-Priority: 900

Package: libmysqlclient* mysql*
Pin: origin ch.archive.ubuntu.com
Pin-Priority: -1

Package: libmysqclient* mysql*
Pin: origin security.ubuntu.com
Pin-Priority: -1

The negative pin-priority tells apt to never install a package from this origin. From the apt_preferences man page:

How APT Interprets Priorities
Priorities (P) assigned in the APT preferences file must be positive or negative integers. They are interpreted as follows (roughly speaking):

P >= 1000
causes a version to be installed even if this constitutes a downgrade of the package

990 <= P < 1000
causes a version to be installed even if it does not come from the target release, unless the installed version is more recent

500 <= P < 990
causes a version to be installed unless there is a version available belonging to the target release or the installed version is more recent

100 <= P < 500
causes a version to be installed unless there is a version available belonging to some other distribution or the installed version is more recent

0 < P < 100
causes a version to be installed only if there is no installed version of the package

P < 0
prevents the version from being installed


P = 0
has undefined behaviour, do not use it.

To have a clean setup again, the (half-) installed packages should be uninstalled and purged:

root@inf-mysql01-p:~# apt-get remove mysql-client mysql-common mysql-community-client mysql-community-server mysql-server
root@inf-mysql01-p:~# apt-get purge mysql-client mysql-common mysql-community-client mysql-community-server mysql-server

Then run apt-get update again to read the new apt preferences, followed by a new installation:

root@inf-mysql01-p:~# apt-get update
root@inf-mysql01-p:~# apt-get install mysql-server
Reading package lists... Done
Building dependency tree      
Reading state information... Done
The following package was automatically installed and is no longer required:
  libsnmp-base
Use 'apt autoremove' to remove it.
The following additional packages will be installed:
  mysql-client mysql-common mysql-community-client mysql-community-server
The following NEW packages will be installed:
  mysql-client mysql-common mysql-community-client mysql-community-server mysql-server
0 upgraded, 5 newly installed, 0 to remove and 23 not upgraded.
Need to get 0 B/50.9 MB of archives.
After this operation, 313 MB of additional disk space will be used.
Do you want to continue? [Y/n] y
Preconfiguring packages ...
[...]
Unpacking mysql-server (5.7.31-1ubuntu18.04) ...
Setting up mysql-common (5.7.31-1ubuntu18.04) ...
update-alternatives: using /etc/mysql/my.cnf.fallback to provide /etc/mysql/my.cnf (my.cnf) in auto mode
Setting up mysql-community-client (5.7.31-1ubuntu18.04) ...
Setting up mysql-client (5.7.31-1ubuntu18.04) ...
Setting up mysql-community-server (5.7.31-1ubuntu18.04) ...
update-alternatives: using /etc/mysql/mysql.cnf to provide /etc/mysql/my.cnf (my.cnf) in auto mode
Setting up mysql-server (5.7.31-1ubuntu18.04) ...
Processing triggers for man-db (2.9.1-1) ...
Processing triggers for systemd (245.4-4ubuntu3.2) ...

No error this time! What about the status? Is MySQL 5.7 running?

root@inf-mysql01-p:~# systemctl status mysql
 mysql.service - MySQL Community Server
     Loaded: loaded (/lib/systemd/system/mysql.service; enabled; vendor preset: enabled)
     Active: active (running) since Mon 2020-08-31 14:02:52 CEST; 58s ago
   Main PID: 33086 (mysqld)
      Tasks: 27 (limit: 4620)
     Memory: 172.6M
     CGroup: /system.slice/mysql.service
             |-33086 /usr/sbin/mysqld --daemonize --pid-file=/var/run/mysqld/mysqld.pid

Aug 31 14:02:52 inf-mysql01-p systemd[1]: Starting MySQL Community Server...
Aug 31 14:02:52 inf-mysql01-p systemd[1]: Started MySQL Community Server.
Aug 31 14:02:54 inf-mysql01-p systemd[1]: /lib/systemd/system/mysql.service:37: PIDFile= references a path below legacy dire>

Yes, it is!

TL;DR: Make sure packages from Ubuntu repos don't interfere

Most setups will probably be happy with MySQL 8.0 coming from the Ubuntu repositories. But if you require MySQL 5.7 (for whatever reason) on your Ubuntu 20.04 system, make sure to avoid cross-repository installations of the MySQL packages. By using a negative pin-priority on the relevant package names (see above) this can be handled properly and also covers future updates.

Update: Beware of dependencies of libmysqlclient21 package

Updated September 3rd 2020: Installation of additional Ubuntu packages, such as libsnmp35 (usually used as a dependency), may result in the following error:

root@inf-mysql01-p:~# apt-get install libsnmp35
Reading package lists... Done
Building dependency tree        
Reading state information... Done
Some packages could not be installed. This may mean that you have
requested an impossible situation or if you are using the unstable
distribution that some required packages have not yet been created
or been moved out of Incoming.
The following information may help to resolve the situation:

The following packages have unmet dependencies:
libsnmp35 : Depends: libmysqlclient21 (>= 8.0.11) but it is not installable
E: Unable to correct problems, you have held broken packages.

In this case the apt preferences must be adjusted:

root@inf-mysql01-p:~# cat /etc/apt/preferences.d/mysql
Package: *
Pin: origin repo.mysql.com
Pin-Priority: 900  

Package: mysql*
Pin: origin ch.archive.ubuntu.com
Pin-Priority: -1

Package: mysql*
Pin: origin security.ubuntu.com
Pin-Priority: -1

Compared to the first pinning preferences (see further up in the article), the libmysqlclient* entry was removed. It turns out that this library is actually not needed to run MySQL server itself. So a mix of MySQL 5.7 and a newer libmysqlclient21 (MySQL 8.0) can co-exist:

root@inf-mysql01-p:~# dpkg -l|grep mysql | awk '{print $2" "$3}'
libmysqlclient21:amd64 8.0.21-0ubuntu0.20.04.4
mysql-apt-config 0.8.15-1
mysql-client 5.7.31-1ubuntu18.04
mysql-common 5.7.31-1ubuntu18.04
mysql-community-client 5.7.31-1ubuntu18.04
mysql-community-server 5.7.31-1ubuntu18.04
mysql-server 5.7.31-1ubuntu18.04