Erreur fatale: impossible d'ouvrir et de verrouiller les tables de privilèges: le moteur de stockage de table pour 'utilisateur' n'a pas cette option

15

Ce message d'erreur apparaît lorsque j'utilise ubuntu 16.04 et le dernier mysql 5.7.19-0ubuntu0.16.04.1 dans une image Docker.

Que pourrait-on faire pour résoudre ce problème?

Pour reproduire l'erreur

  1. Obtenez le Dockerfile:

    FROM ubuntu:16.04
    
    RUN apt update
    RUN DEBIAN_FRONTEND=noninteractive apt install -y mysql-server
    

    (également disponible ici )

  2. Construire et exécuter:

    docker build -t mysqlfail . 
    docker run -it mysqlfail tail -1 /var/log/mysql/error.log
    

    aurait été montré le journal des erreurs suivant:

    2017-08-26T11: 48: 45.398445Z 1 [Avertissement] root @ localhost est créé avec un mot de passe vide! Veuillez envisager de désactiver l'option --initialize-insecure.

    C'est exactement ce que nous voulions: un mysql sans mot de passe root défini pour le moment.

  3. Dans le passé (Ubuntu 14.04 / mysql 5.5), service mysql startc'était possible. Maintenant, si vous essayez cela, cela échoue

    docker run -it mysqlfail service mysql start
     * Starting MySQL database server mysqld    
      No directory, logging in with HOME=/  
                                                                            [fail]
    

    et /var/log/mysql/error.logcontient une ligne:

    2017-08-26T11: 59: 57.680618Z 0 [ERREUR] Erreur fatale: impossible d'ouvrir et de verrouiller les tables de privilèges: le moteur de stockage de table pour 'utilisateur' n'a pas cette option


