web-dev-qa-db-ja.com

致命的なエラー:特権テーブルを開いてロックできません: 'ユーザー'のテーブルストレージエンジンにこのオプションがありません

このエラーメッセージは、Dockerイメージでubuntu 16.04と最新のmysql 5.7.19-0ubuntu0.16.04.1を使用すると表示されます。

これを修正するために何ができるでしょうか?

エラーを再現するには

  1. Dockerfileを取得:

    FROM ubuntu:16.04
    
    RUN apt update
    RUN DEBIAN_FRONTEND=noninteractive apt install -y mysql-server
    

    (また利用可能 ここ

  2. ビルドして実行:

    docker build -t mysqlfail . 
    docker run -it mysqlfail tail -1 /var/log/mysql/error.log
    

    次のエラーログが表示されます。

    2017-08-26T11:48:45.398445Z 1 [警告] root @ localhostは空のパスワードで作成されます! --initialize-insecureオプションをオフにすることを検討してください。

    これはまさに私たちが欲しかったものでした:まだrootパスワードが設定されていないmysql。

  3. 過去(ubuntu 14.04/mysql 5.5)でservice mysql startは可能でした。これを試しても失敗する

    docker run -it mysqlfail service mysql start
     * Starting MySQL database server mysqld    
      No directory, logging in with HOME=/  
                                                                            [fail]
    

    および/var/log/mysql/error.logには次の行が含まれています:

    2017-08-26T11:59:57.680618Z 0 [エラー]致命的エラー:特権テーブルを開いてロックできません: 'ユーザー'のテーブルストレージエンジンにこのオプションがありません


ビルドログ(完全な Dockerfile の場合)

Sending build context to Docker daemon   2.56kB
Step 1/4 : FROM ubuntu:16.04
 ---> ebcd9d4fca80
...
Step 4/4 : RUN service mysql start
 ---> Running in 5b899739d90d
 * Starting MySQL database server mysqld
   ...fail!
The command '/bin/sh -c service mysql start' returned a non-zero code: 1

奇妙な続き

私の回答の試み で概説されている実験の後、私はシェルスクリプトを作成しました

select count(*)

mysqlスペースの各テーブルに対して3回続けてクエリを実行します(実験により、一部のテーブルではクエリが正確に2回失敗することがわかっているためです: )。

その後、

mysql_upgrade   

そしてその

service mysql restart

試されます。 Dockerfileでは、スクリプトは

COPY mysqltest.sh .

このスクリプトを使用したトライアルは、奇妙でクレイジーな結果をもたらします。

  1. のために - -(Docker environment まだ起動に失敗します

    [エラー]致命的なエラー:権限テーブルを開いてロックできません: 'ユーザー'のテーブルストレージエンジンにこのオプションがありません

  2. スクリプトを実行する

    sh mysqltest.sh root
    

    の中に - docker environment

    2017-08-27T09:12:47.021528Z 12 [エラー]/usr/sbin/mysqld:テーブル './mysql/db'はクラッシュしているとマークされており、修復する必要があります
    2017-08-27T09:12:47.050141Z 12 [エラー]テーブルを修復できませんでした:mysql.db
    2017-08-27T09:12:47.055925Z 13 [エラー]/usr/sbin/mysqld:テーブル './mysql/db'はクラッシュしているとマークされており、修復する必要があります
    2017-08-27T09:12:47.407700Z 54 [エラー]/usr/sbin/mysqld:テーブル './mysql/proc'はクラッシュしているとマークされており、修復する必要があります
    2017-08-27T09:12:47.433516Z 54 [エラー]テーブルを修復できませんでした:mysql.proc
    2017-08-27T09:12:47.440695Z 55 [エラー]/usr/sbin/mysqld:テーブル './mysql/proc'はクラッシュしているとマークされており、修復する必要があります
    2017-08-27T09:12:47.769485Z 81 [エラー]/usr/sbin/mysqld:テーブル './mysql/tables_priv'はクラッシュしているとマークされており、修復する必要があります
    2017-08-27T09:12:47.792061Z 81 [エラー]テーブルを修復できませんでした:mysql.tables_priv
    2017-08-27T09:12:47.798472Z 82 [エラー]/usr/sbin/mysqld:テーブル './mysql/tables_priv'はクラッシュしているとマークされており、修復する必要があります
    2017-08-27T09:12:47.893741Z 99 [エラー]/usr/sbin/mysqld:テーブル './mysql/user'はクラッシュしているとマークされており、修復する必要があります
    2017-08-27T09:12:47.914288Z 99 [エラー]テーブルを修復できませんでした:mysql.user
    2017-08-27T09:12:47.920459Z 100 [エラー]/usr/sbin/mysqld:テーブル './mysql/user'はクラッシュしているとマークされており、修復する必要があります

この奇妙な行動を引き起こすためにここで何が起こっているのですか?

15
Wolfgang Fahl

今日、同じ問題に遭遇しました。ユニットテスト用のdockerビルド中にMySQLサービスを実行していますが、MariaDBからMySQL CE 5.7.19にアップグレードするとビルドが壊れました。私にとって問題を解決したのはchown -R mysql:mysql /var/lib/mysql /var/run/mysqld mysqlサービスを開始する前。

したがって、私のDockerfileは次のようになります。

RUN chown -R mysql:mysql /var/lib/mysql /var/run/mysqld && \
    service mysql start && \
    mvn -q verify site

お役に立てれば。

32
Tibor Gyuris

回避策

_find /var/lib/mysql -type f -exec touch {} \; && service mysql start
_

問題の説明

aalexgabi で述べられている根本的な問題は OverlayFSのPOSIX標準の実装 によるものです。

open(2):OverlayFSはPOSIX標準のサブセットのみを実装します。これにより、特定のOverlayFS操作がPOSIX標準に違反する可能性があります。そのような操作の1つがコピー操作です。アプリケーションがfd1=open("foo", O_RDONLY)を呼び出し、次にfd2=open("foo", O_RDWR)を呼び出すとします。この場合、アプリケーションはfd1とfd2が同じファイルを参照することを想定しています。ただし、_open(2_)への2回目の呼び出しの後に行われるコピーアップ操作のため、記述子は異なるファイルを参照します。 fd1は引き続きイメージ内のファイル(lowerdir)を参照し、fd2はコンテナー内のファイル(upperdir)を参照します。これの回避策は、コピー操作が発生する原因となるファイルに触れることです。読み取り専用または読み取り/書き込みアクセスモードに関係なく、後続のすべてのopen(2)操作は、コンテナー(upperdir)内のファイルを参照します。

参照:

9
Murmel

Mac用Dockerのデフォルトであるoverlayfs(overlay2)のエラーを確認しました。 mysqlでイメージを作成した後、イメージでmysqlを開始すると、エラーが発生します。

2017-11-15T06:44:22.141481Z 0 [ERROR] Fatal error: Can't open and lock privilege tables: Table storage engine for 'user' doesn't have this option

「aufs」に切り替えると問題が解決しました。 (Docker for Macでは、「設定...」メニューから「デーモン」タブを選択し、「詳細」タブを選択することで、「daemon.json」を編集できます。

/etc/docker/daemon.json:

{
  "storage-driver" : "aufs",
  "debug" : true,
  "experimental" : true
}

参照:

https://github.com/moby/moby/issues/355

https://qiita.com/Hige-Moja/items/7b1208f16997e2aa9028

8
Tsuneo Yoshioka

ここでは、まだここでは見られない答えを示します。

これをdockerfileに追加します:VOLUME /var/lib/mysql

これにより、/ var/lib/mysqlフォルダーがoverlayFSではなくネイティブのファイルシステムを使用するようになります。これはこの問題を回避します。

これは、公式のmysql dockerイメージがこれに対処するために使用するソリューションです :https://github.com/docker-library/mysql/blob/9d1f62552b5dcf25d3102f14eb82b579ce9f4a26/5.7/Dockerfile

2
Paul Dejean

これはまだ解決策にはならないかもしれません。とにかく、「適切な」答えを他の人に示すかもしれません

以下のdocker bashセッションログは、奇妙なエラーにつながり、最終的にはDocker環境でmysqlデーモンを適切に起動できる一連のステップを示しています。

このセッションでデーモンを起動しようとすると、2回失敗します。1回目はmysql.userテーブルが原因で、もう1回はmysql.dbテーブルが原因です。 --skip-grant-tablesを指定してmysqlデーモンを実行すると機能しますが、これらのテーブルの単純なselect * fromコマンドにも問題があります。

奇妙なことに2つの単純なクエリを実行します。

select Host,user from mysql.user;
select user from mysql.db

そして、デーモンを強制終了して適切に起動します

service mysql start

動作するようです。これを回避策として自動化しようと思います。私はまだ問題の「適切な」解決策と、この奇妙な動作の理由が何であるかについての手掛かりを求めています。

Dockerfile

#*********************************************************************
#
# Dockerfile for https://serverfault.com/questions/870568/2017-08-26t113924-509100z-0-error-fatal-error-cant-open-and-lock-privilege
#
#*********************************************************************

# Ubuntu image
FROM ubuntu:16.04

# 
# Maintained by Wolfgang Fahl / BITPlan GmbH http://www.bitplan.com
# 
MAINTAINER Wolfgang Fahl [email protected]

RUN \
 export DEBIAN_FRONTEND=noninteractive;apt-get update -y && apt-get install -y \
        vim \
    mysql-server 

RUN mkdir /var/run/mysqld;chown mysql /var/run/mysqld
WORKDIR /var/log/mysql

ビルドログ

docker build .

Sending build context to Docker daemon  8.704kB
Step 1/5 : FROM ubuntu:16.04
 ---> ebcd9d4fca80
Step 2/5 : MAINTAINER Wolfgang Fahl [email protected]
 ---> Using cache
 ---> b84df9d5de50
Step 3/5 : RUN export DEBIAN_FRONTEND=noninteractive;apt-get update -y && apt-get install -y         vim    mysql-server
 ---> Using cache
 ---> b51bd2bb172c
Step 4/5 : RUN mkdir /var/run/mysqld;chown mysql /var/run/mysqld
 ---> Using cache
 ---> 5b7455fede6b
Step 5/5 : WORKDIR /var/log/mysql
 ---> c4c333e811ab
Removing intermediate container cfc49e460c96
Successfully built c4c333e811ab

bashセッションログ

docker run -it c4c333e811ab

root@607fa9fe8d98:/var/log/mysql# service mysql start
 * Starting MySQL database server mysqld                                                             No directory, logging in with HOME=/
                                                                                              [fail]
root@607fa9fe8d98:/var/log/mysql# grep ERROR error.log 
2017-08-27T07:56:21.377919Z 0 [ERROR] Fatal error: Can't open and lock privilege tables: Table storage engine for 'user' doesn't have this option
2017-08-27T07:56:21.378149Z 0 [ERROR] Aborting
mysqld_safe --skip-grant-tables&sleep 2;mysql -u root -p=""
select * from mysql.user;
ERROR 1031 (HY000): Table storage engine for 'user' doesn't have this option
select Host,user from mysql.user;
+-----------+------------------+
| Host      | user             |
+-----------+------------------+
| localhost | debian-sys-maint |
| localhost | mysql.session    |
| localhost | mysql.sys        |
| localhost | root             |
+-----------+------------------+
4 rows in set (0.00 sec)
show variables like "%locking%";
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| skip_external_locking | ON    |
+-----------------------+-------+
1 row in set (0.01 sec)
root@607fa9fe8d98:/var/log/mysql# pgrep -fla mysql
721 /bin/sh /usr/bin/mysqld_safe --skip-grant-tables
1083 /usr/sbin/mysqld --basedir=/usr --datadir=/var/lib/mysql --plugin-dir=/usr/lib/mysql/plugin --user=mysql --skip-grant-tables --log-error=/var/log/mysql/error.log --pid-file=/var/run/mysqld/mysqld.pid --socket=/var/run/mysqld/mysqld.sock --port=3306 --log-syslog=1 --log-syslog-facility=daemon --log-syslog-tag=
pkill -f mysql
echo "" > error.log
service mysql start
 * Starting MySQL database server mysqld                                                             No directory, logging in with HOME=/.      [fail]
grep ERROR error.log 
2017-08-27T08:03:12.918047Z 0 [ERROR] Fatal error: Can't open and lock privilege tables: Table storage engine for 'db' doesn't have this option
2017-08-27T08:03:12.918278Z 0 [ERROR] Aborting
mysqld_safe --skip-grant-tables&sleep 2;mysql -u root -p=""
select * from mysql.db;
ERROR 1031 (HY000): Table storage engine for 'db' doesn't have this option
select user from mysql.db;
+---------------+
| user          |
+---------------+
| mysql.session |
| mysql.sys     |
+---------------+
2 rows in set (0.00 sec)
echo "" > error.log
root@607fa9fe8d98:/var/log/mysql# service mysql start
 * Starting MySQL database server mysqld      [ OK ]
1
Wolfgang Fahl