Erro fatal: não é possível abrir e bloquear tabelas de privilégios: o mecanismo de armazenamento de tabela para 'usuário' não possui esta opção

15

Esta mensagem de erro aparece quando eu uso o ubuntu 16.04 e o mais recente mysql 5.7.19-0ubuntu0.16.04.1 em uma imagem do Docker.

O que poderia ser feito para corrigir isso?

Para reproduzir o erro

  1. Obtenha o Dockerfile:

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

    (também disponível aqui )

  2. Crie e execute:

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

    teria sido mostrado o seguinte log de erros:

    2017-08-26T11: 48: 45.398445Z 1 [Aviso] root @ localhost é criado com uma senha vazia! Por favor, considere desativar a opção --initialize-insecure.

    O que era exatamente o que queríamos: um mysql sem senha de root definida ainda.

  3. No passado (ubuntu 14.04 / mysql 5.5) service mysql startera possível. Agora, se você tentar isso, ele falha

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

    e /var/log/mysql/error.logcontém uma linha:

    2017-08-26T11: 59: 57.680618Z 0 [ERRO] Erro fatal: não é possível abrir e bloquear tabelas de privilégios: O mecanismo de armazenamento de tabela para 'usuário' não possui esta opção


log de construção (para o 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

continuação estranha

Após as experiências descritas na minha tentativa de resposta , criei um script de shell que faz um

select count(*)

consulta em cada tabela no espaço mysql três vezes seguidas (porque experimentos mostram que em algumas tabelas a consulta falha exatamente duas vezes :-().

Então uma

mysql_upgrade   

e a

service mysql restart

é tentado. No Dockerfilescript, é disponibilizado via

COPY mysqltest.sh .

Os testes com esse script fornecem resultados estranhos / malucos.

  1. Para o Docker environmentinício ainda falha

    [ERRO] Erro fatal: não é possível abrir e bloquear tabelas de privilégios: o mecanismo de armazenamento de tabela para 'usuário' não possui esta opção

  2. Executando o Script

    sh mysqltest.sh root
    

    nas docker environmentpistas para

    2017-08-27T09: 12: 47.021528Z 12 [ERRO] / usr / sbin / mysqld: A tabela './mysql/db' está marcada como
    travada e deve ser reparada 2017-08-27T09: 12: 47.050141Z 12 [ERRO ] Não foi possível reparar a tabela: mysql.db
    2017-08-27T09: 12: 47.055925Z 13 [ERRO] / usr / sbin / mysqld: A tabela './mysql/db' está marcada como
    travada e deve ser reparada 2017-08 -27T09: 12: 47.407700Z 54 [ERRO] / usr / sbin / mysqld: A tabela './mysql/proc' está marcada como
    travada e deve ser reparada 2017-08-27T09: 12: 47.433516Z 54 [ERRO] Não foi possível ' tabela de reparo t: mysql.proc
    2017-08-27T09: 12: 47.440695Z 55 [ERRO] / usr / sbin / mysqld: A tabela './mysql/proc' está marcada como
    travada e deve ser reparada 2017-08-27T09: 12: 47.769485Z 81 [ERRO] / usr / sbin / mysqld: tabela './mysql/tables_priv'está marcado como travado e deve ser reparado
    2017-08-27T09: 12: 47.792061Z 81 [ERRO] Não foi possível reparar a tabela: mysql.tables_priv
    2017-08-27T09: 12: 47.798472Z 82 [ERRO] / usr / sbin / mysqld: Tabela './mysql/ tables_priv 'está marcado como travado e deve ser reparado
    2017-08-27T09: 12: 47.893741Z 99 [ERRO] / usr / sbin / mysqld: A tabela' ./mysql/user 'está marcada como
    travada e deve ser reparada 2017-08 -27T09: 12: 47.914288Z 99 [ERRO] Não foi possível reparar a tabela: mysql.user
    2017-08-27T09: 12: 47.920459Z 100 [ERRO] / usr / sbin / mysqld: A tabela './mysql/user' é marcado como travado e deve ser reparado

O que está acontecendo aqui para causar esse comportamento estranho?

Wolfgang Fahl
fonte
1
mysqld --skip-grant-tables --skip-networking parece funcionar
Wolfgang Fahl
mkdir / var / run / mysqld; chown mysql / var / run / mysqld também pode ser necessário.
Wolfgang Fahl

Respostas:

30

Encontrei o mesmo problema hoje. Estou executando o serviço MySQL durante a construção do docker para os testes de unidade e a atualização para o MySQL CE 5.7.19 do MariaDB interrompeu a construção. O que resolveu o problema para mim estava sendo executado chown -R mysql:mysql /var/lib/mysql /var/run/mysqldcada vez antes de iniciar o serviço mysql.

Portanto, meu Dockerfile se parece com isso agora:

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

Espero que isto ajude.

Tibor Gyuris
fonte
2
Mesmo problema aqui. Eu tive uma compilação de dois estágios e o Dockerfile "pai" já executa esse chmodcomando. A compilação é bem-sucedida quando eu a executo em um servidor Ubuntu remoto, mas falha quando executada na minha máquina local (OS X). A adição do chmodcomando ao Dockerfile filho corrigiu o problema. Estranho .
Senderle
2
Obrigado! Eu sabia que alguém lá fora tinha que ter um caso de uso semelhante ao meu.
Threed
2
O @senderle também encontrou este tópico. "Construa uma vez, implante em qualquer lugar", disseram eles
duhaime
8

Confirmei o erro no overlayfs (overlay2), que é o padrão no Docker for Mac. O erro ocorre ao iniciar o mysql na imagem, depois de criar uma imagem com o 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

Mudar para "aufs" resolveu o problema. (No Docker para Mac, o "daemon.json" pode ser editado escolhendo o menu "Preferências ..." e selecionando a guia "Daemon" e selecionando a guia "Avançado".)

/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

Tsuneo Yoshioka
fonte
1
Isso resolveu meu problema no Ubuntu 16:04. Eu havia configurado anteriormente o driver de armazenamento overlay2 na janela de encaixe. Obrigado.
Havok
Isso impediu o docker de reiniciar no OSX :(
duhaime
8

Gambiarra

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

Descrição do Problema

O problema subjacente, conforme declarado por aalexgabi, é devido à implementação dos padrões POSIX do OverlayFS :

open (2): o OverlayFS implementa apenas um subconjunto dos padrões POSIX. Isso pode resultar em certas operações OverlayFS quebrando os padrões POSIX. Uma dessas operações é a operação de cópia. Suponha que seu aplicativo chame fd1=open("foo", O_RDONLY)e então fd2=open("foo", O_RDWR). Nesse caso, seu aplicativo espera que fd1 e fd2 se refiram ao mesmo arquivo. No entanto, devido a uma operação de cópia que ocorre após a segunda chamada para open(2), os descritores se referem a arquivos diferentes. O fd1 continua a referenciar o arquivo na imagem (lowerdir) e o fd2 faz referência ao arquivo no contêiner (upperdir). Uma solução alternativa para isso é tocar nos arquivos que causam a operação de cópia. Todas as open(2)operações subseqüentes , independentemente do modo de acesso somente leitura ou leitura e gravação, farão referência ao arquivo no contêiner (upperdir).

Referência:

Murmel
fonte
1
Esta é uma notícia horrível. Eu me pergunto por que o docker não é fixo.
Wolfgang Fahl
2
Honestamente? Nem eu! Quero dizer que isso deve afetar muitos aplicativos, porque é realmente uma operação básica de arquivo. É claro que o problema ocorre somente sob certas condições, mas eles não são tão longe ...
Murmel
2

Aqui está uma resposta que ainda não vejo aqui.

Adicione isso ao seu dockerfile: VOLUME /var/lib/mysql

Isso fará com que a pasta / var / lib / mysql use o sistema de arquivos nativo em vez de overlayFS. Isso contorna esse problema.

Esta é a solução que a imagem oficial do docker mysql usa para lidar com isso, como você pode ver aqui: https://github.com/docker-library/mysql/blob/9d1f62552b5dcf25d3102f14eb82b579ce9f4a26/5.7/Dockerfile

Paul Dejean
fonte
1

Talvez essa ainda não seja a solução. De qualquer forma, pode apontar outras pessoas para uma resposta "adequada"

O log da sessão do docker bash abaixo mostra uma sequência de etapas que levam a erros estranhos e finalmente podem iniciar o daemon mysql corretamente no ambiente do docker.

A tentativa de iniciar o daemon nesta sessão falha duas vezes - uma vez devido à tabela mysql.user e uma vez devido à tabela mysql.db. A execução do daemon mysql com --skip-grant-tables funciona, mas também há problemas com os comandos simples select * from nessas tabelas.

Estranhamente, fazendo duas consultas simples:

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

e depois matar o daemon para iniciá-lo corretamente com

service mysql start

parece funcionar. Agora vou tentar automatizar isso como uma solução alternativa. Ainda estou procurando uma solução "adequada" para o problema e algumas pistas sobre o motivo desse estranho comportamento.

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

construir log

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

log de sessão do 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
fonte
Observe o arquivo docker original github.com/docker-library/mysql/blob/… e o entrypoint.sh github.com/docker-library/mysql/blob/… . Eles vão te dar uma idéia do que precisa ser feito.
Tarun Lalwani 27/08/17
Obrigado pela dica. Minhas experiências adicionais mostram que a série de lançamentos 5.7.x se comporta de maneira diferente, dependendo do x. Até 5.7.14 coisa parece ter sido mais simples. A abordagem variousnines.com/blog/… funciona no meu ambiente linux. No meu ambiente Mac OS, as coisas são mais difíceis.
Wolfgang Fahl