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


15

当我在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)a 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 .

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

  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 [错误]不能' t修复表: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/ table_priv'被标记为已崩溃,应该修复
    2017-08-27T09:12:47.893741Z 99 [ERROR] / 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
mysqld --skip-grant-tables --skip-networking似乎有效
Wolfgang Fahl

mkdir / var / run / mysqld;也可能需要mysql / var / run / mysqld。
Wolfgang Fahl

1
--skip-networking会禁用您可能希望与服务器建立的任何TCP / IP连接,因此有时这很不好。mariadb.com/kb/zh-CN/server-system-variables/#skip_networking
Darko Maksimovic

@DarkoMaksimovic可以将所有权设置的答案作为解决方案。
Wolfgang Fahl

我实际上已经尝试过了,在我的情况下它并没有改变任何东西(MacOS上的MySQL 5.7,Docker 2.1.0.5)。只有--skip-grant-tables有助于启动服务器,尽管该线程中有人抱怨进一步的选择,但我会在何时遇到。
Darko Maksimovic

Answers:


30

今天遇到了同样的问题。我在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
这里同样的问题。我有一个两阶段构建的工作,并且“父” Dockerfile已经运行了此chmod命令。在远程Ubuntu服务器上运行时,构建成功,但在本地计算机(OS X)上运行时,构建失败。将chmod命令添加到子Dockerfile中解决了该问题。奇怪的
senderle '17

2
谢谢!我知道外面的其他人必须有与我自己相似的用例。
threed

2
@senderle也刚刚找到了该线程。他们说
duhaime

9

解决方法

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

问题描述

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)。

参考:


1
这真是可怕的消息。我想知道为什么docker不固定。
Wolfgang Fahl

2
老实说 我也不!我的意思是这必须影响很多应用程序,因为它实际上是一个基本的文件操作。当然,仅在某些情况下才会出现问题,但是距离并不远……
Murmel

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

切换到“ aufs”解决了该问题。(在Mac的Docker上,可以通过选择“首选项...”菜单,选择“守护程序”选项卡,然后选择“高级”选项卡来编辑“ daemon.json”。)

/etc/docker/daemon.json:

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

参考:

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

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


1
这解决了我在Ubuntu 16:04中的问题。我之前已经在docker中配置了overlay2存储驱动程序。谢谢。
Havok

1
这阻止了
docker


1

这可能还不是解决方案。无论如何,它可能将他人指向“适当”的答案

下面的docker bash会话日志显示了一系列步骤,这些步骤导致奇怪的错误,最终使他们能够在docker环境中正确启动mysql守护程序。

在此会话中尝试启动守护程序失败两次-一次是由于mysql.user表,一次是由于mysql.db表。使用--skip-grant-tables运行mysql守护进程是可行的,但是使用这些表上的命令简单的select *也存在问题。

奇怪地做了两个简单的查询:

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

然后杀死守护程序以正确启动它

service mysql start

似乎有效。现在,我将尝试自动解决此问题。我仍在寻找一种“适当”的解决方案,以找出这种奇怪行为的原因是什么。

Docker文件

#*********************************************************************
#
# Dockerfile for /server/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 info@bitplan.com

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 info@bitplan.com
 ---> 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 ]

看原来泊坞窗文件github.com/docker-library/mysql/blob/...和entrypoint.sh github.com/docker-library/mysql/blob/...。他们会告诉您需要做什么。
塔伦·拉尔瓦尼

谢谢你的提示。我的进一步实验表明,5.7.x系列发行版的行为取决于x。到5.7.14,事情似乎更简单了。该severalnines.com/blog/...方法适用于我的Linux环境。在我的Mac OS环境中,事情变得更加困难。
Wolfgang Fahl,
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.