Saving 'lost' MYSQL database running in Docker

I accidentally run docker-compose down instead of stop

November 11, 2019
database docker mysql

MySQL database was running in a docker container. Data was stored in a container not in any external volume. I accidentally executed docker-compose down instead of docker-compose stop and at a first glance it looked like I just wiped my database.

Because the data was not really important, I just started using fresh DB which was created by running docker-compose up.

But there is actually a way to restore the “lost” data even if new database is already being up and running.

Below are the steps to restore.

Find lost volume data

MySQL container stores data in it’s volume /var/lib/mysql.

List all dangling volumes

$ docker volume ls -qf dangling=true
0aed2cf6f3889bf49218f30707574bfd49c68f2329c33020976054ee0e81f1dc
1d130908b164e8e44f3b903930b5d128e58c2cc255be8f811d2ba877f96e6f8e
20965d328e465126d4c6421b67cbbd386a1b45c0fb653011248057b879e64fa7
41d466017c7bd375894f9f7c581f8ebde3d527b7e783b69bed812fc7bb755b8d
4d4d4ca276fa49570ef149a90126d6494637b1561aa349662f291b07e7b33b15

Find the right volume which contains the database you wish to recover. List all of them and check if you can find the database in any of them. There is a chance that you have multiple volumes with db data. Find the latest one by checking timestamps.

Remember volume ID where your db is.

Moving data

Create external volume where data will be stored.

docker volume create --name=app-db
$ docker pull busybox
$ docker run --name=helper -v app-db:/data busybox

This is just a temporary container where the data will be stored in.

Copy lost data to busybox container.

$ docker cp /var/lib/docker/volumes/41d466017c7bd375894f9f7c581f8ebde3d527b7e783b69bed812fc7bb755b8d/_data helper:/data

Check if everything is copied from volume

$ docker run --name=helper2 -v app-db:/data busybox sh
/ ls data/
app_stage           ib_logfile1         mysql
ib_logfile0         ibdata1             performance_schema

Fix docker-compose.yaml for mysql service and define it’s external volume.

Restart services

docker-compose -f docker-compose-stage.yaml down
docker-compose -f docker-compose-stage.yaml up -d

Check if mysql is running OK.

docker-compose -f docker-compose-stage.yaml logs mysql

Your database is restored.

Now even with docker-compose down, database will be fetched from external volume (unless you run docker-compose down -v. Then it will also delete external volume.

comments powered by Disqus