歡迎光臨
每天分享高質量文章

Named Volume 在 MySQL 資料持久化上的基本應用

原文作者:春哥

非常感謝春哥的投稿,同時也有一些感慨。

初識春哥時,春哥是美術設計大咖。後不久,創業並致力於游戲開發,已有3年。從Unity3D到IOS(Swift)開發,從前端開發到後端以及容器技術,從設計開發測試到產品經理以及CEO,已是爬坑纍纍,但是仍是奮勇前行。

春哥仍在奮鬥,游戲也即將上線,而我們也需砥礪前行啊!

使用 Docker 時,容器(Container)會自動創建一個資料捲(Data Volume)來單獨儲存資料。資料捲有獨立的本地目錄,不跟著容器走,你在不同地方使用同一個容器,資料是不一樣的。自動創建的資料捲不便於管理,Docker 官方建議我們用 Named Volume 來負責容器的資料持久化,Named Volume 就是自己取名字手動創建一個資料捲。

本文使用 MySQL 資料庫做例子。資料捲對資料庫容器來說是非常重要的。

 

創建資料捲

這裡我們隨便取個資料捲名字叫 my-data 吧。創建命令很簡單:

docker volume create --name my-data

 

創建共享網絡

容器在創建時,除了自動創建資料捲外,也會自動創建它的專用網絡(Network)。這個網絡我們也要用自己創建的(Defined Network),自己創建的方便管理。這裡給網絡取名叫 my-network

docker network create my-network

為什麼創建這個網絡呢?是為了在容器間共享網絡,看下去就會明白。

 

創建 MySQL 容器

現在利用前面創建的資料捲和網絡創建一個 MySQL 容器:

docker run -d --rm --name mysql-a -v my-data:/var/lib/mysql --network my-network -p 33061:3306 -e MYSQL_ROOT_PASSWORD=abcd1234 mysql:latest

詳細解釋一下各引數:

  • 容器命名為 mysql-a
  • MySQL 預設的端口是 3306,你可以換一個以免和本地的衝突。這個例子中我映射到 33061
  • -d 是後臺運行。 --rm 是讓容器在停止運行時自動刪除。資料在外部的捲里,可以放心刪。
  • -v 就是使用資料捲。/var/lib/mysql 是 MySQL 存放資料的目錄,現在我們要把裡面的東西都映射到資料捲里:-v my-data:/var/lib/mysql
  • --network my-network 使用我們剛纔創建的網絡。
  • -e 設定 MySQL 的環境變數。在這裡我們設定 root 密碼為 abcd1234
  • 最後 mysql:latest 是映像(Image)。具體 tag 可看 Docker Hub: MySQL

 

創建 PhpMyAdmin 容器

管理 MySQL 資料庫的客戶端有很多,其中 PhpMyAdmin 是比較常見的一種。所以現在我們要創建 PhpMyAdmin 的容器,然後去管理 MySQL 容器,也就是連接兩種容器。

如何連接?以前可以用 --link 的方式,但官方已經不推薦了,未來版本會棄用的,這裡就不寫了。官方推薦的是 Defined Network,之前創建 my-network 就是為了用在這裡。如果你不用 PhpMyAdmin 管理,那麼 Network 也可以不單獨創建。

創建容器:

docker run -d --rm --name my-pma --network my-network -p 8080:80 -e PMA_HOST=mysql-a phpmyadmin/phpmyadmin

引數中 PMA_HOST=mysql-a 指定了 MySQL 容器。端口隨便映射了一個 8080。創建好後,PhpMyAdmin 容器和 MySQL 容器就在同一個網絡里了,然後 PhpMyAdmin 就可以管理 MySQL 資料庫了。

現在打開瀏覽器,進 http://localhost:8080,輸入 root 賬戶密碼就可以進去管理了——如果你的 MySQL 版本 >= 5.7,那可能登錄不進去,需要改一下 MySQL 賬號所用的密碼插件(identified with mysql_native_password)。

 

資料捲的備份

使用資料捲的一大好處,是可以在不同機器和環境中使用同一套資料。因此,必須掌握如何備份和還原資料捲。

備份的操作思路:

  1. 創建一個新容器,這個容器有一個資料捲和 MySQL 容器是一樣的。
  2. 再掛載一個非 Named Volume 資料捲(本地目錄),用來映射本地備份目錄。
  3. 將 MySQL 容器資料捲打包,然後存在備份目錄里。
  4. 在本地目錄獲取資料捲打包檔案。

命令列操作:

docker run --rm --volumes-from mysql-a -v $(pwd):/backup busybox tar cvf /backup/mysql-backup.tar /var/lib/mysql

引數說明:

  • 用了 --volumes-from mysql-a,就是從 mysql-a 直接拿它的資料捲(my-data)過來用。
  • -v $(pwd):/backup:將本地當前目錄作為資料捲目錄映射到容器系統的 /backup 目錄,$(pwd)就是輸出當前目錄,註意在 PowerShell 里是 ${pwd}。你用別的目錄也可以。
  • busybox 是用到的 Image,它的容量很小,但重要工具基本都有。
  • tar cvf /backup/mysql-backup.tar /var/lib/mysql 是在容器里執行的備份命令:將 /var/lib/mysql (mysql-a 資料捲內容)打包到 /backup 目錄下的 mysql-backup.tar 中。由於本地當前目錄和 /backup 有映射關係,所以本地當前目錄下也會有 mysql-backup.tar 檔案。

mysql-backup.tar 就是我們創建的資料捲備份檔案,你可以帶著它到處跑了。有些人會做一個專門存放各種資料捲的容器作為備份,我感覺有點麻煩和多餘。

 

資料捲的還原

還原的思路和備份一樣,也是先要搞一個臨時容器,然後執行一些命令去解壓 tar 檔案。

假設我們在別的地方創建了一個新的 MySQL 容器 mysql-b,我們該怎麼把 my-data 資料捲的資料還原到它裡面去呢?

先把 mysql-backup.tar 拷貝到當前目錄。然後:

docker run --rm --volumes-from mysql-b -v $(pwd):/backup centos bash -c "cd /var/lib && rm -rf mysql/* && tar xvf /backup/mysql-backup.tar --strip 2"

這裡重點解釋一下在容器 bash 里執行的命令:

  1. cd /var/lib: 進入 /var/lib 目錄。
  2. rm -rf mysql/*: 刪除目錄 mysql 下的所有檔案,為的是等會將資料捲的備份檔案放進去。刪除再解壓進去比直接改寫更乾凈穩妥一些。
  3. tar xvf /backup/mysql-backup.tar --strip 2: 將 mysql-backup.tar 檔案中 mysql 的檔案解壓到 /var/lib/mysql 目錄中去,因為我們在 /var/lib 中,而打包檔案包括了 /var/lib/mysql 多層目錄,所以加了引數 --strip 2。關於打包解壓目錄這種事你可以自己規劃,只要確保 mysql 里的檔案能正確的備份和還原就行。

檔案解壓完後,重啟當前的 MySQL 容器:

docker restart mysql-b

還原工作到此結束,現在 mysql-b 的資料和 mysql-a 是一樣的了。

 

總結

資料捲對資料庫容器非常重要。Named Volume 可以使我們管理資料捲更為方便,應多加利用。其他資料庫的檔案結構和 MySQL 可能不一樣,但只要掌握了 MySQL 資料捲備份還原的原理之後,其他資料庫應該也不難操作。

    赞(0)

    分享創造快樂