XAMPPのMariaDBが起動しなくなったとき その1

カテゴリー
Windows Wordpress Xampp セキュリティ データベース 開発環境

発生内容

検証のため用意していた、Windows10下の XAMPP のお手軽環境の MariaDB 10 が壊れて起動しなくなった。

20:24:44  [mysql]   Error: MySQL shutdown unexpectedly.
20:24:44  [mysql]   This may be due to a blocked port, missing dependencies,
20:24:44  [mysql]   improper privileges, a crash, or a shutdown by another method.
20:24:44  [mysql]   Press the Logs button to view error logs and check
20:24:44  [mysql]   the Windows Event Viewer for more clues
20:24:44  [mysql]   If you need more help, copy and post this
20:24:44  [mysql]   entire log window on the forums

調査

  • サーバーのバージョンは10.4.11-MariaDB - mariadb.org binary distribution
  • コマンドプロンプトでnetstatを叩いてもport: 3306は使用されていない。
  • 下記はwindowsのイベントビューアのWindoiwsログ->Applicationから。
ソース "MariaDB" からのイベント ID 100 の説明が見つかりません。このイベントを発生させるコンポーネントがローカル コンピューターにインストールされていないか、インストールが壊れています。ローカル コンピューターにコンポーネントをインストールするか、コンポーネントを修復してください。
イベントが別のコンピューターから発生している場合、イベントと共に表示情報を保存する必要があります。
イベントには次の情報が含まれています:
Couldn't repair table: mysql.global_priv

※mysql.global_privテーブルは、2019年6月18日 mysql.user から変更されたユーザー認証テーブルらしい。
https://mariadb.com/ja/resources/blog/mariadb-10-4-global_priv-table/

原因

ユーザのパスワードを変更し、MariaDBのプロセスをXAMPPコントロールパネルで停止せず、なんらかの原因で強制的にkillされると発生するらしい?
(10.3で確認されたようだ。ただし、Couldn’t repair table: mysql.user として。)
今回、自分の環境で発生した原因はWindows Updateによる自動的な再起動による強制終了だった。

対応

下準備

  1. c:\xampp\mysql\bin\my.ini を開く
  2. [mysqld] ラベルの下に skip-grant-tablesを追記
    (これで起動するようになるためバックアップが取れる。ただし、パスワード無しで通ったりするのでセキュリティ的に良くない。後で消すこと。
  3. phpMyAdminを起動し、左のデータベース一覧から mysql データベースを選択
  4. 右にテーブル一覧が表示されるので global_prev (10.3ならuser)を選択
  5. エラーメッセージが出ることを確認
  6. チェックボックスにチェックを付けて、下部のセレクトから解析するなり修復するなり

…で、直るらしいのだが、自分の場合は修復しても駄目で、
DROP TABLEしてバックアップからコピーして復旧しても「各データベースと紐づく特権情報が無い」ため、
phpMyAdmin上で「ユーザー」の項が表示されない事態だった。

作戦A

よくわからない場合は、ここまででテスト環境やサービスと紐づくデータベースをバックアップし、
再インストールをするのが吉。

作戦B

緊急の場合は下記コマンドのようにして処理の必要なデータベースごとにユーザーを作り、権限を振りなおす。ただし、phpMyAdminのホームで「特権」の項が表示されないとか、チェックサムが依然おかしいとか、様々な弊害があった。
GRANT select,update,delete,insertの部分はGRANT ALL PRIVILEGESとすると全部乗せに。

GRANT select,update,delete,insert ON データベース名.* TO ユーザー名@'127.0.0.1' IDENTIFIED BY 'パスワード'
GRANT select,update,delete,insert ON データベース名.* TO ユーザー名@'::1' IDENTIFIED BY 'パスワード'
GRANT select,update,delete,insert ON データベース名.* TO ユーザー名@'localhost' IDENTIFIED BY 'パスワード'

参考資料