致命错误:无法打开和锁定权限表:“用户”的表存储引擎没有此选项

Wol*_*ahl 20 mysql docker

当我在 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
    
    Run Code Online (Sandbox Code Playgroud)

    (也可在此处获得

  2. 构建并运行:

    docker build -t mysqlfail . 
    docker run -it mysqlfail tail -1 /var/log/mysql/error.log
    
    Run Code Online (Sandbox Code Playgroud)

    会显示以下错误日志:

    2017-08-26T11:48:45.398445Z 1 [警告] root@localhost 是用空密码创建的!请考虑关闭 --initialize-insecure 选项。

    这正是我们想要的:一个还没有设置 root 密码的 mysql。

  3. 在过去(ubuntu 14.04 / mysql 5.5)aservice mysql start是可能的。现在如果你尝试这个它会失败

    docker run -it mysqlfail service mysql start
     * Starting MySQL database server mysqld    
      No directory, logging in with HOME=/  
                                                                            [fail]
    
    Run Code Online (Sandbox Code Playgroud)

    /var/log/mysql/error.log包含一行:

    2017-08-26T11:59:57.680618Z 0 [ERROR] 致命错误:无法打开和锁定权限表:“用户”的表存储引擎没有此选项


构建日志(完整的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
Run Code Online (Sandbox Code Playgroud)

奇怪的延续

我的回答尝试中概述的实验之后,我创建了一个 shell 脚本,它执行

select count(*)
Run Code Online (Sandbox Code Playgroud)

在 mysql 空间中的每个表上连续查询 3 次(因为实验表明,在某些表上,查询将恰好失败两次 :-()。

然后一个

mysql_upgrade   
Run Code Online (Sandbox Code Playgroud)

service mysql restart
Run Code Online (Sandbox Code Playgroud)

被尝试。在Dockerfile脚本中可以通过

COPY mysqltest.sh .
Run Code Online (Sandbox Code Playgroud)

使用此脚本的试验给出了奇怪/疯狂的结果。

  1. 对于Docker environment开始仍然失败

    [ERROR] 致命错误:无法打开和锁定权限表:“用户”的表存储引擎没有此选项

  2. 运行脚本

    sh mysqltest.sh root
    
    Run Code Online (Sandbox Code Playgroud)

    docker environment导致

    2017-08-27T09:12:47.021528Z 12 [ERROR] /usr/sbin/mysqld: Table './mysql/db' 被标记为崩溃,应该修复
    2017-08-27T09:12:47.050141Z 12 [ERROR] ] 无法修复表:mysql.db
    2017-08-27T09:12:47.055925Z 13 [ERROR] /usr/sbin/mysqld:表'./mysql/db'被标记为崩溃,应该修复
    2017-08 -27T09:12:47.407700Z 54 [ERROR] /usr/sbin/mysqld: Table './mysql/proc' 被标记为崩溃,应该修复
    2017-08-27T09:12:47.433516Z 54 [ERROR] 无法' t 修复表:mysql.proc
    2017-08-27T09:12:47.440695Z 55 [ERROR] /usr/sbin/mysqld:表'./mysql/proc'被标记为崩溃,应该修复 2017-08-27T09: 12:47.792061Z 81 [错误] 无法修复表:mysql.tables_priv
    2017-08-27T09: 12:47.769485Z 81 [错误] /usr/sbin/mysqld:表'./mysql/tables_priv'被标记为崩溃,应该修复

    2017-08-27T09:12:47.798472Z 82 [错误] /usr/sbin/mysqld:表'./ table_priv' 标记为崩溃,应修复
    2017-08-27T09:12:47.893741Z 99 [ERROR] /usr/sbin/mysqld: Table './mysql/user' 标记为崩溃,应修复
    2017-08 -27T09:12:47.914288Z 99 [ERROR] 无法修复表:mysql.user
    2017-08-27T09:12:47.920459Z 100 [ERROR] /usr/sbin/mysqld: Table './mysql/user' is标记为崩溃,应该修复

这里发生了什么导致这种奇怪的行为?

小智 34

今天遇到同样的问题。我在 docker build 期间运行 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
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助。

  • 同样的问题在这里。我有一个两阶段构建,“父”Dockerfile 已经运行了这个 `chmod` 命令。当我在远程 Ubuntu 服务器上运行它时构建成功,但当我在本地机器 (OS X) 上运行它时失败。将 `chmod` 命令添加到子 Dockerfile 修复了该问题。*奇怪的*。 (2认同)
  • 谢谢!我知道外面的其他人必须有与我自己类似的用例。 (2认同)
  • @senderle 也刚刚找到了这个线程。“一次构建,随处部署”他们说 (2认同)

Mur*_*mel 11

解决方法

find /var/lib/mysql -type f -exec touch {} \; && service mysql start
Run Code Online (Sandbox Code Playgroud)

问题描述

aalexgabi所述的潜在问题是由于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)。

参考:

  • 诚实地?我也不!我的意思是这必须影响很多应用程序,因为它确实是一个基本的文件操作。当然,问题只发生在某些条件下,但它们并没有那么远...... (2认同)

Tsu*_*oka 8

我确认了overlayfs(overlay2)上的错误,这是Docker for Mac的默认设置。使用 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
Run Code Online (Sandbox Code Playgroud)

切换到“aufs”解决了这个问题。(在 Docker for Mac 上,“daemon.json”可以通过选择“Preferences...”菜单,然后选择“Daemon”选项卡,然后选择“Advanced”选项卡来编辑。)

/etc/docker/daemon.json :

{
  "storage-driver" : "aufs",
  "debug" : true,
  "experimental" : true
}
Run Code Online (Sandbox Code Playgroud)

参考:

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

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