web-dev-qa-db-fra.com

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

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é affiché 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'était exactement ce que nous voulions: un mysql sans mot de passe root pour le moment.

  3. Dans le passé (ubuntu 14.04/mysql 5.5) un service mysql start était possible. Maintenant, si vous essayez, 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.log contient 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 dans 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 Dockerfile le script est rendu disponible via

COPY mysqltest.sh .

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

  1. Pour le ---(Docker environment le démarrage échoue toujours

    [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 le docker environment conduit à

    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] Impossible de réparer la table: 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: La table './mysql/tables_priv' est marquée comme plantée et doit être réparée
    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: La table './mysql/tables_priv' est marquée comme plantée et doit être réparée
    2017-08-27T09: 12: 47.893741Z 99 [ERREUR]/usr/sbin/mysqld: La table './mysql/user' est marquée comme plantée et doit être réparée
    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ée comme plantée et doit être réparée

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

15
Wolfgang Fahl

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, c'était d'exécuter chown -R mysql:mysql /var/lib/mysql /var/run/mysqld à chaque 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.

32
Tibor Gyuris

Solution

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 n'implémente qu'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 opérations open(2) suivantes, indépendamment du mode d'accès en lecture seule ou en lecture-écriture, référenceront le fichier dans le conteneur (upperdir).

Référence:

9
Murmel

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/355

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

8
Tsuneo Yoshioka

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

2
Paul Dejean

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 https://serverfault.com/questions/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 build

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 ]
1
Wolfgang Fahl