Kesalahan fatal: Tidak bisa membuka dan mengunci tabel hak istimewa: Mesin penyimpanan tabel untuk 'pengguna' tidak memiliki opsi ini

15

Pesan kesalahan ini muncul ketika saya menggunakan ubuntu 16.04 dan mysql 5.7.19-0ubuntu0.16.04.1 terbaru dalam gambar Docker.

Apa yang bisa dilakukan untuk memperbaikinya?

Untuk mereproduksi kesalahan

  1. Dapatkan Dockerfile:

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

    (juga tersedia di sini )

  2. Bangun dan jalankan:

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

    akan ditampilkan log kesalahan berikut:

    2017-08-26T11: 48: 45.398445Z 1 [Peringatan] root @ localhost dibuat dengan kata sandi kosong! Silakan pertimbangkan mematikan opsi --initialize-insecure.

    Yang persis seperti yang kami inginkan: mysql tanpa kata sandi root yang ditetapkan.

  3. Di masa lalu (ubuntu 14.04 / mysql 5.5) a service mysql startdimungkinkan. Sekarang jika Anda mencoba ini gagal

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

    dan /var/log/mysql/error.logmengandung garis:

    2017-08-26T11: 59: 57.680618Z 0 [GALAT] Kesalahan fatal: Tidak dapat membuka dan mengunci tabel privilege: Mesin penyimpanan tabel untuk 'pengguna' tidak memiliki opsi ini


