Фатальна помилка: Не вдається відкрити та заблокувати таблиці привілеїв: У механізмі зберігання таблиць для "користувача" немає цієї опції


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 створений з порожнім паролем! Подумайте про вимкнення опції - ініціалізувати незахищеність.

    Що було саме те, що ми хотіли: mysql ще не встановлений пароль root.

  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-25


журнал складання (для повного 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

дивне продовження

Після експериментів, як було описано у моїй спробі відповіді , я створив сценарій оболонки, який робить a

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 [ПОМИЛКА] / 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-table --skip-мережа, здається, працює
Wolfgang Fahl

mkdir / var / run / mysqld; також може знадобитися chown mysql / var / run / mysqld.
Вольфганг Фал

1
--skip-мережа відключить будь-які з'єднання TCP / IP, які ви хочете зробити з сервером, тому іноді це погано. mariadb.com/kb/en/server-system-variables/#skip_networking
Дарко Максимович

@DarkoMaksimovic вирішує прийняту відповідь для налаштування права власності.
Вольфганг Фал

Я насправді це вже намагався, і це нічого не змінило в моєму випадку (MySQL 5.7 на MacOS, Docker 2.1.0.5). Тільки --skip-grant-таблиці допомогли запустити сервер, хоча хтось із цієї теми поскаржився на подальший вибір, але я побачу, коли це трапиться зі мною.
Дарко Максимович

Відповіді:


31

Зустрівшись із тією ж проблемою і сьогодні. Я запускаю службу 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 продовжує посилатися на файл у зображенні (downdir), а fd2 посилається на файл у контейнері (upperdir). Вирішення цього завдання - це торкнутися файлів, що спричинить операцію копіювання. Всі наступні open(2)операції незалежно від режиму доступу лише для читання або запису для читання будуть посилатися на файл у контейнері (верхній дір).

Довідка:


1
Це жахлива новина. Цікаво, чому докер не виправлений.
Вольфганг Фаль

2
Чесно? Я також ні! Я маю на увазі, що це має вплинути на безліч додатків, оскільки це дійсно основна операція з файлами. Звичайно, проблема виникає лише за певних умов, але вони не так вже й далекі ...
Мурмель

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

Перехід на "ауфи" вирішив проблему. (На Docker для Mac "daemon.json" можна відредагувати, вибравши меню "Налаштування ..." та вибравши вкладку "Демон" та вибравши вкладку "Додатково".)

/etc/docker/daemon.json:

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

Довідка:

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

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


1
Це вирішило мою проблему в Ubuntu 16:04. Раніше я налаштував драйвер зберігання overlay2 у докер. Спасибі.
Хавок

1
Це завадило докер перезапустити OSX :(
duhaime

2

Ось відповідь я ще не бачу тут.

Додайте це до свого докерфайлу: VOLUME /var/lib/mysql

Це призведе до того, що папка / var / lib / mysql використовуватиме власну файлову систему, а не overlayFS. Це обходить це питання.

Це рішення, яке офіційний образ докера mysql використовує для вирішення цього питання, як ви можете бачити тут: https://github.com/docker-library/mysql/blob/9d1f62552b5dcf25d3102f14eb82b579ce9f4a26/5.7/Dockerfile


1

Це може бути не зовсім рішенням. У будь-якому випадку це може вказувати оточуючим на "правильну" відповідь

Нижній журнал сеансів баскер-докера показує послідовність кроків, які призводять до дивних помилок і, нарешті, зможуть правильно запустити mysql демон в середовищі докера.

Спроба запустити демон на цьому сеансі провалюється двічі - один раз через таблицю mysql.user і один раз через таблицю mysql.db. Запуск демона mysql за допомогою --skip-grant-таблиць працює, але також є проблеми з простим виділенням * з команд цих таблиць.

Дивно робити два прості запити:

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

а потім вбити демона, щоб почати його правильно

service mysql start

здається, працює. Зараз я спробую автоматизувати це як спосіб вирішення. Я все ще шукаю «правильного» вирішення проблеми і деякої підказки, в чому причина цієї дивної поведінки.

Докерфайл

#*********************************************************************
#
# 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/… . Вони дадуть вам уявлення про те, що потрібно зробити.
Tarun Lalwani

Дякую за підказку Мої подальші експерименти показують, що серія випусків 5.7.x поводиться по-різному залежно від x. До 5.7.14 справа, здається, була простішою. Підхід декількох мереж.com/blog/… працює в моєму середовищі Linux. У моєму середовищі Mac OS справи складніші.
Вольфганг Фал
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.