實戰:解決MySQL的數據持久化的問題!
總體步驟:
- 搜索鏡像
- 拉取鏡像
- 查看鏡像
- 啟動鏡像
- 操作容器(重點)
- 停止容器
- 移除容器
1、搜索鏡像
搜索MySQL鏡像,也可以在Docker官方鏡像倉庫中進行搜索。

下載第一個就可以,是官方鏡像OFFICIAL。
2、拉取鏡像
我們就拉取一個MySQL 5.7版本的鏡像。
[root@192 ~]# docker pull mysql:5.7
5.7: Pulling from library/mysql
a076a628af6f: Already exists
f6c208f3f991: Pull complete
88a9455a9165: Pull complete
406c9b8427c6: Pull complete
7c88599c0b25: Pull complete
25b5c6debdaf: Pull complete
43a5816f1617: Pull complete
1831ac1245f4: Pull complete
37677b8c1f79: Pull complete
27e4ac3b0f6e: Pull complete
7227baa8c445: Pull complete
Digest: sha256:b3d1eff023f698cd433695c9506171f0d08a8f92a0c8063c1a4d9db9a55808df
Status: Downloaded newer image for mysql:5.7
docker.io/library/mysql:5.7
3、查看鏡像
查看本地Docker鏡像。
[root@192 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mysql 5.7 a70d36bc331a 8 weeks ago 449MB
centos latest 300e315adb2f 3 months ago 209MB
MySQL 5.7 的鏡像已經下載到本地了。
4、啟動鏡像
啟動MySQL鏡像,運行MySQL容器,需要做數據掛載。
執行命令如下:
docker run -p 12345:3306 \
--name mysql-01 \
-v /tmp/mysql/conf:/etc/mysql/conf.d \
-v /tmp/mysql/logs:/logs \
-v /tmp/mysql/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
-d mysql:5.7
掛載可以自定義目錄,不一定在/tmp目錄中。
命令說明:
-p 12345:3306:將主機的12345端口映射到Docker容器的3306端口。(端口映射)--name mysql-01:定義運行容器名字。-v /tmp/mysql/conf:/etc/mysql/conf.d:將主機/tmp/mysql錄下的conf/my.cnf文件,掛載到容器的/etc/mysq/conf.d目錄。(數據卷掛載)-v /tmp/mysql/logs:/logs:將主機/tmp/mysql目錄下的logs目錄,掛載到容器的/logs目錄。-v /tmp/mysql/data:/var/lib/mysql:將主機/tmp/mysql目錄下的data目錄,掛載到容器的/var/lib/mysql目錄-e MYSQL_ROOT_PASSWORD=123456:初始化MySQL中root用戶的密碼。(-e:環境配置)
因為安裝啟動MySQL,是需要配置密碼的,這是要注意點!
通過Docker Hub網站對該鏡像的說明,可以看到如下設置密碼的命令,
我們照着寫就可以了。$ docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag-d mysql:5.7:后台程序運行mysql:5.7容器。
提示:
Docker掛載主機目錄Docker訪問出現
cannot open directory.:Permission denied(無法打開目錄。:權限被拒絕)解決辦法:在掛載目錄后多加一個
--privieged=true參數即可。
5、操作容器
(1)在MySQL中創建數據庫
進入MySQL容器中進行操作。

上圖可以知,新啟動的MySQL容器ID為8f6a77ba4917。
對容器中的MySQL服務進行操作,如下:
# 進入MySQL容器
[root@192 ~]# docker exec -it 8f6a77ba4917 /bin/bash
root@8f6a77ba4917:/#
# 1.登陸MySQL
root@8f6a77ba4917:/# 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.33 MySQL Community Server (GPL)
Copyright (c) 2000, 2021, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
# 2.查看數據庫
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.03 sec)
# 3.創建一個數據庫
mysql> create database myDB;
Query OK, 1 row affected (0.01 sec)
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| myDB |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.00 sec)
# 4.退出數據庫
mysql> exit
Bye
root@8f6a77ba4917:/#
(2)外部連接Dokcer容器中的MySQL服務
在外部Win10系統,來連接運行在Dokcer上的MySQL服務。
使用Navicat或者SQLyog都可以。
以Navicat為例,如下圖:

點擊確定,進入Navicat,點開dockertest可以看到我們剛剛手動創建的數據庫myDB,如下圖:

