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

13

Esta mensagem de erro aparece quando eu uso o Ubuntu 16.04 e o último 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 [Warning] root@localhost is created with an empty password ! Please consider switching off the --initialize-insecure option.

    Qual era exatamente o que nós queríamos: um mysql sem senha root ainda.

  3. No passado (Ubuntu 14.04 / mysql 5.5) foi possível um service mysql start . Agora, se você tentar isso, ele falhará

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

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

    2017-08-26T11:59:57.680618Z 0 [ERROR] Fatal error: Can't open and lock privilege tables: Table storage engine for 'user' doesn't have this option

criar log (para obter o 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 os experimentos descritos na minha tentativa de resposta , criei um script de shell que faz uma

select count(*)

consulta em cada tabela no espaço mysql três vezes seguidas (porque as experiências mostram que em algumas tabelas a consulta irá falhar exatamente duas vezes :-().

Então um

mysql_upgrade   

e o

service mysql restart

é tentado. No Dockerfile , o script é disponibilizado via

COPY mysqltest.sh .

Os testes com este script dão resultados estranhos / loucos.

  1. Para o Docker environment , o início ainda falha

    [ERROR] Fatal error: Can't open and lock privilege tables: Table storage engine for 'user' doesn't have this option

  2. Executando o script

    sh mysqltest.sh root
    

    na docker environment leva a

    2017-08-27T09:12:47.021528Z 12 [ERROR] /usr/sbin/mysqld: Table './mysql/db' is marked as crashed and should be repaired
    2017-08-27T09:12:47.050141Z 12 [ERROR] Couldn't repair table: mysql.db
    2017-08-27T09:12:47.055925Z 13 [ERROR] /usr/sbin/mysqld: Table './mysql/db' is marked as crashed and should be repaired
    2017-08-27T09:12:47.407700Z 54 [ERROR] /usr/sbin/mysqld: Table './mysql/proc' is marked as crashed and should be repaired
    2017-08-27T09:12:47.433516Z 54 [ERROR] Couldn't repair table: mysql.proc
    2017-08-27T09:12:47.440695Z 55 [ERROR] /usr/sbin/mysqld: Table './mysql/proc' is marked as crashed and should be repaired
    2017-08-27T09:12:47.769485Z 81 [ERROR] /usr/sbin/mysqld: Table './mysql/tables_priv' is marked as crashed and should be repaired
    2017-08-27T09:12:47.792061Z 81 [ERROR] Couldn't repair table: mysql.tables_priv
    2017-08-27T09:12:47.798472Z 82 [ERROR] /usr/sbin/mysqld: Table './mysql/tables_priv' is marked as crashed and should be repaired
    2017-08-27T09:12:47.893741Z 99 [ERROR] /usr/sbin/mysqld: Table './mysql/user' is marked as crashed and should be repaired
    2017-08-27T09:12:47.914288Z 99 [ERROR] Couldn't repair table: mysql.user
    2017-08-27T09:12:47.920459Z 100 [ERROR] /usr/sbin/mysqld: Table './mysql/user' is marked as crashed and should be repaired

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

    
por Wolfgang Fahl 26.08.2017 / 13:45

5 respostas

26

Correu para o mesmo problema hoje. Estou executando o serviço MySQL durante a compilação do docker para os testes de unidade e atualizando para o MySQL CE 5.7.19 do MariaDB quebrou a compilação. O que resolveu o problema para mim foi executar chown -R mysql:mysql /var/lib/mysql /var/run/mysqld cada vez antes de iniciar o serviço mysql.

Então, meu Dockerfile é assim agora:

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

Espero que isso ajude.

    
por 07.09.2017 / 22:41
7

Confirmei o erro em overlayfs (overlay2), que é o padrão no Docker para Mac. O erro acontece ao iniciar o mysql na imagem, após 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 aba "Daemon", e selecionando a aba "Avançado").

/etc/docker/daemon.json:

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

Ref:

link

link

    
por 15.11.2017 / 08:21
4

Solução alternativa

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

Descrição do problema

O problema subjacente declarado por aalexgabi é devido a a implementação dos padrões POSIX de OverlayFS :

open(2): OverlayFS only implements a subset of the POSIX standards. This can result in certain OverlayFS operations breaking POSIX standards. One such operation is the copy-up operation. Suppose that your application calls fd1=open("foo", O_RDONLY) and then fd2=open("foo", O_RDWR). In this case, your application expects fd1 and fd2 to refer to the same file. However, due to a copy-up operation that occurs after the second calling to open(2), the descriptors refer to different files. The fd1 continues to reference the file in the image (lowerdir) and the fd2 references the file in the container (upperdir). A workaround for this is to touch the files which causes the copy-up operation to happen. All subsequent open(2) operations regardless of read-only or read-write access mode will be referencing the file in the container (upperdir).

Referência:

por 18.01.2018 / 18:31
1

Isso pode não ser a solução ainda. De qualquer forma, pode apontar outros para uma resposta "adequada"

O log de sessão do docker bash mostra uma sequência de etapas que leva a erros estranhos e, finalmente, é capaz de iniciar o daemon mysql adequadamente no ambiente de encaixe.

Tentar iniciar o daemon nesta sessão falha duas vezes - uma vez devido à tabela mysql.user e uma vez devido à tabela mysql.db. Executar o daemon mysql com o --skip-grant-tables funciona, mas também há problemas com comandos select * de simples nestas 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. Eu ainda estou procurando por uma solução "adequada" para o problema e alguma pista sobre qual é a razão para esse comportamento estranho.

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

log de criação

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 da 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 ]
    
por 27.08.2017 / 10:14
0

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 do overlayFS. Isso contorna essa questão.

Esta é a solução que a imagem oficial do docker do mysql usa para lidar com isso, como você pode ver aqui: link

    
por 28.09.2018 / 23:52

Tags