ข้อผิดพลาดร้ายแรง: ไม่สามารถเปิดและล็อคตารางสิทธิ์: เครื่องมือจัดเก็บตารางสำหรับ 'ผู้ใช้' ไม่มีตัวเลือกนี้


15

ข้อความแสดงข้อผิดพลาดนี้ปรากฏขึ้นเมื่อฉันใช้ ubuntu 16.04 และ mysql ล่าสุด 5.7.19-0ubuntu0.16.04.1 ในอิมเมจ Docker

จะแก้ไขอะไรได้บ้าง?

เพื่อทำซ้ำข้อผิดพลาด

  1. รับDockerfile:

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

    (มีที่นี่ด้วย )

  2. สร้างและเรียกใช้:

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

    จะแสดงบันทึกข้อผิดพลาดต่อไปนี้:

    2017-08-26T11: 48: 45.398445Z 1 [คำเตือน] root @ localhost ถูกสร้างขึ้นด้วยรหัสผ่านที่ว่างเปล่า! โปรดพิจารณาปิดตัวเลือก - เริ่มต้นที่ไม่ปลอดภัย

    ซึ่งเป็นสิ่งที่เราต้องการ: mysql ที่ยังไม่ได้ตั้งรหัสผ่านรูท

  3. ในอดีต (Ubuntu 14.04 / mysql 5.5) เป็นservice mysql startไปได้ ตอนนี้ถ้าคุณลองสิ่งนี้มันจะล้มเหลว

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

    และ/var/log/mysql/error.logมีบรรทัด:

    2017-08-26T11: 59: 57.680618Z 0 [ข้อผิดพลาด] ข้อผิดพลาดร้ายแรง: ไม่สามารถเปิดและล็อคตารางสิทธิ์: เครื่องมือจัดเก็บตารางสำหรับ 'ผู้ใช้' ไม่มีตัวเลือกนี้


