MAGAZINE

ルーターマガジン

インフラ/運用

【MariaDB 10.4 】 Linux Ubuntu 上でMariaDB をバージョン指定してインストールしたい!

2021.12.22
Pocket

ルータのkanazawaです。

エンジニアとしてお仕事を始める上で、まず立ちはだかる壁が環境構築です。 特に弊社では新入社員・アルバイトのみなさんには

  • HTML
  • Ruby
  • DB (MariaDB)
  • Git
  • スクレイピング

についての研修を8〜15営業日ほどかけてみっちりやって頂いていますが、この中でも、特に苦戦しているのがMariaDBのインストールだったりします。 特に、業務で使用する場合は環境を揃えるためにバージョンの指定が有ることが多く、ググってもいい情報に巡り会えないことが多いです。

この記事では、MariaDBを初めて使う人に向けて、インストール方法の解説をしたいと思います。最後には、WSL上でMariaDB 10.4を使う場合にハマりがちなポイントもまとめてあるので、興味の有る方はそちらもご覧ください。

環境

このインストール手順は、以下の環境で試しています。

  • OS: Ubuntu 20.04.3 focal
  • ターゲットDB: MariaDB 10.4

筆者の環境ではないですが、 Ubuntu 18.04 bionic でも本質的には問題ないはずです。

MariaDBインストール手順

公式にしたがってaptを使えばOKです。

まずはMariaDBの公式に行って、aptのリポジトリの更新をします。 若干、初心者に優しくないサイトですが、まずは手元のLinuxのディストリビューションとバージョンに従って、上記の画像の項目を選択します。上から順番に

  • OSのディストリビューションとバージョン
  • インストールするMariaDBバージョン
  • ミラーサーバの場所

です。ミラーサーバの場所は、日本国内ならば山形大学一択なので、それを選んで下さい。(国外からダウンロードする場合は、物理的に近い場所のサーバを選びましょう。) すると、aptパッケージの更新用のコマンドが現れるので、ターミナルにコピーして実行します。

sudo apt-get install software-properties-common dirmngr apt-transport-https
sudo apt-key adv --fetch-keys 'https://mariadb.org/mariadb_release_signing_key.asc'
sudo add-apt-repository 'deb [arch=amd64,arm64,ppc64el,s390x] https://ftp.yz.yamagata-u.ac.jp/pub/dbms/mariadb/repo/10.4/ubuntu focal main'

これによって、aptコマンドでmariadbのパッケージを取得する準備ができます。3つ目のコマンドがミソでaptが参照するリポジトリの一覧に、山形大学のサーバーに有るubuntu(focal)向けのmariadb 10.4 のパッケージを追加しているんですね。

このコマンドが成功したら次に、インストールのコマンドを実行しましょう。公式サイトに従って、以下を実行します。1つ目のコマンドは、さっきaptが参照するリポジトリにmariadbを追加したため、手元のPCでaptが管理している情報を更新するために必要です。2つ目のコマンドによって、実際にmariadb サーバ(と関連ソフトウェア)のインストールが実行されます。

sudo apt update
sudo apt install mariadb-server

以下は筆者環境のログですが、失敗せずに終わればこのように、triggerの設定で終わります。

% sudo apt install mariadb-server                                                                                                            
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following additional packages will be installed:
  galera-4 libaio1 libcgi-fast-perl libcgi-pm-perl libdbd-mysql-perl libdbi-perl libfcgi-perl libhtml-template-perl libmariadb3 libmysqlclient21 libreadline5
  libterm-readkey-perl mariadb-client-10.4 mariadb-client-core-10.4 mariadb-common mariadb-server-10.4 mariadb-server-core-10.4 mysql-common socat
Suggested packages:
  libclone-perl libmldbm-perl libnet-daemon-perl libsql-statement-perl libipc-sharedcache-perl mailx mariadb-test tinyca
The following NEW packages will be installed:
  galera-4 libaio1 libcgi-fast-perl libcgi-pm-perl libdbd-mysql-perl libdbi-perl libfcgi-perl libhtml-template-perl libmariadb3 libmysqlclient21 libreadline5
  libterm-readkey-perl mariadb-client-10.4 mariadb-client-core-10.4 mariadb-common mariadb-server mariadb-server-10.4 mariadb-server-core-10.4 mysql-common socat
