当我在 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
奇怪的延续
经过如下实验我的回答尝试,我创建了一个 shell 脚本,它执行
select count(*)
对mysql空间中的每个表连续进行三次查询(因为实验表明,在某些表上查询将会失败两次:-())。
然后
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'被标记为崩溃,应进行修复
这里发生了什么,导致了这种奇怪的行为?
答案1
今天遇到了同样的问题。我在 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
希望这可以帮助。
答案2
解决方法
find /var/lib/mysql -type f -exec touch {} \; && service mysql start
问题描述
潜在的问题如下亚历克斯加比是由于OverlayFS 的 POSIX 标准的实现:
open(2):OverlayFS 仅实现了 POSIX 标准的子集。这可能导致某些 OverlayFS 操作违反 POSIX 标准。其中一个操作是复制操作。假设您的应用程序调用
fd1=open("foo", O_RDONLY)
然后调用fd2=open("foo", O_RDWR)
。在这种情况下,您的应用程序希望 fd1 和 fd2 引用同一个文件。但是,由于在第二次调用之后发生了复制操作open(2
,因此描述符引用不同的文件。fd1 继续引用映像中的文件 (lowerdir),而 fd2 引用容器中的文件 (upperdir)。解决此问题的方法是触摸导致复制操作发生的文件。所有后续open(2)
操作,无论是只读还是读写访问模式,都将引用容器中的文件 (upperdir)。
参考:
答案3
我确认错误发生在 Docker for Mac 默认的 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
}
参考:
答案4
这可能还不是解决方案。无论如何,它可能会为其他人指明一个“正确”的答案
下面的 docker bash 会话日志展示了导致奇怪错误的一系列步骤,最终能够在 docker 环境中正确启动 mysql 守护进程。
在此会话中尝试启动守护进程失败两次 - 一次是由于 mysql.user 表,一次是由于 mysql.db 表。使用 --skip-grant-tables 运行 mysql 守护进程可以正常工作,但对这些表执行简单的 select * from 命令也会出现问题。
奇怪的是做了两个简单的查询:
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 ]