สร้างบันทึก (สำหรับสมบูรณ์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

ความต่อเนื่องแปลก ๆ

หลังจากการทดลองตามที่ระบุไว้ในคำตอบของความพยายามของฉันฉันสร้างเชลล์สคริปต์ที่ทำ

select count(*)

แบบสอบถามในแต่ละตารางในพื้นที่ mysql สามครั้งในแถว (เนื่องจากการทดลองแสดงให้เห็นว่าในบางตารางแบบสอบถามจะล้มเหลวสองครั้ง :-()

จากนั้น

mysql_upgrade   

และ

service mysql restart

พยายามแล้ว ในDockerfileสคริปต์มีให้บริการผ่านทาง

COPY mysqltest.sh .

การทดลองกับสคริปต์นี้ให้ผลลัพธ์แปลก ๆ

  1. สำหรับการDocker environmentเริ่มต้นยังคงล้มเหลว

    [ข้อผิดพลาด] ข้อผิดพลาดร้ายแรง: ไม่สามารถเปิดและล็อคตารางสิทธิ์: เครื่องมือจัดเก็บตารางสำหรับ 'ผู้ใช้' ไม่มีตัวเลือกนี้

  2. เรียกใช้สคริปต์

    sh mysqltest.sh root
    

    ในสิ่งที่docker environmentนำไปสู่

    2017-08-27T09: 12: 47.021528Z 12 [ข้อผิดพลาด] / usr / sbin / mysqld: ตาราง './mysql/db' ถูกทำเครื่องหมายว่าขัดข้องและควรได้รับการซ่อมแซม
    2017-08-27T09: 12: 47.050141Z 12 [ERROR ] ไม่สามารถซ่อมแซมตาราง: mysql.db
    2017-08-27T09: 12: 47.055925Z 13 [ข้อผิดพลาด] / usr / sbin / mysqld: ตาราง './mysql/db' ถูกทำเครื่องหมายว่าขัดข้องและควรซ่อมแซม
    2017-08 -27T09: 12: 47.407700Z 54 [ข้อผิดพลาด] / usr / sbin / mysqld: ตาราง './mysql/proc' ถูกทำเครื่องหมายว่าขัดข้องและควรได้รับการซ่อมแซม
    2017-08-27T09: 12: 47.433516Z 54 [ERROR] ไม่สามารถ ' ตารางซ่อมแซม t: mysql.proc
    2017-08-27T09: 12: 47.440695Z 55 [ข้อผิดพลาด] / usr / sbin / mysqld: ตาราง './mysql/proc' ถูกทำเครื่องหมายว่าขัดข้องและควรซ่อมแซม
    2017-08-27T09: 12: 47.769485Z 81 [ข้อผิดพลาด] / usr / sbin / mysqld: ตาราง './mysql/tables_priv'ถูกทำเครื่องหมายว่าผิดพลาดและควรได้รับการซ่อมแซม
    2017-08-27T09: 12: 47.792061Z 81 [ข้อผิดพลาด] ไม่สามารถซ่อมแซมตาราง: mysql.tables_priv
    2017-08-27T09: 12: 47.798472Z 82 [ข้อผิดพลาด] / usr / sbin / mysqld: ตาราง '/mysql/ tables_priv 'ถูกทำเครื่องหมายว่าล้มเหลวและควรซ่อมแซม
    2017-08-27T09: 12: 47.893741Z 99 [ข้อผิดพลาด] / usr / sbin / mysqld: ตาราง' ./mysql/user 'ถูกทำเครื่องหมายว่าผิดพลาดและควรได้รับการซ่อมแซม
    2017-08 -27T09: 12: 47.914288Z 99 [ข้อผิดพลาด] ไม่สามารถซ่อมแซมตาราง: mysql.user
    2017-08-27T09: 12: 47.920459Z 100 [ข้อผิดพลาด] / usr / sbin / mysqld: ตาราง './mysql/user' คือ ทำเครื่องหมายว่าผิดพลาดและควรได้รับการซ่อมแซม

เกิดอะไรขึ้นที่นี่เพื่อทำให้เกิดพฤติกรรมแปลก ๆ นี้?


1
mysqld --skip-grant-tables --skip-networking ดูเหมือนว่าจะทำงาน
Wolfgang Fahl

อาจจำเป็นต้องใช้ mkdir / var / run / mysqld; chown mysql / var / run / mysqld
Wolfgang Fahl

1
--skip-networking จะปิดการเชื่อมต่อ TCP / IP ใด ๆ ที่คุณอาจต้องการทำกับเซิร์ฟเวอร์ดังนั้นบางครั้งสิ่งนี้ก็ไม่ดี mariadb.com/kb/en/server-system-variables/#skip_networking
Darko Maksimovic

@DarkoMaksimovic ดูคำตอบที่ยอมรับสำหรับการตั้งค่าความเป็นเจ้าของที่จะเป็นทางออก
Wolfgang Fahl

จริง ๆ แล้วฉันได้ลองแล้วและมันก็ไม่ได้เปลี่ยนแปลงอะไรในกรณีของฉัน (MySQL 5.7 บน MacOS, Docker 2.1.0.5) เฉพาะ --skip-Grant-tables ช่วยเริ่มต้นเซิร์ฟเวอร์แม้ว่ามีบางคนในหัวข้อนี้บ่นเกี่ยวกับการเลือกเพิ่มเติม แต่ฉันจะเห็นเมื่อมันเกิดขึ้นกับฉัน
Darko Maksimovic

คำตอบ:


30

วิ่งเข้าไปในปัญหาเดียวกันวันนี้ ฉันใช้บริการ MySQL ในระหว่างการสร้างนักเทียบท่าสำหรับการทดสอบหน่วยและอัปเกรดเป็น MySQL CE 5.7.19 จาก MariaDB ทำให้โครงสร้างขาด สิ่งที่แก้ปัญหาสำหรับฉันคือการทำงานchown -R mysql:mysql /var/lib/mysql /var/run/mysqldทุกครั้งก่อนเริ่มบริการ mysql

ดังนั้น Dockerfile ของฉันจะเป็นดังนี้:

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

หวังว่านี่จะช่วยได้


2
ปัญหาเดียวกันที่นี่ ฉันทำงานบิลด์แบบสองขั้นตอนและ Dockerfile "parent" รันchmodคำสั่งนี้แล้ว การสร้างสำเร็จเมื่อฉันเรียกใช้บนเซิร์ฟเวอร์ Ubuntu ระยะไกล แต่ล้มเหลวเมื่อฉันเรียกใช้บนเครื่องท้องถิ่น (OS X) การเพิ่มchmodคำสั่งให้กับชายด์ Dockerfile แก้ไขปัญหาได้ แปลก
senderle

2
ขอขอบคุณ! ฉันรู้ว่ามีคนอื่นที่นั่นต้องมีกรณีการใช้ที่คล้ายกันเป็นของฉันเอง
ตกลง

2
@senderle เพิ่งพบกระทู้นี้เช่นกัน "สร้างครั้งเดียวนำไปใช้งานได้ทุกที่" พวกเขากล่าว
duhaime

9

วิธีแก้ปัญหา

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

คำอธิบายปัญหา

ปัญหาพื้นฐานตามที่ระบุโดยaalexgabiเกิดจากการนำมาตรฐาน POSIX ของ OverlayFS มาใช้ :

open (2): OverlayFS ใช้ชุดย่อยของมาตรฐาน POSIX เท่านั้น ซึ่งอาจส่งผลให้การดำเนินการ OverlayFS บางอย่างผิดปกติ POSIX มาตรฐาน หนึ่งในการดำเนินการดังกล่าวคือการดำเนินการคัดลอก สมมติว่าโปรแกรมที่คุณเรียกร้องแล้วfd1=open("foo", O_RDONLY) fd2=open("foo", O_RDWR)ในกรณีนี้แอปพลิเคชันของคุณคาดว่า fd1 และ fd2 จะอ้างถึงไฟล์เดียวกัน อย่างไรก็ตามเนื่องจากการดำเนินการคัดลอกที่เกิดขึ้นหลังจากการเรียกครั้งที่สองopen(2) descriptors อ้างถึงไฟล์ต่าง ๆ fd1 ยังคงอ้างอิงไฟล์ในรูปภาพ (lowerdir) และ fd2 อ้างอิงไฟล์ในคอนเทนเนอร์ (upperdir) วิธีหลีกเลี่ยงปัญหานี้คือการสัมผัสไฟล์ที่ทำให้การคัดลอกเกิดขึ้น open(2)การดำเนินการที่ตามมาทั้งหมดไม่ว่าโหมดการเข้าถึงแบบอ่านอย่างเดียวหรืออ่านอย่างเดียวจะเป็นการอ้างอิงไฟล์ในคอนเทนเนอร์ (Upperdir)

อ้างอิง:


1
นี่เป็นข่าวที่น่ากลัว ฉันสงสัยว่าทำไมนักเทียบท่าไม่ได้รับการแก้ไข
Wolfgang Fahl

2
สุจริต? ฉันก็ไม่เหมือนกัน! ฉันหมายความว่าสิ่งนี้จะมีผลกับแอปพลิเคชั่นจำนวนมากเพราะเป็นการดำเนินการกับไฟล์ขั้นพื้นฐานจริงๆ แน่นอนปัญหาเกิดขึ้นภายใต้เงื่อนไขบางอย่าง แต่พวกเขาไม่ได้ออกไปที่ไกล ...
Murmel

8

ฉันยืนยันข้อผิดพลาดเกี่ยวกับโอเวอร์เลย์ (โอเวอร์เลย์ 2) ที่เป็นค่าเริ่มต้นบน Docker สำหรับ Mac ข้อผิดพลาดเกิดขึ้นเมื่อเริ่ม mysql บนภาพหลังจากสร้างภาพด้วย 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

การเปลี่ยนเป็น "aufs" แก้ปัญหาได้ (บน Docker สำหรับ Mac สามารถแก้ไข "daemon.json" ได้โดยเลือกเมนู "Preferences ... " และเลือกแท็บ "Daemon" และเลือกแท็บ "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


1
วิธีนี้แก้ไขปัญหาของฉันใน Ubuntu 16:04 ฉันได้กำหนดค่าก่อนหน้านี้ไดรเวอร์การจัดเก็บข้อมูลแบบ overlay2 ในนักเทียบท่า ขอบคุณ
Havok

1
สิ่งนี้ทำให้นักเทียบท่าไม่สามารถรีสตาร์ทบน OSX :(
duhaime

2

นี่คือคำตอบที่ฉันยังไม่เห็นที่นี่

เพิ่มไปยังไฟล์ dockerfile ของคุณ: VOLUME /var/lib/mysql

สิ่งนี้จะทำให้โฟลเดอร์ / var / lib / mysql ใช้ระบบไฟล์เนทีฟแทน overlayFS สิ่งนี้หลีกเลี่ยงปัญหานี้

นี่เป็นวิธีการแก้ภาพที่นักเทียบท่า mysql อย่างเป็นทางการใช้เพื่อจัดการกับสิ่งนี้ตามที่คุณเห็นที่นี่: https://github.com/docker-library/mysql/blob/9d1f62552b5dcf25d3102f14eb82b579ce9f4a26/5.7/Dockerfile


1

นี่อาจยังไม่เป็นทางออก อย่างไรก็ตามมันอาจชี้ให้คนอื่นเห็นคำตอบที่ "เหมาะสม"

บันทึกเซสชั่นทุบตี basher ด้านล่างแสดงลำดับขั้นตอนที่นำไปสู่ข้อผิดพลาดที่แปลกและในที่สุดก็สามารถเริ่ม mysql daemon ได้อย่างถูกต้องในสภาพแวดล้อมของนักเทียบท่า

การพยายามสตาร์ท daemon ในเซสชันนี้ล้มเหลวสองครั้ง - หนึ่งครั้งเนื่องจากตาราง mysql.user และอีกครั้งเนื่องจากตาราง mysql.db การเรียกใช้ mysql daemon ด้วย --skip-grant-tables ทำงานได้ แต่ยังมีปัญหากับการเลือก * จากคำสั่งบนตารางเหล่านี้

ทำแบบสอบถามง่ายๆสองอย่างที่น่าประหลาดใจ:

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

จากนั้นฆ่า daemon เพื่อเริ่มต้นอย่างถูกต้องด้วย

service mysql start

ดูเหมือนว่าจะทำงาน ตอนนี้ฉันจะพยายามทำให้สิ่งนี้เป็นวิธีแก้ปัญหาโดยอัตโนมัติ ฉันยังคงมองหาวิธีการแก้ปัญหาที่ "ถูกต้อง" และยังมีเงื่อนงำว่าอะไรคือสาเหตุของพฤติกรรมแปลก ๆ นี้

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 info@bitplan.com

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

สร้างบันทึก

docker build .

Sending build context to Docker daemon  8.704kB
Step 1/5 : FROM ubuntu:16.04
 ---> ebcd9d4fca80
Step 2/5 : MAINTAINER Wolfgang Fahl info@bitplan.com
 ---> 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

ทุบตีบันทึกเซสชั่น

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 ]

ดูไฟล์นักเทียบท่าเดิมgithub.com/docker-library/mysql/blob/...และ entrypoint.sh github.com/docker-library/mysql/blob/... พวกเขาจะทำให้คุณมีความคิดว่าต้องทำอะไร
Tarun Lalwani

ขอบคุณสำหรับคำใบ้ การทดลองเพิ่มเติมของฉันแสดงให้เห็นว่าการเปิดตัวซีรีส์ 5.7.x นั้นทำงานแตกต่างกันไปตาม x มากถึง 5.7.14 สิ่งที่ดูเหมือนจะง่ายขึ้น severalnines.com/blog/...วิธีการทำงานในสภาพแวดล้อมลินุกซ์ของฉัน ในสภาพแวดล้อม Mac OS ของฉันสิ่งที่ยากขึ้น
Wolfgang Fahl
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.