Foreword

Data backup has always been the most important thing in website operation and maintenance. Everyone knows the value of data!

Data backup usually includes: file backup and database backup.

Below, we will mainly discuss the more frequent `database backups>, compare the difference between its traditional backup method and the modern [Docker] (https://zhouzhipeng.com/category/docker) backup method, and bring you experience in the container. Times, the new "trend" data backup method!

Traditional database backup method

Take the relational database mysql as an example, aside from its master-slave architecture and cold standby, in general, if you need to manually back up data with commands, you can use the following command:

Mysqldump -h your_mysql_host -P your_mysql_port -uuser -p db_name > db_name_`date +%Y%m%d`.sql

The direct use of mysql comes with the command mysqldump, which looks pretty good. This way is a bit flawed:

When the amount of data is large, dump generates SQL will be slower, after all, requires a certain logical operation

(Of course, you definitely have a better backup method than mysqldump, here is not extended, it is compared with the following:)

Of course, there is a backup to restore, and the backup method corresponding to the above backup method is also very easy:

Mysql -u root -h your_mysql_host -P your_mysql_port -p db_name < db_name_20180212.sql

Seemingly good, the only minor flaw is:

The restored database db_name needs to be created in advance

(Of course, you may have a more elegant way of not creating db_name in advance, here is not to extend, focus on comparison with the following:)

Docker Volume backup method

Ok, finally you have to get to the point!

![](https://zhouzhipeng.com/wp-content/uploads/2018/02/cute docker.png)

I believe that everyone will not be familiar with this cute cartoon logo above. If you don’t know what ‘Docker` is, you can read my other article: [Introduction to the world of docker] (https: //zhouzhipeng.com/walk-in-docker-beginning.html)

Prerequisite knowledge

  1. Docker Volume data volume: [official documentation] (https://docs.docker.com/storage/volumes/)
  2. Docker Registry repository: [Docker Private Warehouse Build] (https://zhouzhipeng.com/install-docker-private-registry.html)

The premise of the following operations is:

Your database is running as a Docker container!

In order to make a sharp contrast with the traditional model, we also run a mysql container.

Creating a data volume

Before running the container, use docker volume create to create a data volume for mounting the mapped mysql container data file:

[root@localhost ~]# docker volume create mysql_data
Mysql_data

Use the docker volume inspect command to see the details of the mysql_data data volume you just created:

[root@localhost ~]# docker volume inspect mysql_data
[
    {
        "CreatedAt": "2018-02-12T09:14:45+08:00",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/mysql_data/_data",
        "Name": "mysql_data",
        "Options": {},
        "Scope": "local"
    }
]

Everyone noticed this line "Mountpoint": "/var/lib/docker/volumes/mysql_data/_data"`

This is the directory path of the data volume mysql_data on the host machine. Let’s take a look at cd:

[root@localhost ~]# cd /var/lib/docker/volumes/mysql_data/_data
[root@localhost _data]# ls
[root@localhost _data]# pwd
/var/lib/docker/volumes/mysql_data/_data
[root@localhost _data]#

Yes, it is empty now! Because there is no container to mount it.

Running the mysql container

The mysql version uses the more popular 5.x series, using docker run to run the mysql container:

[root@localhost _data]# docker run -d --name mysql5.7 -e MYSQL_ROOT_PASSWORD=123456 -p 3307:3306 -v mysql_data:/var/lib/mysql mysql:5.7
7e971e3a80c8b3235230417a76387a61ad86c7de68fa6086bde3cbd8f162691a

Note the -v mysql_data:/var/lib/mysql in the above command, which will mount the data volume mysql_data we created earlier to the /var/lib/mysql directory inside the mysql container. (Refer to [docker hub mysql] ( https://hub.docker.com/_/mysql/))

First, first check if the mysql container just created is normal or not, use the docker exec command to connect to the mysql server:

[root@localhost ~]# docker exec -it mysql5.7 mysql -uroot -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.7.20 MySQL Community Server (GPL)

Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
Others may be trademarks of their respective
Owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

Mysql>

Connect ok, then create a table and make some data:

Mysql> use mysql;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
Mysql> create table person(name varchar(100),age int);
Query OK, 0 rows affected (0.33 sec)

Mysql> insert into person(name,age) values('zhouzhipeng.com',18);
Query OK, 1 row affected (0.02 sec)

Mysql> select * from person;
+-----------------+------+
| name | age |
+-----------------+------+
| zhouzhipeng.com | 18 |
+-----------------+------+
1 row in set (0.00 sec)

Mysql>

So far, the data is ready for ok. Next, we will back up the mysql database and restore our data on another machine!

Guest, please go down!

backup database

With the data volume mysql_data, the rest of the things become extremely simple, at this point, no longer care about what type of database, mysql? postgresql? ….

Database types are not important! With the docker data volume, we only care about file!

A very simple backup method, package the mysql_data directory and upload it to ftp or docker repository (we choose the latter).

# 0. Stop mysql5.7 first (optional)
Docker stop mysql5.7

# 1. Mount the mysql_data data volume to another container (alpine image)
# The following command only needs to be executed once. To prevent the container from being terminated after startup (the alpine entry command is sh), use the entry command ping 127.0.0.1 to keep it running in the background.
Docker run -d --name mysql-backup -v mysql_data:/volume alpine ping 127.0.0.1

        
# 2. On the mysql-backup container created above, use the tar command to package the directory.
Docker exec -it mysql-backup tar -cjf /mysql_data.tar.bz2 -C /volume ./

# 3. Can go to the container check whether the file has
[root@localhost ~]# docker exec -it mysql-backup sh
/ # ls -lh mysql_data.tar.bz2
-rw-r--r-- 1 root root 5.2M Feb 12 02:39 mysql_data.tar.bz2

# ok, everything is normal

Is this finished? No!

Be aware that if the data backup is placed locally, it is still unsafe. We need to transfer it to our warehouse for inventory, easy to archive, and easy to migrate!

Here we use the docker’s docker registry for the whole family bucket. The construction of the docker repository can be referenced:

 [Docker Private Warehouse Building] (https://zhouzhipeng.com/install-docker-private-registry.html)

Because I am poor (no money to buy a server to do docker warehouse), so here is a convenient free use of a cloud free docker warehouse.

Backup upload to docker warehouse

Remember the previous alpine container created for a tar package?

docker run -d --name mysql-backup -v mysql_data:/volume alpine ping 127.0.0.1

(Do you think that in order to package a catalog, it takes so much effort to run a container to do it?)

docker turns everything, including your data!

# 1. Submit the container change to the new image (just like you use git)
[root@localhost ~]# docker commit -m "My mysql data backup" mysql-backup registry.cn-shanghai.aliyuncs.com/zhouzhipeng/mysql-backup:20180212
Sha256:263c779bc7ff489e8a5c01bd95d0901e98f3f7c29b2f2ff51388be36983e593d

# 2. Push the image to the repository (just like you use git)
[root@localhost ~]# docker push registry.cn-shanghai.aliyuncs.com/zhouzhipeng/mysql-backup:20180212
The push refers to a repository [registry.cn-shanghai.aliyuncs.com/zhouzhipeng/mysql-backup]
Fe0aee4fcfed: Pushed
5bef08742407: Pushed
20180212: digest: sha256: a1cc7fb06b11baf6376be550620e60fb2dcc29abf154ffd4564487a09c56d8d7 size: 739
[root@localhost ~]#

# 3. Complete

Ok, finally, our data is considered "safe"!

Next, let’s change a database to demonstrate how to restore the database!

Restore the database

It used to be that you and O&M exchanged the details of the database in this way:

You: Can you help me restore the postgres database of the xxx business?

Uncle Yunwei: What? Is postgres a database? I have never used it, the order will not knock!

You: Amount. . .

(End: You spent hours working with Uncle Yunwei to complete the restoration!)

(Operational maintenance does not make certain database commands normal, but he will not be surprised by the docker command!)

The place that really shows the power of docker may be here! Finally, you can say aloud to Yunwei’s uncle.

You: Can you help me restore the xxx database of the xxx business? I sent your message to the image name.

Uncle Operation: Good

After a minute…..

Uncle Operation: all done!

I don’t say anything, let’s do it:

# 1. In order to test the effect, I changed a machine
# 2. Create a data volume
[zhipeng.zhou@instance-2 ~]$ docker volume create mysql_data
Mysql_data

# 3. Use the data mirror in front of the registration: registry.cn-shanghai.aliyuncs.com/zhouzhipeng/mysql-backup:20180212
Docker run --rm -v mysql_data:/volume registry.cn-shanghai.aliyuncs.com/zhouzhipeng/mysql-backup:20180212 sh -c "rm -rf /volume/* /volume/..?* /volume/. [!.]* ; tar -C /volume/ -xjf /mysql_data.tar.bz2 ;"

## Simply explain the above command: Here, mount the backup image created in the previous directory to the mysql_data data volume directory, and use the tar command to decompress the previously prepared tarball.

# 4. Check whether the file is normal (mysql_data data volume directory)
[zhipeng.zhou@instance-2 ~]$ sudo ls /var/lib/docker/volumes/mysql_data/_data
Auto.cnf client-cert.pem ibdata1 ibtmp1 private_key.pem server-key.pem
Ca-key.pem client-key.pem ib_logfile0 mysql public_key.pem sys
Ca.pem ib_buffer_pool ib_logfile1 performance_schema server-cert.pem

# 5. Run mysql
[zhipeng.zhou@instance-2 ~]$ docker run -d --name mysql5.7 -e MYSQL_ROOT_PASSWORD=123456 -p 3307:3306 -v mysql_data:/var/lib/mysql mysql:5.7

# 6. Connection test
[zhipeng.zhou@instance-2 ~]$ docker exec -it mysql5.7 mysql -uroot -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.21 MySQL Community Server (GPL)

Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
Others may be trademarks of their respective
Owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

Mysql> use mysql;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
Mysql> select * from person;
+-----------------+------+
| name | age |
+-----------------+------+
| zhouzhipeng.com | 18 |
+-----------------+------+
1 row in set (0.00 sec)

Mysql>

# 7. all done

to sum up

The whole process above is the actual operation of the person. It is just a matter of throwing bricks and jade. Some details may not be considered well. Please forgive me.

After carefully understanding the whole process, you will find that when everything is around docker, we don’t have to care about ftp file services, database types, database command features, and other details. . .

The era of containerization has indeed come, stateful database containers, stateless application containers, competing in the world of docker! You can keep the traditional operation mode and operation and maintenance mode, but please do not reject any ultimate belief that can enhance productivity and liberate your hands!

Last modified: 2019年3月29日

Author

Comments

想咨询下,为什么不直接将/var/lib/docker/volumes/mysql_data/_data目录打包,然后定期上传?
是因为这种方式备份的数据mysql无法识别,还是因为需要通过mysql备份镜像来上传数据到阿里云?

    Author
    zhouzhipeng 

    一般不建议直接访问/var/lib/docker/volumes/mysql_data/_data 这个目录,考虑到docker跨平台兼容性,比如在mac和windows上是没有直接/var/lib/docker这个目录的,它在虚拟机内部。使用volume可以规避这一点。

Write a Reply or Comment

Your email address will not be published.