說明我們在外部成功訪問到了Docker容器中的MySQL服務。
之后就可以通過遠程的第三方軟件來操作Docker容器中的MySQL服務了。
原理說明:Navicat連接到服務器的
12345端口,12345端口和容器內的3306端口映射,這個時候外界就可以連接上Docker容器中的MySQL服務了。
(3)查看掛載情況
啟動MySQL容器時的掛載配置如下:
-v /tmp/mysql/conf:/etc/mysql/conf.d \
-v /tmp/mysql/logs:/logs \
-v /tmp/mysql/data:/var/lib/mysql \
進入宿主機的/tmp/mysql/目錄,查看是否有這三個文件夾。
[root@192 ~]# ll /tmp/mysql/
總用量 4
drwxr-xr-x. 2 root root 6 3月 19 12:27 conf
drwxr-xr-x. 6 polkitd root 4096 3月 19 12:32 data
drwxr-xr-x. 2 root root 6 3月 19 12:27 logs
說明已經容器數據卷的掛載成功了。
我們進入data目錄查看內容。
[root@192 ~]# ll /tmp/mysql/data/
總用量 188484
-rw-r-----. 1 polkitd input 56 3月 19 12:27 auto.cnf
-rw-------. 1 polkitd input 1676 3月 19 12:27 ca-key.pem
-rw-r--r--. 1 polkitd input 1112 3月 19 12:27 ca.pem
-rw-r--r--. 1 polkitd input 1112 3月 19 12:27 client-cert.pem
-rw-------. 1 polkitd input 1680 3月 19 12:27 client-key.pem
-rw-r-----. 1 polkitd input 1359 3月 19 12:28 ib_buffer_pool
-rw-r-----. 1 polkitd input 79691776 3月 19 12:28 ibdata1
-rw-r-----. 1 polkitd input 50331648 3月 19 12:28 ib_logfile0
-rw-r-----. 1 polkitd input 50331648 3月 19 12:27 ib_logfile1
-rw-r-----. 1 polkitd input 12582912 3月 19 12:28 ibtmp1
drwxr-x---. 2 polkitd input 20 3月 19 12:32 myDB
drwxr-x---. 2 polkitd input 4096 3月 19 12:28 mysql
drwxr-x---. 2 polkitd input 8192 3月 19 12:28 performance_schema
-rw-------. 1 polkitd input 1676 3月 19 12:28 private_key.pem
-rw-r--r--. 1 polkitd input 452 3月 19 12:28 public_key.pem
-rw-r--r--. 1 polkitd input 1112 3月 19 12:27 server-cert.pem
-rw-------. 1 polkitd input 1676 3月 19 12:27 server-key.pem
drwxr-x---. 2 polkitd input 8192 3月 19 12:28 sys
可以看到MySQL服務的數據庫都同步到宿主機中,連我們剛剛新創建的myDB數據庫也同步過來了。
(4)測試MySQL服務持久化
我們使用第三方軟件操作容器中的MySQL服務,創建一個新的數據庫testDB,看看數據庫能否同步到宿主機中。
在Navicat中創建testDB數據庫,如下圖:

然后在宿主機的/tmp/mysql/data目錄中是否能夠查看到。
[root@192 ~]# ll /tmp/mysql/data/
總用量 188484
-rw-r-----. 1 polkitd input 56 3月 19 12:27 auto.cnf
-rw-------. 1 polkitd input 1676 3月 19 12:27 ca-key.pem
-rw-r--r--. 1 polkitd input 1112 3月 19 12:27 ca.pem
-rw-r--r--. 1 polkitd input 1112 3月 19 12:27 client-cert.pem
-rw-------. 1 polkitd input 1680 3月 19 12:27 client-key.pem
-rw-r-----. 1 polkitd input 1359 3月 19 12:28 ib_buffer_pool
-rw-r-----. 1 polkitd input 79691776 3月 19 12:28 ibdata1
-rw-r-----. 1 polkitd input 50331648 3月 19 12:28 ib_logfile0
-rw-r-----. 1 polkitd input 50331648 3月 19 12:27 ib_logfile1
-rw-r-----. 1 polkitd input 12582912 3月 19 12:28 ibtmp1
drwxr-x---. 2 polkitd input 20 3月 19 12:32 myDB
drwxr-x---. 2 polkitd input 4096 3月 19 12:28 mysql
drwxr-x---. 2 polkitd input 8192 3月 19 12:28 performance_schema
-rw-------. 1 polkitd input 1676 3月 19 12:28 private_key.pem
-rw-r--r--. 1 polkitd input 452 3月 19 12:28 public_key.pem
-rw-r--r--. 1 polkitd input 1112 3月 19 12:27 server-cert.pem
-rw-------. 1 polkitd input 1676 3月 19 12:27 server-key.pem
drwxr-x---. 2 polkitd input 8192 3月 19 12:28 sys
drwxr-x---. 2 polkitd input 20 3月 19 12:47 testDB # 看這里
在宿主機中看到了testDB數據庫,說明MySQL容器持久化的配置是成功的。
(5)問題說明
在進行如上操作的時候,我發現/tmp/mysql/conf/目錄是空的,如下:
[root@192 ~]# ll /tmp/mysql/conf/
總用量 0
而且會把MySQL容器中的/etc/mysql/conf.d目錄也清空,原本mysql 5.7 的/etc/mysql/conf.d目錄內容如下:
root@6a0bc07a843b:/# ls /etc/mysql/conf.d/
docker.cnf mysql.cnf mysqldump.cnf
是有三個文件的。
說明:
- MySQL 5.7的默認配置文件是
/etc/mysql/my.cnf文件。- 如果想要自定義配置,建議向
/etc/mysql/conf.d目錄中創建.cnf文件。- 新建的文件可以任意起名,只要保證后綴名是
.cnf即可,新建的文件中的配置項可以覆蓋/etc/mysql/my.cnf中的配置項。- 提示:不同版本的MySQL 鏡像,配置文件的位置可能會有不同。
所以/etc/mysql/conf.d/目錄是空的,我們不需要擔心。
如果我們要實現在宿主機進行對容器中MySQL服務的配置,解決的方式有兩種
- 手動在宿主機的
/tmp/mysql/conf/目錄(自己配置的目錄)創建以.cnf后綴的配置文件,然后手動按規則編輯。 - 在啟動一個MySQL容器,把上面三個文件拷貝到宿主機,放入到
/tmp/mysql/conf/目錄中,然后在手動進行配置。
(6)MySQL數據庫的數據備份
命令如下:
docker exec mysql 容器ID \
sh -c 'exec mysqldump --all-databases -uroot -p"123456"' > /tmp/mysql/all-databases.sql
示例:
先查看MySQL容器是否正在運行,要運行中才能執行數據備份命令。

