MySQL 5.7のmysqld --initializeと鶏卵問題

MySQLのデータディレクトリの初期化にはこれまで mysql_install_db が使われてきましたが、MySQL 5.7からは mysqld --initialize を使うことが推奨されています。

mysqld --initialize は datadir 配下にファイルやサブディレクトリがあるとエラー終了します。

# mysqld --initialize --user=mysql
2016-10-04T11:39:01.313174Z 0 [ERROR] --initialize specified but the data directory has files in it. Aborting.
2016-10-04T11:39:01.313222Z 0 [ERROR] Aborting

なので datadir をスッカラカンにして再度実行してみます。my.cnf はこんな内容で、datadir の下に tmpdir、InnoDBのデータとログのディレクトリがある構成です。

datadir  = /data/mysql
tmpdir   = /data/mysql/tmp
innodb_data_home_dir            = ibdata
innodb_log_group_home_dir       = iblog
# rm -fr /data/mysql/*
# mysqld --initialize --user=mysql
# echo $?
1
# cat /data/mysql/mysqld.err
mysqld: Can't create/write to file '/data/mysql/tmp/ibSY07SU' (Errcode: 2 - No such file or directory)
2016-10-04T11:41:18.876953Z 0 [ERROR] InnoDB: Unable to create temporary file; errno: 2
2016-10-04T11:41:18.876965Z 0 [ERROR] InnoDB: Plugin initialization aborted with error Generic error
2016-10-04T11:41:18.876971Z 0 [ERROR] Plugin 'InnoDB' init function returned error.
2016-10-04T11:41:18.876975Z 0 [ERROR] Plugin 'InnoDB' registration as a STORAGE ENGINE failed.
2016-10-04T11:41:18.876980Z 0 [ERROR] Failed to initialize plugins.
2016-10-04T11:41:18.876983Z 0 [ERROR] Aborting

/data/mysql/tmp が存在しないので /data/mysql/tmp/ibSY07SU が作れずエラー終了しています。

InnoDBのデータ、ログディレクトリについても同様で、自動ではサブディレクトリを作ってくれません。

[ERROR] InnoDB: Operating system error number 2 in a file operation.
[ERROR] InnoDB: The error means the system cannot find the path specified.
[ERROR] InnoDB: If you are installing InnoDB, remember that you must create directories yourself, InnoDB does not create them.
[ERROR] InnoDB: File ibdata/ibdata1: 'create' returned OS error 71. Cannot continue operation
[ERROR] InnoDB: Cannot continue operation.
[ERROR] InnoDB: Operating system error number 2 in a file operation.
[ERROR] InnoDB: The error means the system cannot find the path specified.
[ERROR] InnoDB: If you are installing InnoDB, remember that you must create directories yourself, InnoDB does not create them.
[ERROR] InnoDB: File iblog/ib_logfile101: 'create' returned OS error 71.
[ERROR] InnoDB: Cannot create iblog/ib_logfile101
[ERROR] InnoDB: InnoDB Database creation was aborted with error Generic error. You may need to delete the ibdata1 file before trying to start up again.
[ERROR] Plugin 'InnoDB' init function returned error.
[ERROR] Plugin 'InnoDB' registration as a STORAGE ENGINE failed.
[ERROR] Failed to initialize plugins.
[ERROR] Aborting


というわけで、初期化にはサブディレクトリが必要なわけですが、サブディレクトリがあると mysqld --initialize はエラー終了します。

_人人人人人人人人人人人人人人人人人人_
> どうすりゃいいねん!!!!!!! <
 ̄Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y ̄



途方に暮れそうになりましたが、ドキュメントにちゃんと書いてありました。

As of MySQL 5.7.11, an existing data directory is permitted to be nonempty if every entry either has a name that begins with a period (.) or is named using an --ignore-db-dir option.

https://dev.mysql.com/doc/refman/5.7/en/data-directory-initialization-mysqld.html

というわけで、予め必要なサブディレクトリを作っておいて、必要なだけ --ignore-db-dir で繰り返しそれを指定すればOKです。

# rm -fr /data/mysql/*
# install -d -o mysql -g mysql -m 750 /data/mysql/{tmp,ibdata,iblog}
# mysqld --initialize  --user=mysql --ignore-db-dir=tmp --ignore-db-dir=ibdata --ignore-db-dir=iblog
# echo $?
0

追記 2023-03-06

--ignore-db-dir は 5.7 で deprecated だったのですが、8.0 で廃止されて使えなくなりました。

8.0 ではどうすればいいのでしょうか。。。