systemd-tmpfiles-setup.service が LDAP を使用できなくて /var/run/mysqld が作成されなかった


目次

こんにちは。

ピクトリンク事業部開発部インフラ課の粟田です。

CentOS7で表題の件に引掛ってmysqlが自動起動できない問題にあたったので解決方法のメモを記述します。

問題

まぁ、表題の通りなんですが、OSを再起動しても /var/run/mysqld ディレクトリが作成されていないので、mysql が /var/run/mysqld/mysqld.pid ファイル作成エラーで起動できませんでした。

暫定として、

# mkdir /var/run/mysqld
# chown -R mysql:mysql /var/run/mysqld

していたのを根本的に修正したいな、と調査しました。

調査

% systemctl status mysqld
● mysqld.service - MySQL Server
   Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled; vendor preset: disabled)
   Active: failed (Result: start-limit) since 木 2019-04-18 14:07:26 JST; 11s ago
     Docs: man:mysqld(8)
           http://dev.mysql.com/doc/refman/en/using-systemd.html
  Process: 1194 ExecStart=/usr/sbin/mysqld --daemonize --pid-file=/var/run/mysqld/mysqld.pid $MYSQLD_OPTS (code=exited, status=1/FAILURE)
  Process: 1070 ExecStartPre=/usr/bin/mysqld_pre_systemd (code=exited, status=0/SUCCESS)
% sudo journalctl -u mysqld
-snip-
4月 18 14:26:59 server mysqld[3604]: 2019-04-18T05:26:59.222329Z 0 [ERROR] Can't start server: can't check PID filepath: No such file or directory
-snip-

ここでWebサイトを調査してみると、

systemdでサービスを動かす際、/var/runにディレクトリを作った時の落とし穴と対策

お前らもさっさとハマって泣くべきCentOS7の落とし穴4つ

の様な記事が見つかったので対応できそうかなと進めてみました。

検証

/etc/tmpfiles.d にファイルを作成するとディレクトリが作れる、という事だったので作成して再起動を実施してみました。

/etc/tmpfiles.d/mysql.conf その1

% echo "d /var/run/mysqld 0755 mysql mysql  -" | sudo tee /etc/tmpfiles.d/mysql.conf
% sudo reboot

再起動してからディレクトリ確認

% ls -l /var/run/ | grep mysqld

できてないじゃないですか……

/etc/tmpfiles.d のファイルを参照するプロセスを確認してみると、 systemd-tmpfiles ってのが見つかりました。

引数見て実行してみると、

% systemd-tmpfiles --create
% ls -l /var/run/ | grep mysqld
drwxr-xr-x  2 mysql  mysql            40  4月 18 14:21 mysqld

できてる……

systemd-tmpfiles がどこから呼ばれているのかを調べてみると、/usr/lib/systemd/system/systemd-tmpfiles-setup.service を見つけました。

早速ステータスを確認してみます。

% systemctl status systemd-tmpfiles-setup
● systemd-tmpfiles-setup.service - Create Volatile Files and Directories
   Loaded: loaded (/usr/lib/systemd/system/systemd-tmpfiles-setup.service; static; vendor preset: disabled)
   Active: failed (Result: exit-code) since 木 2019-04-18 14:07:17 JST; 24min ago
     Docs: man:tmpfiles.d(5)
           man:systemd-tmpfiles(8)
  Process: 596 ExecStart=/usr/bin/systemd-tmpfiles --create --remove --boot --exclude-prefix=/dev (code=exited, status=1/FAILURE)
 Main PID: 596 (code=exited, status=1/FAILURE)

エラーですやん。

さらに、このプログラムを調べてみると、/usr/lib/tmpfiles.d を参照する様なので見てみる。 デフォルトのmysql.conf

% ls /usr/lib/tmpfiles.d 
abrt.conf   initscripts.conf  libstoragemgmt.conf  mysql.conf          pam.conf      rpm.conf             sudo.conf             systemd.conf  var.conf
etc.conf    legacy.conf       lvm2.conf            nscd.conf           python.conf   sap.conf             svnserve.conf         tmp.conf      x11.conf
httpd.conf  libselinux.conf   mdadm.conf           nss-pam-ldapd.conf  rpcbind.conf  selinux-policy.conf  systemd-nologin.conf  tuned.conf
% cat /usr/lib/tmpfiles.d/mysql.conf 
-snip-
d /var/run/mysqld 0755 mysql mysql  -

あれ、既にある……

エラーを調査するべく sudo journalctl -u systemd-tmpfiles-setup.service を実行。

さーせん。ログ取るの忘れました…
mysql ユーザが unknown だという事だけは覚えてるんですけど。

mysql ユーザが LDAP に定義されていて、ネットワーク起動前に systemd-tmpfiles-setup が実行されるから起動できないんだろうと推測しました。

そこで、mysql ユーザでないユーザで /var/run/mysqld を作ってみます。

% echo "d /var/run/mysqld 0755 root root -" | sudo tee /etc/tmpfiles.d/mysql.conf
% sudo reboot

再起動してから

% ls -l /var/run/ | grep mysqld 
drwxr-xr-x 2 root root 40 4月 18 14:29 mysqld

ちゃんとできてる!

ここまでで根本解決として以下のものを想定しました。

  1. /var/run/mysql を root で作って起動時に mysql に uid/gid を設定する
  2. mysql 起動直前に /usr/bin/systemd-tmpfiles –create を実行する
  3. pid ファイルの出力位置を変更する
  4. ホストのローカルに LDAP に定義してるuid/gid で mysql ユーザを作成してしまう

実際には1、2、3どの方法でも解決するのは確認しました。

4は未検証です。

LDAP 認証できない様にサーバ起動してユーザ作成するのとかが面倒だったので……

解決

先に提案した中で、1番を選択する事にしました。

理由として、

  • 2番を選択したら systemctl status systemd-tmpfiles-setup で常にエラーになってるのがなんかイヤ
    • プロセス起動のたびに create 呼ばれるのは chown 呼ぶより気色悪いし
  • 3番は /etc/my.cnf を変更したのに pid ファイルの出力先が変らない、と大騒ぎする人がいたのでいじりたくないな
  • どうせどれを選択しても /usr/lib/systemd/system/mysqld.service は編集しないといけないし(4は除く)

を思うと他の人に手順を説明しやすいのは1番かな、と。

% echo "d /var/run/mysqld 0755 root root -" | sudo tee /etc/tmpfiles.d/mysql.conf
% sudo vim /usr/lib/systemd/system/mysqld.service
# Needed to create system tables
ExecStartPre=/usr/bin/mysqld_pre_systemd
の直下に追記
↓
# Needed to create system tables
ExecStartPre=/usr/bin/mysqld_pre_systemd
ExecStartPre=/usr/bin/chown -R mysql:mysql /var/run/mysqld

これで mysql が自動起動できる様になりました。

あとがき

systemd-tmpfiles-setup と LDAP 相性よろしくないのかも……

他にも記事をいくつか見つけたし。