CentOS7にMariaDBを入れようとしてハマった話

#発端
CentOS7からはMySQLではなくMariaDBが標準になっているようです。
自宅で使用している環境をCentOS7にしたので、せっかくだからMariaDBを入れようと思ったのですが、少しハマったので今後のために残しておきます。

#TL;DR
MariaDBのバージョンを10.4未満から10.4以上にアップデートする際は、`/var/lib/mysql/mysql/`を削除してからインストールしましょう。
<font color="red">※当記事は、OSにMariaDBを初めてインストールする際の記事です。
すでに運用している場合、/var/lib/mysql/mysql/を削除すると、ユーザ情報等の必要なデータがなくなってしまう可能性があります。</font>

#実際に行った手順
##１．まずはインストールしてみる

```sh:
# インストール
[root@localhost /]# yum install mariadb-server mariadb-client

# MariaDB起動
[root@localhost /]# systemctl start mariadb
```

この段階で、MariaDBのバージョンが10.4.8であることを知り、せっかくだからアップデートをすることに。

##２．10.4.8にアップデート
```sh:停止
# 現在のバージョン確認
[root@localhost /]# mysql --version
mysql  Ver 15.1 Distrib 5.5.60-MariaDB, for Linux (x86_64) using readline 5.1

# MariaDB停止
[root@localhost /]# systemctl stop mariadb
```
yumでアップデートするには、`/etc/yum.repos.d/`内に、ファイルを作成する必要があるのだが、OSのディストリビューションごとに内容が異なるので、設定がちょっと手間。

そこでワンタイムでファイルを作成するコマンドを公式が用意してくれているので、それを用いて実行する。
参考：https://mariadb.com/kb/en/library/mariadb-package-repository-setup-and-usage/

```sh:アップデート
# yumのリポジトリファイルを作成
[root@localhost /]# curl -sS https://downloads.mariadb.com/MariaDB/mariadb_repo_setup | sudo bash

# アップデート
[root@localhost /]# yum update mariadb-server

# 確認
[root@localhost /]# mysql --version
mysql  Ver 15.1 Distrib 10.4.8-MariaDB, for Linux (x86_64) using readline 5.1
```

##３．初期設定
※文字コード等の設定も行いましたが、今回の件とは関係ないため省略してます。

```sh:mysql_secure_installationの実行
## MariaDB起動
[root@localhost /]# systemctl start mariadb

## mysql_secure_installation実行
[root@localhost /]# mysql_secure_installation
```

上記のコマンドを実行して進めようとしたところ以下のようにエラーになってしまった。

```
NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB
      SERVERS IN PRODUCTION USE!  PLEASE READ EACH STEP CAREFULLY!

In order to log into MariaDB to secure it, we'll need the current
password for the root user. If you've just installed MariaDB, and
haven't set the root password yet, you should just press enter here.

Enter current password for root (enter for none):  ←　初期状態なので何も入力せずにENTER
OK, successfully used password, moving on...

Setting the root password or using the unix_socket ensures that nobody
can log into the MariaDB root user without the proper authorisation.

Enable unix_socket authentication? [Y/n] Y
ERROR 1146 (42S02) at line 1: Table 'mysql.global_priv' doesn't exist
Failed!
Cleaning up...
```
mysqlデータベースに`global_priv`というテーブルが存在しない模様。

調べてみるとMariaDB 10.4からユーザ管理は`mysql.user`から`mysql.global_priv`テーブルで行うことになったみたい。
参考：https://mariadb.org/authentication-in-mariadb-10-4/

実際に中身をみてもテーブルが存在しなかった。

```
[root@localhost /]# mysql -uroot -e 'show tables from mysql'
+---------------------------+
| Tables_in_mysql           |
+---------------------------+
| columns_priv              |
| db                        |
| event                     |
| func                      |
| general_log               |
| help_category             |
| help_keyword              |
| help_relation             |
| help_topic                |
| host                      |
| ndb_binlog_index          |
| plugin                    |
| proc                      |
| procs_priv                |
| proxies_priv              |
| servers                   |
| slow_log                  |
| tables_priv               |
| time_zone                 |
| time_zone_leap_second     |
| time_zone_name            |
| time_zone_transition      |
| time_zone_transition_type |
| user                      |
+---------------------------+
```

## ４．MariaDBをアンインストールして再度インストールしてみる
バージョン10.4.8のはずなのに`global_priv`テーブルが存在しなかった。
5.5.60からアップデートしたからかな？と思い、アンインストール後に直接10.4.8をインストールしてみた。

```sh:アンインストールからのインストール
# MariaDB停止
[root@localhost /]# systemctl stop mariadb

# インストールされているMariaDB関連のサービス表示
[root@localhost /]# yum list installed | grep mariadb
MariaDB-client.x86_64                   10.4.8-1.el7.centos            @mariadb-main
MariaDB-common.x86_64                   10.4.8-1.el7.centos            @mariadb-main
MariaDB-compat.x86_64                   10.4.8-1.el7.centos            @mariadb-main
MariaDB-server.x86_64                   10.4.8-1.el7.centos            @mariadb-main
galera-4.x86_64                         26.4.2-1.rhel7.el7.centos      @mariadb 

# アンインストール
[root@localhost /]# yum remove MariaDB-compat MariaDB-server

# アンインストールされているか確認
[root@localhost /]# mysql --version
bash: /usr/bin/mysql: そのようなファイルやディレクトリはありません

# インストール
[root@localhost /]# yum install mariadb-server mariadb-client

# MariaDB起動
[root@localhost /]# systemctl start mariadb

# バージョン確認
[root@localhost /]# mysql --version
mysql  Ver 15.1 Distrib 10.4.8-MariaDB, for Linux (x86_64) using readline 5.1

## mysql_secure_installation実行
[root@localhost /]# mysql_secure_installation
```