執行命令:
docker exec mysql 8f6a77ba4917 \ sh -c 'exec mysqldump --all-databases -uroot -p"123456"' > /tmp/mysql/all-databases.sql
說明:mysqldump -u root -p 數據庫名 > 導出的數據庫文件名,上面是導出所有數據庫到后邊的文件中。
這樣就可以手動的實現MySQL容器數據庫備份到宿主機了。
6、停止容器
# 退出容器
root@8f6a77ba4917:/# exit
exit
# 查看當前正在運行的容器
[root@192 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS
8f6a77ba4917 mysql:5.7 "docker-entrypoint.s…" 55 minutes ago Up 55 minutes
# 停止掉mysql:5.7容器
[root@192 ~]# docker stop 8f6a77ba4917
8f6a77ba4917
7、移除容器
# 查看本地容器
[root@192 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS
8f6a77ba4917 mysql:5.7 "docker-entrypoint.s…" 58 minutes ago Exited (0) 2 minutes
# 刪除mysql:5.7容器
[root@192 ~]# docker rm 8f6a77ba4917
8f6a77ba4917
# 查看容器是否刪除
[root@192 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
此時,我們創建的mysql:5.7容器已經被停止刪除,最后我們在到宿主機的/tmp/mysql/data目錄中,查看mysql:5.7容器持久化數據是否還在。
[root@192 ~]# ll /tmp/mysql/data/
總用量 176196
-rw-r-----. 1 polkitd input 56 3月 19 12:27 auto.cnf
-rw-------. 1 polkitd input 1676 3月 19 12:27 ca-key.pem
-rw-r--r--. 1 polkitd input 1112 3月 19 12:27 ca.pem
-rw-r--r--. 1 polkitd input 1112 3月 19 12:27 client-cert.pem
-rw-------. 1 polkitd input 1680 3月 19 12:27 client-key.pem
-rw-r-----. 1 polkitd input 694 3月 19 13:24 ib_buffer_pool
-rw-r-----. 1 polkitd input 79691776 3月 19 13:24 ibdata1
-rw-r-----. 1 polkitd input 50331648 3月 19 13:24 ib_logfile0
-rw-r-----. 1 polkitd input 50331648 3月 19 12:27 ib_logfile1
drwxr-x---. 2 polkitd input 20 3月 19 12:32 myDB
drwxr-x---. 2 polkitd input 4096 3月 19 12:28 mysql
drwxr-x---. 2 polkitd input 8192 3月 19 12:28 performance_schema
-rw-------. 1 polkitd input 1676 3月 19 12:28 private_key.pem
-rw-r--r--. 1 polkitd input 452 3月 19 12:28 public_key.pem
-rw-r--r--. 1 polkitd input 1112 3月 19 12:27 server-cert.pem
-rw-------. 1 polkitd input 1676 3月 19 12:27 server-key.pem
drwxr-x---. 2 polkitd input 8192 3月 19 12:28 sys
drwxr-x---. 2 polkitd input 20 3月 19 12:47 testDB
說明:刪除容器,持久化還在。我們掛載到本地的數據卷依舊沒有丟失,這就實現了容器數據持久化功能!
