Неустранимая ошибка: невозможно открыть и заблокировать таблицы привилегий: механизм хранения таблиц для пользователя не имеет этой опции

15

Это сообщение об ошибке появляется, когда я использую ubuntu 16.04 и последнюю версию mysql 5.7.19-0ubuntu0.16.04.1 в образе Docker.

Что можно сделать, чтобы это исправить?

Воспроизвести ошибку

  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.

    Это было именно то, что мы хотели: mysql без пароля root.

  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 три раза подряд (поскольку эксперименты показывают, что для некоторых таблиц запрос завершится с ошибкой ровно дважды :-().

Потом

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/ tables_priv 'помечен как аварийный и должен быть исправлен
    2017-08-27T09: 12: 47.893741Z 99 [ОШИБКА] / usr / sbin / mysqld: Таблица' ./mysql/user 'помечена как
    аварийная и должна быть восстановлена 2017-08-08 -27T09: 12: 47.914288Z 99 [ОШИБКА] Не удалось восстановить таблицу: mysql.user
    2017-08-27T09: 12: 47.920459Z 100 [ОШИБКА] / usr / sbin / mysqld: Таблица './mysql/user' is помечен как разбившийся и должен быть отремонтирован

Что здесь происходит, чтобы вызвать это странное поведение?

Вольфганг Фаль
источник
1
mysqld --skip-grant-tables --skip-сети, кажется, работает
Вольфганг
mkdir / var / run / mysqld; также может потребоваться chown mysql / var / run / mysqld.
Вольфганг
1
--skip-network отключит любые соединения TCP / IP, которые вы можете захотеть установить с сервером, поэтому иногда это плохо. mariadb.com/kb/en/server-system-variables/#skip_networking
Дарко Максимович
@DarkoMaksimovic см. Принятый ответ для настройки собственности, чтобы быть решением.
Вольфганг Фал
Я на самом деле уже пробовал это, и это ничего не изменило в моем случае (MySQL 5.7 на MacOS, Docker 2.1.0.5). Только --skip-grant-tables помог запустить сервер, хотя кто-то в этой теме жаловался на дальнейшие select'ы, но я посмотрю, когда это произойдет со мной.
Дарко Максимович

Ответы:

30

Столкнулся с той же проблемой сегодня. Я запускаю службу MySQL во время сборки докера для модульных тестов, а обновление до MySQL CE 5.7.19 от MariaDB прервало сборку. То, что решило проблему для меня, запускалось 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
2
Спасибо! Я знал, что у кого-то еще должен быть такой же вариант использования, как и у меня.
Тридцатого
2
@senderle только что нашел эту ветку. «Построить один раз, развернуть где угодно»,
duhaime
9

Временное решение

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

Описание проблемы

Основная проблема, заявленная aalexgabi , связана с реализацией стандартов POSIX для OverlayFS :

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

Ссылка:

Murmel
источник
1
Это ужасные новости. Интересно, почему докер не исправлен.
Вольфганг Фал
2
Честно? И я нет! Я имею в виду, что это должно повлиять на многие приложения, потому что это действительно базовая файловая операция. Конечно, проблема возникает только при определенных условиях, но они не так далеко ...
Murmel
8

Я подтвердил ошибку на overlayfs (overlay2), которая по умолчанию установлена ​​в Docker для 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» решил проблему. (В Docker для Mac файл «daemon.json» можно редактировать, выбрав меню «Предпочтения ...», вкладку «Демон» и вкладку «Дополнительно».)

/etc/docker/daemon.json:

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

Ref:

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

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

Цунео Йошиока
источник
1
Это решило мою проблему в Ubuntu 16:04. Ранее я настроил драйвер хранилища overlay2 в докере. Благодарю.
Havok
1
Это предотвратило перезапуск докера на OSX :(
duhaime
2

Вот ответ, которого я пока не вижу здесь.

Добавьте это в ваш dockerfile: VOLUME /var/lib/mysql

Это заставит папку / var / lib / mysql использовать собственную файловую систему, а не overlayFS. Это обходит эту проблему.

Это решение, используемое официальным образом Docker для MySQL, как вы можете увидеть здесь: https://github.com/docker-library/mysql/blob/9d1f62552b5dcf25d3102f14eb82b579ce9f4a26/5.7/Dockerfile

Пол Дежан
источник
1

Возможно, это еще не совсем решение. В любом случае это может указывать другим на «правильный» ответ

В журнале сеанса Docker Bash ниже показана последовательность шагов, которые приводят к странным ошибкам и, наконец, к возможности правильно запустить демон mysql в среде Docker.

Попытка запустить демон в этом сеансе не удалась дважды - один раз из-за таблицы mysql.user и один раз из-за таблицы mysql.db. Запуск демона mysql с --skip-grant-tables работает, но есть также проблемы с простым выбором команд * в этих таблицах.

Странно делать два простых запроса:

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

а затем убить демона, чтобы запустить его правильно с

service mysql start

похоже на работу. Сейчас я попытаюсь автоматизировать это в качестве обходного пути. Я все еще ищу «правильное» решение проблемы, и некоторые понимают, в чем причина такого странного поведения.

Dockerfile

#*********************************************************************
#
# 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 вещь вроде бы была проще. В моем окружении linux работает подход twonines.com/blog/… В моей среде Mac OS все сложнее.
Вольфганг