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 ではどうすればいいのでしょうか。。。