DB-유

Installing MySQL 5.7 on CentOS 7 Step by Step

· mysql, centos, installation

I keep forgetting that CentOS 7 ships MariaDB 5.5, not MySQL, and every new server reminds me the hard way. When a vendor only tests against Oracle's builds, or I want the JSON type and the newer InnoDB features, I go to the official MySQL Yum repository. 5.7 also changed a few things from 5.6: a random temporary root password, and validate_password on by default. That trips up almost everyone on first login, me included.

This is what I run on a fresh CentOS 7 minimal install. You need root or sudo, outbound HTTPS to repo.mysql.com, and no old MariaDB or MySQL packages. Check with rpm -qa | grep -i -E 'mariadb|mysql'; mariadb-libs is usually there and gets replaced automatically.

Add the MySQL Yum repository

Download the release package for EL7 and install it. It adds the repo definitions under /etc/yum.repos.d/ and imports the GPG key.

sudo yum install -y https://dev.mysql.com/get/mysql57-community-release-el7-9.noarch.rpm
sudo yum repolist enabled | grep mysql

You should see mysql57-community in the list. The same release package also contains the 5.5, 5.6 and 8.0 development repos, disabled by default. If you ever need to switch, use yum-config-manager --disable mysql57-community together with --enable for the other one, but leave it alone here.

Install the server package

sudo yum install -y mysql-community-server

This pulls in mysql-community-client, mysql-community-common and mysql-community-libs, and it replaces mariadb-libs. Confirm the version afterwards:

mysqld --version
# mysqld  Ver 5.7.17 for Linux on x86_64 (MySQL Community Server (GPL))

Start it and enable it at boot

sudo systemctl start mysqld
sudo systemctl enable mysqld
sudo systemctl status mysqld

The first start initializes the data directory in /var/lib/mysql, creates the system tables, generates SSL certificates, and creates root@localhost with a random password. That password is written to the error log, not to the console.

Find the temporary root password

sudo grep 'temporary password' /var/log/mysqld.log
# 2017-01-03T09:12:44.123456Z 1 [Note] A temporary password is generated for root@localhost: k;Rt3!qwErTy

Copy the string after the colon exactly. I paste it rather than type it, since those passwords are full of characters that look alike. It's marked as expired, so the only statement you can run before changing it is ALTER USER.

mysql_secure_installation

sudo mysql_secure_installation

Enter the temporary password, then set a new one. Because validate_password is loaded with policy MEDIUM, the new password must be at least 8 characters and contain upper and lower case letters, a digit and a special character. Answer Y to removing anonymous users, disallowing remote root login, removing the test database and reloading privilege tables.

If you prefer to do this manually instead of through the script:

ALTER USER 'root'@'localhost' IDENTIFIED BY 'N3w-Str0ng-Passw0rd!';

A starting /etc/my.cnf

On CentOS the main config file is /etc/my.cnf. This is my usual starting point for a small dedicated server:

[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
symbolic-links=0
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
innodb_buffer_pool_size=1G
innodb_log_file_size=256M
innodb_file_per_table=1
max_connections=200

Set innodb_buffer_pool_size to roughly 50–70% of RAM on a database-only box. Restart after editing:

sudo systemctl restart mysqld

Firewall, only if you need remote access

sudo firewall-cmd --permanent --add-service=mysql
sudo firewall-cmd --reload

This opens TCP 3306. Do not do this on a server where only local applications connect; keep bind-address=127.0.0.1 in my.cnf instead.

Did it work?

mysql -u root -p -e "SELECT VERSION(); SHOW VARIABLES LIKE 'character_set_server';"

You should get the 5.7.x version string and utf8mb4. Also check systemctl is-enabled mysqld; I've been burned by a service that was running but not enabled.

Errors I keep seeing

  • ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this statement. – You logged in with the temporary password and tried to run something else. Run the ALTER USER statement from the secure-installation section first.
  • ERROR 1819 (HY000): Your password does not satisfy the current policy requirements – The new password is too weak for validate_password. Either choose a stronger one or lower the policy with SET GLOBAL validate_password_policy=LOW; (not recommended on production).
  • Job for mysqld.service failed because the control process exited with error code after editing my.cnf – Almost always a typo or an innodb_log_file_size change on an existing data directory. Check sudo tail -50 /var/log/mysqld.log; if you changed the log file size on 5.7 it should resize automatically, but a bad option name will stop startup.
  • Transaction check error: file /usr/share/mysql/... conflicts between attempted installs – Leftover MariaDB packages. Remove them with yum remove mariadb-libs and rerun the install.

Next I usually create a limited application user and a nightly mysqldump job. Those are separate posts.