build log (untuk lengkap 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

kelanjutan yang aneh

Setelah percobaan sebagaimana diuraikan dalam upaya jawaban saya , saya membuat skrip shell yang melakukan a

select count(*)

kueri pada setiap tabel dalam ruang mysql tiga kali berturut-turut (karena percobaan menunjukkan bahwa pada beberapa tabel kueri akan gagal tepat dua kali :-().

Lalu a

mysql_upgrade   

dan

service mysql restart

sudah dicoba. Dalam Dockerfileskrip tersedia melalui

COPY mysqltest.sh .

Uji coba dengan skrip ini memberikan hasil yang aneh / gila.

  1. Untuk Docker environmentawal masih gagal

    [GALAT] Kesalahan fatal: Tidak bisa membuka dan mengunci tabel hak istimewa: Mesin penyimpanan tabel untuk 'pengguna' tidak memiliki opsi ini

  2. Menjalankan skrip

    sh mysqltest.sh root
    

    dalam docker environmentmengarah ke

    2017-08-27T09: 12: 47.021528Z 12 [ERROR] / usr / sbin / mysqld: Table './mysql/db' ditandai sebagai
    macet dan harus diperbaiki 2017-08-27T09: 12: 47.050141Z 12 [KESALAHAN ] Tidak dapat memperbaiki tabel: mysql.db
    2017-08-27T09: 12: 47.055925Z 13 [KESALAHAN] / usr / sbin / mysqld: Tabel './mysql/db' ditandai sebagai
    macet dan harus diperbaiki 2017-08 -27T09: 12: 47.407700Z 54 [GALAT] / usr / sbin / mysqld: Tabel './mysql/proc' ditandai sebagai
    macet dan harus diperbaiki 2017-08-27T09: 12: 47.433516Z 54 [GALAT] Tidak bisa ' t meja perbaikan: mysql.proc
    2017-08-27T09: 12: 47.440695Z 55 [KESALAHAN] / usr / sbin / mysqld: Tabel './mysql/proc' ditandai sebagai
    macet dan harus diperbaiki 2017-08-27T09: 12: 47.769485Z 81 [GALAT] / usr / sbin / mysqld: Table './mysql/tables_priv'ditandai sebagai macet dan harus diperbaiki
    2017-08-27T09: 12: 47.792061Z 81 [GALAT] Tidak dapat memperbaiki tabel: mysql.tables_priv
    2017-08-27T09: 12: 47.798472Z 82 [GALAT] / usr / sbin / mysqld: Table './mysql/ tables_priv 'ditandai sebagai macet dan harus diperbaiki
    2017-08-27T09: 12: 47.893741Z 99 [GALAT] / usr / sbin / mysqld: Table' ./mysql/user 'ditandai sebagai
    macet dan harus diperbaiki 2017-08 -27T09: 12: 47.914288Z 99 [GALAT] Tidak dapat memperbaiki tabel: mysql.user
    2017-08-27T09: 12: 47.920459Z 100 [KESALAHAN] / usr / sbin / mysqld: Table './mysql/user' is ditandai sebagai macet dan harus diperbaiki

Apa yang terjadi di sini yang menyebabkan perilaku aneh ini?

Wolfgang Fahl
sumber
1
mysqld --skip-grant-tables --skip-networking tampaknya berfungsi
Wolfgang Fahl
mkdir / var / run / mysqld; chown mysql / var / run / mysqld mungkin juga dibutuhkan.
Wolfgang Fahl

Jawaban:

30

Berlari ke masalah yang sama hari ini. Saya menjalankan layanan MySQL selama pembuatan docker untuk unit test dan meningkatkan ke MySQL CE 5.7.19 dari MariaDB yang rusak. Apa yang memecahkan masalah bagi saya berjalan chown -R mysql:mysql /var/lib/mysql /var/run/mysqldsetiap kali sebelum memulai layanan mysql.

Jadi Dockerfile saya terlihat seperti ini sekarang:

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

Semoga ini membantu.

Tibor Gyuris
sumber
2
Masalah yang sama disini. Saya memiliki build dua tahap, dan Dockerfile "induk" sudah menjalankan chmodperintah ini . Build berhasil ketika saya menjalankannya di server Ubuntu jauh, tetapi gagal ketika saya menjalankannya di mesin lokal saya (OS X). Menambahkan chmodperintah ke Dockerfile anak memperbaiki masalah. Aneh .
pengirim
2
Terima kasih! Saya tahu orang lain di luar sana harus memiliki kasus penggunaan yang serupa dengan kasus saya.
threed
2
@senderle baru saja menemukan utas ini. "Bangun sekali, sebarkan di mana saja" kata mereka
duhaime
8

Saya mengkonfirmasi kesalahan pada overlayfs (overlay2) yang merupakan default pada Docker untuk Mac. Kesalahan terjadi ketika memulai mysql pada gambar, setelah membuat gambar dengan 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

Beralih ke "aufs" memecahkan masalah. (Pada Docker untuk Mac, "daemon.json" dapat diedit dengan memilih menu "Preferences ...", dan memilih tab "Daemon", dan memilih tab "Advanced".)

/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
sumber
1
Ini menyelesaikan masalah saya di Ubuntu 16:04. Saya telah mengkonfigurasi sebelumnya driver penyimpanan overlay2 di buruh pelabuhan. Terima kasih.
Havok
Hal ini mencegah buruh pelabuhan untuk tidak memulai kembali di OSX :(
duhaime
8

Penanganan masalah

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

Deskripsi masalah

Masalah mendasar seperti yang dinyatakan oleh aalexgabi adalah karena penerapan standar POSIX dari OverlayFS :

open (2): OverlayFS hanya mengimplementasikan subset dari standar POSIX. Ini dapat mengakibatkan operasi OverlayFS tertentu melanggar standar POSIX. Salah satu operasi tersebut adalah operasi copy-up. Misalkan aplikasi Anda memanggil fd1=open("foo", O_RDONLY)lalu fd2=open("foo", O_RDWR). Dalam hal ini, aplikasi Anda mengharapkan fd1 dan fd2 untuk merujuk ke file yang sama. Namun, karena operasi penyalinan yang terjadi setelah panggilan kedua ke open(2), deskriptor merujuk ke file yang berbeda. The fd1 terus merujuk file dalam gambar (lowerdir) dan fd2 referensi file dalam wadah (upperdir). Solusi untuk ini adalah dengan menyentuh file yang menyebabkan operasi copy-up terjadi. Semua open(2)operasi selanjutnya terlepas dari mode akses baca-saja atau baca-tulis akan mereferensikan file dalam wadah (upperdir).

Referensi:

Murmel
sumber
1
Ini berita buruk. Saya bertanya-tanya mengapa buruh pelabuhan tidak diperbaiki.
Wolfgang Fahl
2
Secara jujur? Aku juga tidak! Maksud saya ini harus mempengaruhi banyak aplikasi, karena ini benar-benar operasi file dasar. Tentu saja masalahnya hanya terjadi dalam kondisi tertentu, tetapi mereka tidak terlalu jauh ...
Murmel
2

Inilah jawaban yang belum saya lihat di sini.

Tambahkan ini ke dockerfile Anda: VOLUME /var/lib/mysql

Ini akan menyebabkan folder / var / lib / mysql menggunakan sistem file asli daripada overlayFS. Ini menghindari masalah ini.

Ini adalah solusi yang digunakan gambar pekerja pelabuhan mysql resmi untuk menangani hal ini seperti yang Anda lihat di sini: https://github.com/docker-library/mysql/blob/9d1f62552b5dcf25d3102f14eb82b579ce9f4a26/5.7/Dockerfile

Paul Dejean
sumber
1

Ini mungkin belum menjadi solusinya. Bagaimanapun itu mungkin mengarahkan orang lain ke jawaban "tepat"

Log sesi docker bash di bawah ini menunjukkan urutan langkah-langkah yang menyebabkan kesalahan aneh dan akhirnya dapat memulai daemon mysql dengan benar di lingkungan buruh pelabuhan.

Mencoba memulai daemon di sesi ini gagal dua kali - sekali karena tabel mysql.user dan sekali karena tabel mysql.db. Menjalankan daemon mysql dengan --skip-grant-tables berfungsi tetapi ada juga masalah dengan * pilih sederhana dari perintah pada tabel ini.

Anehnya melakukan dua pertanyaan sederhana:

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

dan kemudian membunuh daemon untuk memulainya dengan benar

service mysql start

sepertinya berhasil. Sekarang saya akan mencoba mengotomatiskan ini sebagai solusinya. Saya masih mencari solusi yang "tepat" untuk masalah dan beberapa petunjuk apa alasan untuk perilaku aneh ini.

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

buat 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 sesi 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
sumber
Lihatlah file buruh pelabuhan asli github.com/docker-library/mysql/blob/… dan entrypoint.sh github.com/docker-library/mysql/blob/… . Mereka akan memberi Anda gambaran tentang apa yang perlu dilakukan.
Tarun Lalwani
Terima kasih atas petunjuknya. Eksperimen lebih lanjut saya menunjukkan bahwa seri 5.7.x rilis berperilaku berbeda tergantung pada x. Hingga 5.7.14 hal tampaknya lebih sederhana. The severalnines.com/blog/... Pendekatan bekerja di lingkungan linux saya. Di lingkungan Mac OS saya, berbagai hal lebih sulit.
Wolfgang Fahl