66

I just upgraded to Docker Desktop 2.4 on MacOS, from version 2.3. Suddenly none of my mysql containers will start. The logs show this as the reason:

Different lower_case_table_names settings for server ('2') and data dictionary ('0').
Data Dictionary initialization failed.
Aborting

The database files are mounted in a volume on my host machine, so that they persist between restarts.

I finally figured out why. Posting in order to answer.

Cully
  • 6,427
  • 4
  • 36
  • 58

6 Answers6

122

With the latest docker you can disable the gRPC Fuse for file sharing. (the gRPC Fuse setting is causing this problem, it's incompatible with the data dictionary of 0)

screenshot docker

This fixes the problem... You can stop here if you're happy, but to use the new filesystem you can:

  • Disable this checkbox
  • Start the container
  • Dump the database
  • Enable this checkbox
  • Make sure your data folder empty (so mysql creates a new data dictionary)
  • Import the dumped database

UPDATE

Since version 2.5, the setting has been moved to the 'experimental features' page:

enter image description here

gamecreature
  • 3,232
  • 3
  • 20
  • 18
  • 1
    Doesn't work in my case :( Still can't persist the /var/lib/mysql/ as volume. As soon as I copy this folder from the container to my local project and restart the container (docker-compose up) mysql service fails to start – FullStack Alex Oct 02 '20 at 20:51
  • Worked for me too, thanks! My experience with docker so far has been quite mixed. – Ars Oct 05 '20 at 04:06
  • Or if your database is disposable/in a dev project, simply skip to step 5 and start over :-) – Robin van Baalen Oct 11 '20 at 16:58
  • Thanks! Worked with Docker Desktop 2.5.0.1 on macOS 10.14.6 Mojave and mysql 8.0.13 – AbstractVoid Dec 29 '20 at 16:43
  • Thanks for this you good human! This caught me off guard today at a very bad time, irritating stuff. Really appreciate this find it was beginning to manifest as a bad headache. – kmjb Jan 27 '21 at 19:40
  • 3
    I can't see the gRPC option in Windows Docker Desktop 4.2.0. – huang Nov 17 '21 at 05:49
  • For some reason it is not getting unchecked when pressed save and restart button. Weird. macOS 12.5.1 and docker desktop 4.12.0 (85629) – HumaN Sep 18 '22 at 03:13
  • Thanks! it solved my problem. you can find this option on Docker desktop 4.15 :: - Preferences -> General -> Choose file sharing implementation for your container. - you should choose osxfs( Legacy) – Shane Park Jan 07 '23 at 03:39
23

The lower_case_table_names setting tells mysql how to store and compare table names. If the file system the database is stored on is itself not case-sensitive, it will force you to use lower_case_table_names=2.

The MacOS filesystem is not case-sensitive. Up until Docker Desktop 2.4, the mysql container apparently didn't know that the underlying filesystem is not case-sensitive and set lower_case_table_names=0. However, since upgrading to Docker 2.4, Docker is apparently smarter about how it mounts volumes. So the container realizes its running on a case-insensitive filesystem and forces lower_case_table_names=2. The problem is that you cannot change the value of lower_case_table_names after initializing the database. And since the data dictionary was initialized with lower_case_table_names=0, it will fail to initialize with the server set to lower_case_table_names=2.

The only solution I've found is to:

  1. Downgrade to Docker Desktop 2.3
  2. Backup the entire database
  3. Upgrade to Docker 2.4
  4. Delete the volume storing the database.
  5. Reinitialize the database.
  6. Restore the database from backup.

UPDATE: See this answer below for a better solution. There is apparently no need to downgrade. You can instead disable "gRPC Fuse for filesharing", backup the database, re-enable gRPC fuse, delete your database data folder, and restore the database from backup.

Cully
  • 6,427
  • 4
  • 36
  • 58
4

Another option is to create a case sensitive APFS volume using Disk Utility.

Add APFS to container Shows storage between APFS volumes are shared

Unlike a partition, it is possible to share the free space, so you don't need to worry about reserving enough space to run your database.

Then create a symlink from your project to your case sensitive volume.

cd ~/my-project
ln -s /Volumes/MySQL/project-db mysql
Harry King
  • 502
  • 4
  • 15
  • 2
    This was an easy fix for MacOS thanks man. – Aftab Naveed Apr 16 '22 at 08:33
  • Best, worked for MacOS. I had to delete and loss data in last iteration for similar issue. Thought it was due to mysql version change. But this time kept same version container but still it same issue. Not this method helped. Thanks – HumaN Sep 18 '22 at 03:11
2

Docker removed this option on the recent updates , i manage to solve this issue on windows by doing this

Run a shell as administrator:

go to your local mounted mysql volume and run

fsutil file setCaseSensitiveInfo ./ enable 

credits to https://github.com/docker/for-win/issues/12384#issuecomment-972845031

Loic H
  • 328
  • 4
  • 12
  • Could you update your answer and include some details about what the command does, how it solves the problem? – Cully Dec 29 '21 at 18:45
1

A small addition to Loic's H answer. Suppose your mapping is something like this:

docker run --name your_container_name ... -v //d/MySqlDockerData:/var/lib/mysql ...

if your try

fsutil file setCaseSensitiveInfo d:\MySqlDockerData

you will get an error "The directory is not empty"

To get around this follow these steps:

  1. run docker container stop your_container_name
  2. transfer the contents of the folder to the another place (clear the folder)
  3. run again fsutil file setCaseSensitiveInfo d:\MySqlDockerData
  4. transfer back saved data to the d:\MySqlDockerData
  5. run docker container start your_container_name

voila

Alexander
  • 11
  • 2
  • 1
    The original question was related to macOS, but it looks like you're on Windows. Are you seeing this same issue on Windows as well? – Cully Jul 06 '22 at 17:00
  • Cully, quite so and I reffered on the Loic H answer concerning Windows specifically – Alexander Jul 07 '22 at 07:04
  • I'm curious, do you know how you were able to get case-insensitive volume mounted on Windows in the first place (the thing that caused the problem)? – Cully Jul 07 '22 at 16:51
  • As far as I know, prior to WSL2 it was common practice to map a Windows folder. Today it is recommended to use Linux folders for mapping to improve performance. But you can still map to a regular Windows folder, which has the attribute case-insensitive by default - the same problem as you perfectly described in your answer. – Alexander Jul 08 '22 at 12:24
  • Ah! I didn't realize Windows file systems were also case-insensitive. That's good to know. Thanks! – Cully Jul 08 '22 at 15:49
0

As workaround on Windows OS I disabled WSL in Docker Desktop and it helped me

Update. After last Docker Desktop Updates I was forced to set Windows directory with DB data as case sensitive

AID
  • 124
  • 5
  • This shouldn't be an issue in Windows since it uses a case-sensitive filesystem. I think you may be running into another problem. – Cully Aug 17 '21 at 17:20
  • Can you confirm you're getting the same message in your logs (the message shown in the question)? – Cully Aug 19 '21 at 20:55
  • Yes, first notice is ```Setting lower_case_table_names=2 because file system for /var/lib/mysql/ is case insensitive``` then ```InnoDB initialization has ended. Different lower_case_table_names settings for server ('2') and data dictionary ('0'). Data Dictionary initialization failed.``` – AID Aug 20 '21 at 09:06
  • Do you have it mounted on a case-insensitive filesystem? – Cully Aug 20 '21 at 18:41
  • I simply specified `./docker/dbdata:/var/lib/mysql` in volumes in my docker-compose.yml, where `docker/dbdata` is my Windows directory (NTFS) – AID Aug 23 '21 at 09:33