『現學現忘』Docker基礎 — 31、實現MySQL同步資料

繁華似錦Fighting發表於2022-03-24

實戰:解決MySQL的資料持久化的問題!

總體步驟:

  • 搜尋映象
  • 拉取映象
  • 檢視映象
  • 啟動映象
  • 操作容器(重點)
  • 停止容器
  • 移除容器

1、搜尋映象

搜尋MySQL映象,也可以在Docker官方映象倉庫中進行搜尋。

image

下載第一個就可以,是官方映象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容器中進行操作。

image

上圖可以知,新啟動的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為例,如下圖:

image

點選確定,進入Navicat,點開dockertest可以看到我們剛剛手動建立的資料庫myDB,如下圖:

image

說明我們在外部成功訪問到了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資料庫,如下圖:

image

然後在宿主機的/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服務的配置,解決的方式有兩種

  1. 手動在宿主機的/tmp/mysql/conf/目錄(自己配置的目錄)建立以.cnf字尾的配置檔案,然後手動按規則編輯。
  2. 在啟動一個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容器是否正在執行,要執行中才能執行資料備份命令。

image

執行命令:

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

說明:刪除容器,持久化還在。我們掛載到本地的資料卷依舊沒有丟失,這就實現了容器資料持久化功能!

相關文章