上記コマンドを実行しても結果は同じで、`mysql.global_priv`が存在しないと表示されてしまった。

## ５．解決
ここで１時間ぐらい悩んだのだが、ふと`/var/lib/mysql/mysql/`の中身が気になってファイルを覗いてみると確かに`mysql.global_priv`は存在していなかった

```
[root@localhost /]# ls /var/lib/mysql/mysql/
columns_priv.MYD  event.frm          help_category.MYI  help_topic.MYD        ndb_binlog_index.frm  procs_priv.MYI    slow_log.CSM     time_zone.frm              time_zone_transition.MYI
columns_priv.MYI  func.MYD           help_category.frm  help_topic.MYI        plugin.MYD            procs_priv.frm    slow_log.CSV     time_zone_leap_second.MYD  time_zone_transition.frm
columns_priv.frm  func.MYI           help_keyword.MYD   help_topic.frm        plugin.MYI            proxies_priv.MYD  slow_log.frm     time_zone_leap_second.MYI  time_zone_transition_type.MYD
db.MYD            func.frm           help_keyword.MYI   host.MYD              plugin.frm            proxies_priv.MYI  tables_priv.MYD  time_zone_leap_second.frm  time_zone_transition_type.MYI
db.MYI            general_log.CSM    help_keyword.frm   host.MYI              proc.MYD              proxies_priv.frm  tables_priv.MYI  time_zone_name.MYD         time_zone_transition_type.frm
db.frm            general_log.CSV    help_relation.MYD  host.frm              proc.MYI              servers.MYD       tables_priv.frm  time_zone_name.MYI         user.MYD
event.MYD         general_log.frm    help_relation.MYI  ndb_binlog_index.MYD  proc.frm              servers.MYI       time_zone.MYD    time_zone_name.frm         user.MYI
event.MYI         help_category.MYD  help_relation.frm  ndb_binlog_index.MYI  procs_priv.MYD        servers.frm       time_zone.MYI    time_zone_transition.MYD   user.frm
```

そして、MariaDBアンインストール後も`/var/lib/mysql/`ディレクトリは残ったままになっていた。

そこで、MariaDBアンインストール後に`/var/lib/mysql/mysql/`ディレクトリを削除してからインストールすると`mysql.global_priv`が作成され、mysql_secure_installationもうまく実行することができるようになった。

```sh:
# MariaDB停止
[root@localhost /]# systemctl stop mariadb

# アンインストール
[root@localhost /]# yum remove MariaDB-compat MariaDB-server

# /var/lib/mysql/mysql/削除
[root@localhost /]# rm -rf /var/lib/mysql/mysql/

# インストール
[root@localhost /]# yum install mariadb-server mariadb-client

# MariaDB起動
[root@localhost /]# systemctl start mariadb

# mysql_secure_installation実行
[root@localhost /]# mysql_secure_installation

NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB
      SERVERS IN PRODUCTION USE!  PLEASE READ EACH STEP CAREFULLY!

In order to log into MariaDB to secure it, we'll need the current
password for the root user. If you've just installed MariaDB, and
haven't set the root password yet, you should just press enter here.

Enter current password for root (enter for none): 
OK, successfully used password, moving on...

Setting the root password or using the unix_socket ensures that nobody
can log into the MariaDB root user without the proper authorisation.

You already have your root account protected, so you can safely answer 'n'.

Switch to unix_socket authentication [Y/n] Y
Enabled successfully!
Reloading privilege tables..
 ... Success!    ←　通った！


You already have your root account protected, so you can safely answer 'n'.

Change the root password? [Y/n] n
 ... skipping.

By default, a MariaDB installation has an anonymous user, allowing anyone
to log into MariaDB without having to have a user account created for
them.  This is intended only for testing, and to make the installation
go a bit smoother.  You should remove them before moving into a
production environment.

Remove anonymous users? [Y/n] Y
 ... Success!

Normally, root should only be allowed to connect from 'localhost'.  This
ensures that someone cannot guess at the root password from the network.

Disallow root login remotely? [Y/n] Y
 ... Success!

By default, MariaDB comes with a database named 'test' that anyone can
access.  This is also intended only for testing, and should be removed
before moving into a production environment.

Remove test database and access to it? [Y/n] Y
 - Dropping test database...
 ... Success!
 - Removing privileges on test database...
 ... Success!

Reloading the privilege tables will ensure that all changes made so far
will take effect immediately.

Reload privilege tables now? [Y/n] Y
 ... Success!

Cleaning up...

All done!  If you've completed all of the above steps, your MariaDB
```

# まとめ
MariaDB（MySQLも？）では`systemctl start mariadb`を実行したときに
`/var/lib/mysql/`内にmysqlというディレクトリが存在しない場合は作成し、すでに存在している場合は何もしない仕組みになっているのかと思われます。

なので、5.5.60をインストールして`systemctl start mariadb`を実行した時、`/var/lib/mysql/mysql/`ディレクトリが作られてしまい（このときは`mysql.global_priv`が存在しない）、
その後は`/var/lib/mysql/mysql/`が存在するため、何をしても`mysql.global_priv`が作られなかったのだろうと思います。