DebianのMariaDBのパスワードレス設定
少し古いMariaDB(10.3)の起動時に '--basedir' option is always ignored というメッセージを含んだエラーがでていたので原因の追及と対処ををしました。
その際に気づいたのですが、MariaDBでは mysql_upgrade(mariadb_upgrade) などで用いられるパスワードレスでの運用方法がバージョン10.4.3を境に変更されたようです。
具体的には debian.cnf 拡張設定ファイルからUNIXソケット認証に置き換えられました。
ここでは、事の発端となった'--basedir' option is always ignored メッセージ消し方から、debian.cnfファイル、UNIXソケット認証、検証時に発生した「 InnoDB: Missing FILE_CHECKPOINT 」への対処法について書いています。
'--basedir' option is always ignored
「 '--basedir' option is always ignored 」このメッセージは近年のMariaDBを稼働させているのなら、そのままでも運用上問題ないと思われます。
MariaDBのバージョンをアップグレードすると、おそらく自然に消えます。
それでも気になる人へメッセージの消し方を紹介します。
まず、このメッセージは mysql_upgrade によって出力されています。このコマンドオプションに --basedir というものがあり、メッセージはこの値が無視されているということを言っています。
mysql_upgrade --help で表示させてみますと、
mysql_upgrade --help
... -b, --basedir=name Not used by mysql_upgrade. Only for backward compatibility. ...
となっており、後方互換の為に有効になっているが利用しないオプションということです。
mysql_upgradeが実行される理由
mysql_upgrade はMariaDB(MySQL)がアップグレードされた後にスキーマ等を古いバージョンから新しいバージョンへアップグレードするためのコマンドです。
なので、バージョンアップをした場合にだけ実行が必要なのですが、ユーザービリティの為に起動時に常に実行されるように設定されています。
もう少し詳しく書くと、実際にはデータベース起動時に、--version-check オプション付きで mysql_upgrade が実行されます。これにより、アップデート後の初回の実行時にのみ(通常の) mysql_upgrade が実行される仕組みになっています。
mysql_upgradeの実行は /etc/mysql/debian-start にあるスクリプトファイルに記述されています。
debian-start
...
# ここで追加のソースが読み込まれます
source /usr/share/mysql/debian-start.inc.sh
...
# ここで変数にコマンドがセットされます
MYUPGRADE="/usr/bin/mysql_upgrade --defaults-extra-file=/etc/mysql/debian.cnf --version-check
...
# 先に読み込んだソースに下記の関数が記述されていて、それらを呼んでいます
# MYUPGRADE(mysql_upgrade)は upgrade_system_tables_if_necessary関数内で利用されています
trap "" SIGHUP
(
upgrade_system_tables_if_necessary;
check_root_accounts;
check_for_crashed_tables;
) >&2 &
# trap...部はハングアップを無視(ユーザーの接続切断等の対策)
# ( 部は別プロセス化し、標準出力を標準エラーにして、バックグランドで実行
...
またこのスクリプトは、 MariaDBのサービスファイルにある ExecStartPost=/etc/mysql/debian-start のエントリーで設定されているため毎回のMariaDBの起動前に実行されるようになっています。
--basedirオプション
ここまでで、mysql_upgradeが実行される仕組みはわかりましたが、debian-start スクリプトには --basedirオプションは付与されていません。
また、通常のシェルから mysql_upgrade を実行する場合は root のパスワードを求められるのにそれがないまま実行されています。
不足しているように思われたそれらは --default-extra-fileで指定されている、/etc/mysql/debian.cnf に記述されています。これは設定拡張ファイルで、clientやmysql_upgrade、mysql_adminなどのコマンド実行時に自動付与する拡張設定がセクションごと分けられて記述されています。
ここに次のように設定されているため、basedirオプションが付与されます。ですので、このbasedirの行をコメントアウトすればオプションは付与されなくなり、メッセージは表示されなくなります。
/etc/mysql/debian.cnf
# Automatically generated for Debian scripts. DO NOT TOUCH! [client] host = localhost user = root password = your-mariadb-root-password socket = /var/run/mysqld/mysqld.sock [mysql_upgrade] host = localhost user = root password = your-mariadb-root-password socket = /var/run/mysqld/mysqld.sock # コメントアウト # basedir = /usr
DO NOT TOUCHと書いてあるのは自動生成されるファイルからのようですが、たとえばMariaDBのrootユーザーのパスワードを変更してもこのファイルの値は同期しませんので、変更しないと仕方がないと思います。筆者の経験則ではこのファイルを書き換えて問題になったことはありませんが、気になるようなら同内容の別名のファイルを作ってスクリプトからの--defatus-extra-fileの指定も変えればいいと思います。
debian.cnfファイルの廃止
現行のMariaDBにおいてはdebian.cnfファイルは廃止されています。どこからが堺かは確認していませんが、後方互換の為、廃止の案内と共に、debian.cnfで構成されている状態になっているバージョンもあります(10.5.19では互換設定があることを確認しています)。
互換設定がない場合でも、debian.cnf ファイルがないだけで --defaults-extra-file オプション自体は残っていますので設定ファイルを自作して、MariaDB起動時のスクリプトを先に紹介したように修正すれば、同様の運用は可能です。
この時、--defaults-extra-fileオプションは -u や -pといった他のどのオプションよりも先に書く必要あがありますので注意してください。そうしないとオプションを認識できずに「 mysql: unknown variable 'defaults-extra-file... 」というエラーになります。
また、拡張設定ファイルにパスワードを記述する場合は、他のユーザーに利用されないよう読み取り権限も外しておく必要もあります。
次のようにファイルを設定した上で、それを利用すればシェルからパスワードレスの設定が可能です。
original-ext.cnf
[client] host = localhost user = user password = password
先のようなファイルを記述しておき、実行します。
$ mysqldump --defaults-extra-file=original-ext.cnf target_db>/home/user/dump.sql
debian.cnf ファイルがなぜ廃止されたかというと、バージョン10.4.3以降にデフォルト適用となったUnix Sokcet認証プラグインで代替できるからのようです。
Unixソケット認証
MariaDBのUnix Socket 認証プラグインを使うとMariaDBのシェルへのログイン時にOSの資格情報を利用します。この時接続はUnixソケット経由となります。
Unixソケットとはいわばアプリの通信用の窓口で、IPアドレスとは別のルート(ファイルシステム経由)でMariaDBに接続することができます。
Unixソケット認証プラグインがインストールしてある状態(10.4.3以降はデフォルト)なら、次のようにするだけで設定が可能です。
ユーザー名はOSのユーザー名、ホスト名は通常localhostになると思います。(ユーザー名@ホスト名で識別されるOSユーザーに対しての許可)
また先のdebian.cnfの代替として利用するならユーザー名の部分はrootとなると思います。
こうすることで、OSユーザーからMariaDBへ接続する際にユーザー名とパスワードが不要となります。
pオプションを付けた場合は、パスワード入力のプロンプトが表示されますが、何を入力しても接続できます。
また、通常UNIXソケットへ接続するには mysql コマンドに -S オプションを加え、ソケットファイルへのパスを渡しますが、事前にソケットファイル経由の認証を指定している為、それを明示する必要がありません。
# mysql # mysql -u root -p -S /var/run/mysqld/mysqld.sock などとSオプションをつけなくてもソケット接続になります。
UNIXソケット認証から元の認証に戻すには次のようにします。
MariaDB[]>ALTER USER 'root'@'localhost' IDENTIFIED VIA mysql_native_password; MariaDB[]>ALTER USER 'root'@'localhost' IDENTIFIED BY 'root-password';
逆にUNIXソケット認証を禁止したい場合は、50-server.cnfに次のように記述しておきます。
50-server.cnf
... unix_socket=off # オプションプレフィックスを使った指定 # disable_unix_socket
UNIXソケット認証はOSユーザーを使った認証なので、OSユーザーとは別のユーザーでの実行はできません。そのような場合は先のように拡張設定ファイルを用います。
クラッシュ
今回、検証をしていたら次のようなエラーがでてMariaDBが起動できなくなってしまいました。InnoDBがクラッシュし、リカバリー用のログファイルが正常機能しない場合におきるエラーのようです。
InnoDB: Missing FILE_CHECKPOINT at 862819 between the checkpoint 862819 and the end 862843. InnoDB: Plugin initialization aborted with error Generic error
これを解消するには、設定ファイルに innodb_force_recovery = xの設定値をいれます。xには 1~6の値が入ります。この時データベースに対してリカバリ以外の操作が起きないように注意してください。
MySQLのInnoDBのリカバリのページに詳細は書かれていますが、値が大きくなるにつれてデータの消失の可能性が高いものになります。
特に4以上データが永続的に失われる危険性が高いです。
起動できたらSELECTの操作でデータベースの値を取得するか(DROPやCREATE等のSQLはモードに設定する値によって使えない事があります)、mysqldumpですべてのデータを取得します。
データベースを初期化して、dumpデータを取り込めば
dumpの作業を終えたら、innodb_force_recovery = x の設定を消して dump データを取り込みます。
他の方法としては、ib_logファイルを削除して起動する方法もあります。この場合、クラッシュ時に書き出されていなかったデータは確実に失われます。
また、事前に設定されていれば定期的なdumpファイルとbinlogからデータベースを復旧させることもできます。