0 upgraded, 20 newly installed, 0 to remove and 37 not upgraded.
Need to get 28.3 MB of archives.
After this operation, 221 MB of additional disk space will be used.
Do you want to continue? [Y/n] Y
Get:1 https://ftp.yz.yamagata-u.ac.jp/pub/dbms/mariadb/repo/10.4/ubuntu focal/main arm64 mysql-common all 1:10.4.22+maria~focal [5,552 B]
...中略...
Setting up mariadb-server (1:10.4.22+maria~focal) ...
Processing triggers for libc-bin (2.31-0ubuntu9.2) ...
Processing triggers for man-db (2.9.1-1) ...
Processing triggers for doc-base (0.10.9) ...
Processing 1 added doc-base file...

Ubuntu ならば、systemctlが使えるはずなので、aptでのインストールが完了した段階で、mariadb-serverがsystemctlに登録されるはずです。そのため、特にmariadb-serverの立ち上げを意識すること無く、クライアントコマンドからローカルのサーバに接続することができるはずです。ターミナルから以下のように、ローカルのMariaDBサーバに接続してバージョンを確認してみましょう。

立ち上げ周りで問題があれば、こちらの記事も是非見て下さい。ユーザ権限周りでログインに失敗している場合、こちらの記事もおすすめです!

% mysql -uroot
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 37
Server version: 10.4.22-MariaDB-1:10.4.22+maria~focal-log mariadb.org binary distribution

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> select version();
+-------------------------------------------+
| version()                                 |
+-------------------------------------------+
| 10.4.22-MariaDB-1:10.4.22+maria~focal-log |
+-------------------------------------------+
1 row in set (0.000 sec)

ちゃんと10.4になってますね。これでインストールが完了しました。お疲れ様です🍻

WSL上UbuntuでMariaDB 10.4をインストールするときにハマりがちポイント

先程、インストール手順の中で"Ubuntu ならば、systemctlが使える"と簡単に書きましたが、実はここにトラップがあって、WSL上でUbuntuを使っている場合、場合によってはそこにハマってしまうケースが見られます。

WSL上でUbuntuを使っている場合、systemctlに対応していないため代わりにserviceというコマンドによって、各サービスの管理を行うことになります。本来ならば、systemctlserviceのどちらも使えるようにaptはmariadbをインストールしてくれる筈なのですが、mariadb 10.4 の場合には、どうやらserviceが参照する/etc/init.dというディレクトリにmariadbのサービス実行用のBashスクリプトが生成されないという問題が有るようです。

改めてmariadb-serverのインストールログを丹念に見ると次のように、如何にもクサイログが出ています。私はmysqlをまだ入れていないはずなのに、stopに失敗するとは… そもそも入ってないなら loadされて無くて当然では??

Failed to stop mysql.service: Unit mysql.service not loaded.

この問題の解決策としては、aptが/etc/init.dにmariadbの起動スクリプトの展開に失敗しているので、その展開を自分でやればいいじゃん👌 という手があります。 例えばここを参考にして、以下のコマンドを実行します。

sudo cp /usr/share/mysql/mysql.init /etc/init.d/mysql
sudo chmod a+x /etc/init.d/mysql

これは/usr/share/mysql/mysql.initにmysqlサーバの起動スクリプトが置かれるはずなので、それをserviceの管理下である/etc/init.dにコピーして実行権限を付与しています。こうすることで、service経由でmariadb-serverの起動ができるようになりWSL上でもMariaDB 10.4が使用出来ます。

更に四方山(興味があれば読んでね)

前述の、mariadb 10.4 の場合には、どうやらserviceが参照する/etc/init.dというディレクトリにmariadbのサービス実行用のBashスクリプトが生成されないという問題にともなって、systemctlが入っている素Ubuntu上で、serviceコマンドを実行すると次のような奇妙なことが置きます。まず、sudo service --status-all | grep mysqlでmysqlサービスが立ち上がっているか確認します。

% sudo service --status-all | grep mysql               
                                         

結果は空ですね。つまりmysqlserviceの管理対象に登録されていないことがわかります。しかし、今度はsudo service mysql statusでmysqlのステータスを確認すると...

