このエラーメッセージは、Dockerイメージでubuntu 16.04と最新のmysql 5.7.19-0ubuntu0.16.04.1を使用すると表示されます。
これを修正するために何ができるでしょうか?
エラーを再現するには
Dockerfile
を取得:
FROM ubuntu:16.04
RUN apt update
RUN DEBIAN_FRONTEND=noninteractive apt install -y mysql-server
(また利用可能 ここ )
ビルドして実行:
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。
過去(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 .
このスクリプトを使用したトライアルは、奇妙でクレイジーな結果をもたらします。
のために - -(Docker environment
まだ起動に失敗します
[エラー]致命的なエラー:権限テーブルを開いてロックできません: 'ユーザー'のテーブルストレージエンジンにこのオプションがありません
スクリプトを実行する
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'はクラッシュしているとマークされており、修復する必要があります
この奇妙な行動を引き起こすためにここで何が起こっているのですか?
今日、同じ問題に遭遇しました。ユニットテスト用の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
お役に立てれば。
回避策
_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)内のファイルを参照します。
参照:
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
}
参照:
ここでは、まだここでは見られない答えを示します。
これをdockerfileに追加します:VOLUME /var/lib/mysql
これにより、/ var/lib/mysqlフォルダーがoverlayFSではなくネイティブのファイルシステムを使用するようになります。これはこの問題を回避します。
これは、公式のmysql dockerイメージがこれに対処するために使用するソリューションです :https://github.com/docker-library/mysql/blob/9d1f62552b5dcf25d3102f14eb82b579ce9f4a26/5.7/Dockerfile
これはまだ解決策にはならないかもしれません。とにかく、「適切な」答えを他の人に示すかもしれません
以下の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 ]