journal de construction (pour l'intégralité 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

suite bizarre

Après les expériences décrites dans ma tentative de réponse , j'ai créé un script shell qui fait un

select count(*)

requête sur chaque table de l'espace mysql trois fois de suite (car les expériences montrent que sur certaines tables, la requête échouera exactement deux fois :-().

Puis un

mysql_upgrade   

et le

service mysql restart

est essayé. Dans le Dockerfilescript est mis à disposition via

COPY mysqltest.sh .

Les essais avec ce script donnent des résultats étranges / fous.

  1. Car le Docker environmentdépart échoue encore

    [ERREUR] Erreur fatale: impossible d'ouvrir et de verrouiller les tables de privilèges: le moteur de stockage de table pour 'utilisateur' n'a pas cette option

  2. Exécution du script

    sh mysqltest.sh root
    

    dans les docker environmentpistes de

    2017-08-27T09: 12: 47.021528Z 12 [ERREUR] / usr / sbin / mysqld: La table './mysql/db' est marquée comme
    plantée et doit être réparée 2017-08-27T09: 12: 47.050141Z 12 [ERREUR ] Impossible de réparer la table: mysql.db
    2017-08-27T09: 12: 47.055925Z 13 [ERREUR] / usr / sbin / mysqld: La table './mysql/db' est marquée comme
    plantée et doit être réparée 2017-08 -27T09: 12: 47.407700Z 54 [ERREUR] / usr / sbin / mysqld: La table './mysql/proc' est marquée comme
    plantée et doit être réparée 2017-08-27T09: 12: 47.433516Z 54 [ERREUR] Ne pouvait pas ' t table de réparation: mysql.proc
    2017-08-27T09: 12: 47.440695Z 55 [ERREUR] / usr / sbin / mysqld: La table './mysql/proc' est marquée comme
    plantée et doit être réparée 2017-08-27T09: 12: 47.769485Z 81 [ERREUR] / usr / sbin / mysqld: Table './mysql/tables_priv'est marqué comme écrasé et doit être réparé
    2017-08-27T09: 12: 47.792061Z 81 [ERREUR] Impossible de réparer la table: mysql.tables_priv
    2017-08-27T09: 12: 47.798472Z 82 [ERREUR] / usr / sbin / mysqld: Table './mysql/ tables_priv 'est marqué comme planté et doit être réparé
    2017-08-27T09: 12: 47.893741Z 99 [ERREUR] / usr / sbin / mysqld: Le tableau' ./mysql/user 'est marqué comme planté et doit être réparé
    2017-08 -27T09: 12: 47.914288Z 99 [ERREUR] Impossible de réparer la table: mysql.user
    2017-08-27T09: 12: 47.920459Z 100 [ERREUR] / usr / sbin / mysqld: La table './mysql/user' est marqué comme écrasé et doit être réparé

Que se passe-t-il ici pour provoquer ce comportement étrange?

Wolfgang Fahl
la source
1
mysqld --skip-grant-tables --skip-networking semble fonctionner
Wolfgang Fahl
mkdir / var / run / mysqld; chown mysql / var / run / mysqld peut également être nécessaire.
Wolfgang Fahl
1
--skip-networking désactivera toutes les connexions TCP / IP que vous voudrez peut-être établir avec le serveur, donc parfois c'est mauvais. mariadb.com/kb/en/server-system-variables/#skip_networking
Darko Maksimovic
@DarkoMaksimovic voit la réponse acceptée pour que le paramètre de propriété soit la solution.
Wolfgang Fahl
J'avais déjà essayé cela et cela n'a rien changé dans mon cas (MySQL 5.7 sur MacOS, Docker 2.1.0.5). Seules --skip-grant-tables ont aidé à démarrer le serveur, bien que quelqu'un dans ce fil se soit plaint d'autres sélections, mais je verrai quand cela m'arrivera.
Darko Maksimovic

Réponses:

30

Ran dans le même problème aujourd'hui. J'exécute le service MySQL pendant la construction du docker pour les tests unitaires et la mise à niveau vers MySQL CE 5.7.19 de MariaDB a interrompu la construction. Ce qui a résolu le problème pour moi était de s'exécuter à chown -R mysql:mysql /var/lib/mysql /var/run/mysqldchaque fois avant de démarrer le service mysql.

Donc, mon Dockerfile ressemble à ceci maintenant:

RUN chown -R mysql:mysql /var/lib/mysql /var/run/mysqld && \
    service mysql start && \
    mvn -q verify site

J'espère que cela t'aides.

Tibor Gyuris
la source
2
Même problème ici. J'ai eu une construction en deux étapes et le Dockerfile "parent" exécute déjà cette chmodcommande. La génération réussit lorsque je l'exécute sur un serveur Ubuntu distant, mais échoue lorsque je l'exécute sur ma machine locale (OS X). L'ajout de la chmodcommande au Dockerfile enfant a résolu le problème. Étrange .
senderle
2
Je vous remercie! Je savais que quelqu'un d'autre devait avoir un cas d'utilisation similaire au mien.
jeudi
2
@senderle vient également de trouver ce fil. "Construisez une fois, déployez n'importe où", ont-ils déclaré
duhaime
9

solution de contournement

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

Description du problème

Le problème sous-jacent tel qu'indiqué par aalexgabi est dû à l'implémentation des standards POSIX d'OverlayFS :

open (2): OverlayFS implémente uniquement un sous-ensemble des normes POSIX. Cela peut entraîner certaines opérations OverlayFS enfreignant les normes POSIX. Une telle opération est l'opération de copie. Supposons que votre application appelle fd1=open("foo", O_RDONLY)puis fd2=open("foo", O_RDWR). Dans ce cas, votre application s'attend à ce que fd1 et fd2 se réfèrent au même fichier. Cependant, en raison d'une opération de copie qui se produit après le deuxième appel à open(2), les descripteurs font référence à différents fichiers. Le fd1 continue de référencer le fichier dans l'image (lowerdir) et le fd2 fait référence au fichier dans le conteneur (upperdir). Une solution de contournement consiste à toucher les fichiers qui provoquent l'opération de copie. Toutes les open(2)opérations suivantes , quel que soit le mode d'accès en lecture seule ou en lecture-écriture, référenceront le fichier dans le conteneur (upperdir).

Référence:

Murmel
la source
1
C'est une horrible nouvelle. Je me demande pourquoi docker n'est pas réparé.
Wolfgang Fahl
2
Honnêtement? Moi non plus! Je veux dire que cela doit affecter de nombreuses applications, car il s'agit vraiment d'une opération de base sur les fichiers. Bien sûr, le problème ne se produit que sous certaines conditions, mais ils ne sont pas si loin ...
Murmel
8

J'ai confirmé l'erreur sur overlayfs (overlay2) qui est la valeur par défaut sur Docker pour Mac. L'erreur se produit lors du démarrage de mysql sur l'image, après avoir créé une image avec 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

Le passage à "aufs" a résolu le problème. (Sur Docker pour Mac, le fichier "daemon.json" peut être modifié en choisissant le menu "Préférences ...", en sélectionnant l'onglet "Démon" et en sélectionnant l'onglet "Avancé".)

/etc/docker/daemon.json:

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

Réf:

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

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

Tsuneo Yoshioka
la source
1
Cela a résolu mon problème dans Ubuntu 16:04. J'avais précédemment configuré le pilote de stockage overlay2 dans docker. Merci.
Havok
1
Cela a empêché Docker de redémarrer sur OSX :(
duhaime
2

Voici une réponse que je ne vois pas encore ici.

Ajoutez ceci à votre dockerfile: VOLUME /var/lib/mysql

Cela entraînera le dossier / var / lib / mysql à utiliser le système de fichiers natif plutôt que overlayFS. Cela contourne ce problème.

C'est la solution que l'image docker officielle de mysql utilise pour gérer cela, comme vous pouvez le voir ici: https://github.com/docker-library/mysql/blob/9d1f62552b5dcf25d3102f14eb82b579ce9f4a26/5.7/Dockerfile

Paul Dejean
la source
1

Ce n'est peut-être pas encore tout à fait la solution. Quoi qu'il en soit, cela pourrait indiquer aux autres une réponse «correcte»

Le journal de session bash de docker ci-dessous montre une séquence d'étapes qui conduisent à des erreurs étranges et enfin à pouvoir démarrer correctement le démon mysql dans l'environnement docker.

Essayer de démarrer le démon dans cette session échoue deux fois - une fois à cause de la table mysql.user et une fois à cause de la table mysql.db. L'exécution du démon mysql avec --skip-grant-tables fonctionne mais il y a aussi des problèmes avec la simple sélection * des commandes sur ces tables.

Fait étrangement deux requêtes simples:

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

puis tuer le démon pour le démarrer correctement avec

service mysql start

semble fonctionner. Je vais maintenant essayer d'automatiser cela comme solution de contournement. Je cherche toujours une solution «appropriée» au problème et certains savent quelle est la raison de ce comportement étrange.

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

journal de construction

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

journal de session 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 ]
Wolfgang Fahl
la source
Regardez le fichier docker d'origine github.com/docker-library/mysql/blob/… et le point d'entrée.sh github.com/docker-library/mysql/blob/… . Ils vous donneront une idée de ce qui doit être fait.
Tarun Lalwani
Merci pour l'astuce. Mes autres expériences montrent que la série de versions 5.7.x se comporte différemment selon le x. Jusqu'à 5.7.14, la chose semble avoir été plus simple. L' approche multiplenines.com/blog/… fonctionne dans mon environnement Linux. Dans mon environnement Mac OS, les choses sont plus difficiles.
Wolfgang Fahl