% sudo service mysql status             
● mariadb.service - MariaDB 10.4.22 database server
     Loaded: loaded (/lib/systemd/system/mariadb.service; enabled; vendor preset: enabled)
    Drop-In: /etc/systemd/system/mariadb.service.d
             └─migrated-from-my.cnf-settings.conf
     Active: active (running) since Mon 2021-12-20 12:01:01 JST; 48min ago
       Docs: man:mysqld(8)
             https://mariadb.com/kb/en/library/systemd/
    Process: 17804 ExecStartPre=/usr/bin/install -m 755 -o mysql -g root -d /var/run/mysqld (code=exited, status=0/SUCCESS)
    Process: 17805 ExecStartPre=/bin/sh -c systemctl unset-environment _WSREP_START_POSITION (code=exited, status=0/SUCCESS)
...後略...                                         

なんと普通に立ち上がっています。

これは実はserviceコマンドが、システムにsystemctlが入っている場合は、そちらを呼び出すように作られているからなんですね。/usr/sbin/serviceを見てみると(Bashスクリプトなので読めます)、超抜粋ですが、次のように内部でsystemctlを呼び出していることがわかります。

   case "${ACTION}" in
      restart|status|try-restart)
         exec systemctl $sctl_args ${ACTION} ${UNIT}
      ;;

しかし、serviceコマンドをオプション--status-allで実行した場合、次のコードが走るのですが、見ての通り、SERVICEDIRに登録されているコマンドに対してループを回すように実装されていますね。SERVICEDIRとは言わずもがな、/etc/init.dです。なのでここに登録されていないサービスは、sudo service --status-allで表示されなかったわけです。

       if [ -z "${SERVICE}" -a $# -eq 1 -a "${1}" = "--status-all" ]; then
          cd ${SERVICEDIR}
          for SERVICE in * ; do
            case "${SERVICE}" in
              functions | halt | killall | single| linuxconf| kudzu)
                  ;;
              *)
                if ! is_ignored_file "${SERVICE}" \
		    && [ -x "${SERVICEDIR}/${SERVICE}" ]; then
                        out=$(env -i LANG="$LANG" LANGUAGE="$LANGUAGE" LC_CTYPE="$LC_CTYPE" LC_NUMERIC="$LC_NUMERIC" LC_TIME="$LC_TIME" LC_COLLATE="$LC_COLLATE" LC_MONETARY="$LC_MONETARY" LC_MESSAGES="$LC_MESSAGES" LC_PAPER="$LC_PAPER" LC_NAME="$LC_NAME" LC_ADDRESS="$LC_ADDRESS" LC_TELEPHONE="$LC_TELEPHONE" LC_MEASUREMENT="$LC_MEASUREMENT" LC_IDENTIFICATION="$LC_IDENTIFICATION" LC_ALL="$LC_ALL" PATH="$PATH" TERM="$TERM" "$SERVICEDIR/$SERVICE" status 2>&1)
                        retval=$?
                        if echo "$out" | egrep -iq "usage:"; then
                          #printf " %s %-60s %s\n" "[?]" "$SERVICE:" "unknown" 1>&2
                          echo " [ ? ]  $SERVICE" 1>&2
                          continue
                        else
                          if [ "$retval" = "0" -a -n "$out" ]; then
                            #printf " %s %-60s %s\n" "[+]" "$SERVICE:" "running"
                            echo " [ + ]  $SERVICE"
                            continue
                          else
                            #printf " %s %-60s %s\n" "[-]" "$SERVICE:" "NOT running"
                            echo " [ - ]  $SERVICE"
                            continue
                          fi
                        fi
                  #env -i LANG="$LANG" LANGUAGE="$LANGUAGE" LC_CTYPE="$LC_CTYPE" LC_NUMERIC="$LC_NUMERIC" LC_TIME="$LC_TIME" LC_COLLATE="$LC_COLLATE" LC_MONETARY="$LC_MONETARY" LC_MESSAGES="$LC_MESSAGES" LC_PAPER="$LC_PAPER" LC_NAME="$LC_NAME" LC_ADDRESS="$LC_ADDRESS" LC_TELEPHONE="$LC_TELEPHONE" LC_MEASUREMENT="$LC_MEASUREMENT" LC_IDENTIFICATION="$LC_IDENTIFICATION" LC_ALL="$LC_ALL" PATH="$PATH" TERM="$TERM" "$SERVICEDIR/$SERVICE" status
                fi
                ;;
            esac
          done
          exit 0

さいごに

困ったらまず公式を当たろう。

Pocket

CONTACT

お問い合わせ・ご依頼はこちらから