Error grave: no se pueden abrir y bloquear tablas de privilegios: el motor de almacenamiento de tablas para 'usuario' no tiene esta opción

15

Este mensaje de error aparece cuando uso ubuntu 16.04 y el último mysql 5.7.19-0ubuntu0.16.04.1 en una imagen de Docker.

¿Qué se podría hacer para arreglar esto?

Para reproducir el error

  1. Obtén el Dockerfile:

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

    (también disponible aquí )

  2. Construye y ejecuta:

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

    se le habría mostrado el siguiente registro de errores:

    2017-08-26T11: 48: 45.398445Z 1 [Advertencia] root @ localhost se crea con una contraseña vacía. Considere desactivar la opción --initialize-insecure.

    Que era exactamente lo que queríamos: un mysql sin contraseña de root establecida todavía.

  3. En el pasado (ubuntu 14.04 / mysql 5.5) a service mysql startera posible. Ahora si intentas esto falla

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

    y /var/log/mysql/error.logcontiene una línea:

    2017-08-26T11: 59: 57.680618Z 0 [ERROR] Error grave: no se pueden abrir y bloquear tablas de privilegios: el motor de almacenamiento de tablas para 'usuario' no tiene esta opción


registro de compilación (para el completo 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

continuación extraña

Después de los experimentos como se describe en mi intento de respuesta , creé un script de shell que hace un

select count(*)

consulta en cada tabla en el espacio mysql tres veces seguidas (porque los experimentos muestran que en algunas tablas la consulta fallará exactamente dos veces :-().

Entonces un

mysql_upgrade   

y el

service mysql restart

es probado En el Dockerfileguión está disponible a través de

COPY mysqltest.sh .

Las pruebas con este script dan resultados extraños / locos.

  1. Para el Docker environmentcomienzo todavía falla

    [ERROR] Error grave: no se pueden abrir y bloquear tablas de privilegios: el motor de almacenamiento de tablas para 'usuario' no tiene esta opción

  2. Ejecutando el script

    sh mysqltest.sh root
    

    en las docker environmentpistas para

    2017-08-27T09: 12: 47.021528Z 12 [ERROR] / usr / sbin / mysqld: la tabla './mysql/db' está marcada como
    bloqueada y debe repararse 2017-08-27T09: 12: 47.050141Z 12 [ERROR ] No se pudo reparar la tabla: mysql.db
    2017-08-27T09: 12: 47.055925Z 13 [ERROR] / usr / sbin / mysqld: la tabla './mysql/db' está marcada como
    bloqueada y debe repararse 2017-08 -27T09: 12: 47.407700Z 54 [ERROR] / usr / sbin / mysqld: la tabla './mysql/proc' está marcada como
    bloqueada y debe repararse 2017-08-27T09: 12: 47.433516Z 54 [ERROR] no se pudo ' t tabla de reparación: mysql.proc
    2017-08-27T09: 12: 47.440695Z 55 [ERROR] / usr / sbin / mysqld: la tabla './mysql/proc' está marcada como
    bloqueada y debe repararse 2017-08-27T09: 12: 47.769485Z 81 [ERROR] / usr / sbin / mysqld: Tabla './mysql/tables_priv'está marcado como bloqueado y debe repararse
    2017-08-27T09: 12: 47.792061Z 81 [ERROR] No se pudo reparar la tabla: mysql.tables_priv
    2017-08-27T09: 12: 47.798472Z 82 [ERROR] / usr / sbin / mysqld: Table './mysql/ tables_priv 'está marcado como bloqueado y debe repararse
    2017-08-27T09: 12: 47.893741Z 99 [ERROR] / usr / sbin / mysqld: Table' ./mysql/user 'está marcado como
    bloqueado y debe repararse 2017-08 -27T09: 12: 47.914288Z 99 [ERROR] No se pudo reparar la tabla: mysql.user
    2017-08-27T09: 12: 47.920459Z 100 [ERROR] / usr / sbin / mysqld: La tabla './mysql/user' es marcado como estrellado y debe repararse

¿Qué está pasando aquí para causar este extraño comportamiento?

Wolfgang Fahl
fuente
1
mysqld --skip-grant-tables --skip-networking parece funcionar
Wolfgang Fahl el
mkdir / var / run / mysqld; chown mysql / var / run / mysqld también podría ser necesario.
Wolfgang Fahl el

Respuestas:

30

Me encontré con el mismo problema hoy. Estoy ejecutando el servicio MySQL durante la compilación de Docker para las pruebas unitarias y la actualización a MySQL CE 5.7.19 de MariaDB rompió la compilación. Lo que resolvió el problema para mí se ejecutaba chown -R mysql:mysql /var/lib/mysql /var/run/mysqldcada vez antes de iniciar el servicio mysql.

Entonces mi Dockerfile se ve así ahora:

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

Espero que esto ayude.

Tibor Gyuris
fuente
2
El mismo problema aqui. Tuve una compilación de dos etapas en funcionamiento, y el Dockerfile "padre" ya ejecuta este chmodcomando. La compilación tiene éxito cuando lo ejecuto en un servidor Ubuntu remoto, pero falla cuando lo ejecuto en mi máquina local (OS X). Agregar el chmodcomando al archivo Docker secundario solucionó el problema. Extraña .
senderle
2
¡Gracias! Sabía que alguien más tenía que tener un caso de uso similar al mío.
trillado
2
@senderle acaba de encontrar este hilo también. "Construye una vez, despliega en cualquier lugar" dijeron
duhaime
8

Confirmé el error en overlayfs (overlay2) que es el predeterminado en Docker para Mac. El error ocurre al iniciar mysql en la imagen, después de crear una imagen con 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

Cambiar a "aufs" resolvió el problema. (En Docker para Mac, el "daemon.json" se puede editar seleccionando el menú "Preferencias ...", seleccionando la pestaña "Daemon" y seleccionando la pestaña "Avanzado".

/etc/docker/daemon.json:

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

Árbitro:

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

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

Tsuneo Yoshioka
fuente
1
Esto resolvió mi problema en Ubuntu 16:04. Había configurado previamente el controlador de almacenamiento overlay2 en la ventana acoplable. Gracias.
Havok
Esto evitó que Docker se reiniciara en OSX :(
duhaime
8

Solución alterna

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

Descripción del problema

El problema subyacente según lo establecido por aalexgabi se debe a la implementación de los estándares POSIX de OverlayFS :

open (2): OverlayFS solo implementa un subconjunto de los estándares POSIX. Esto puede provocar que ciertas operaciones de OverlayFS rompan los estándares POSIX. Una de esas operaciones es la operación de copia. Supongamos que su aplicación llama fd1=open("foo", O_RDONLY)y luego fd2=open("foo", O_RDWR). En este caso, su aplicación espera que fd1 y fd2 hagan referencia al mismo archivo. Sin embargo, debido a una operación de copia que ocurre después de la segunda llamada a open(2), los descriptores hacen referencia a diferentes archivos. El fd1 continúa haciendo referencia al archivo en la imagen (lowerdir) y el fd2 hace referencia al archivo en el contenedor (upperdir). Una solución alternativa para esto es tocar los archivos que provocan la operación de copia. Todas las open(2)operaciones posteriores , independientemente del modo de acceso de solo lectura o lectura-escritura, harán referencia al archivo en el contenedor (upperdir).

Referencia:

Murmel
fuente
1
Esta es una noticia horrible. Me pregunto por qué Docker no está arreglado.
Wolfgang Fahl el
2
¿Honestamente? ¡Yo tampoco! Quiero decir que esto tiene que afectar a muchas aplicaciones, porque es realmente una operación básica de archivos. Por supuesto, el problema ocurre solo bajo ciertas condiciones, pero no están tan lejos ...
Murmel
1

Esta podría no ser la solución todavía. De todos modos, podría señalar a otros una respuesta "adecuada"

El registro de la sesión de docker bash a continuación muestra una secuencia de pasos que conducen a errores extraños y finalmente poder iniciar el demonio mysql correctamente en el entorno de docker.

Intentar iniciar el demonio en esta sesión falla dos veces: una debido a la tabla mysql.user y otra debido a la tabla mysql.db. Ejecutar el demonio mysql con --skip-grant-tables funciona pero también hay problemas con la simple selección * de los comandos en estas tablas.

Extrañamente haciendo dos consultas simples:

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

y luego matando al demonio para comenzarlo correctamente con

service mysql start

parece funcionar. Ahora intentaré automatizar esto como una solución alternativa. Todavía estoy buscando una solución "adecuada" para el problema y alguna idea de cuál es la razón de este extraño comportamiento.

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

registro de compilación

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

registro de sesión 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
fuente
Mire el archivo acoplable original github.com/docker-library/mysql/blob/… y el entrypoint.sh github.com/docker-library/mysql/blob/… . Te darán una idea de lo que hay que hacer.
Tarun Lalwani
gracias por la pista. Mis experimentos posteriores muestran que la serie de lanzamientos 5.7.x se comporta de manera diferente dependiendo de la x. Hasta 5.7.14 la cosa parece haber sido más simple. El enfoque multiplenines.com/blog/… funciona en mi entorno Linux. En mi entorno Mac OS las cosas son más difíciles.
Wolfgang Fahl