# 使用MySQL
## 啟動MySQL實例
對我個人來說,使用Docker的最大需求就是可以簡化一些應用的安裝,特別是數據庫之類的-_-b。所以,使用Docker的第一個Demo就是啟動一個MySQL實例。
```powershell
# 拉取MySQL鏡像
docker pull mysql
# 啟動MySQL實例
# name參數將該Container命名為demo.mysql
# p參數將Container內部的3306端口(MySQL的默認端口)映射到本地
# e參數添加環境變量,這里將MySQL的root用戶密碼設置為password
# d參數指定該Container在后臺允許,即不會在當前命令行中顯示輸出
docker run --name demo.mysql -e MYSQL_ROOT_PASSWORD=password -p 3306:3306 -d mysql
```
如果一切正常的話,命令行中將只輸出Container的ID,同時我們也可以通過`docker ps`命令查看到。

如果有更進一步的需要,還可以直接進入Container內部操作(可以視作Lunix環境)。
```powershell
docker exec -it demo.mysql bash
```

## 關于數據卷
數據卷(volume)是一個生命周期獨立于容器(container)的特殊目錄,可以實現數據的持久化儲存。
說到這里,想必大家應該都能想到,MySQL這樣的數據庫應用必然會需要建立數據卷。我們可以用`docker volume ls`來查看一下。

果然,MySQL鏡像在創建實例容器時,會默認創建一個數據卷。
因此,這就涉及到一個坑。
在刪除MySQL的實例時,我在一開始就只使用`docker rm demo.mysql`。
但是,這個操作并不會刪除與容器相關的數據卷。
所以,這里需要注意,如果確定不再需要了,可以通過`docker rm -v demo.mysql`來徹底刪除(包括數據卷)。
當然,對于已經存在的且不再需要的數據卷,我們也可以通過以下方式來刪除。
```powershell
# 刪除某個數據卷
docker volume rm bb338dbf12e4fff1deae0260ab55089a53555a6e340ae2d2f823920e7be3d725a
# 刪除所有數據卷
docker volume rm $(docker volume ls -q)
```
這里稍微解釋一下刪除所有數據卷的命令。
它其實包括了兩部分
1. docker volume ls -q
2. docker volume rm
其中的第一部分可以列出所有數據卷的Id,然后將值傳給第二個命令,即起到了刪除所有數據卷的作用。
## 創建MySQL集群
如果覺得只是啟動一個MySQL體現不出Docker的優勢,那么這邊我們來試著用Docker創建一個MySQL集群。
### 使用命令行創建
首先,自然是[官方文檔](https://hub.docker.com/r/mysql/mysql-cluster/)。
因為官方文檔已經講的挺詳細的了,所以這邊只是單純的題一下。
```PowerShell
# 創建一個內部網絡,命名為cluster
docker network create cluster --subnet=192.168.0.0/16
# 創建MySQL管理節點
docker run -d --net=cluster --name=management1 --ip=192.168.0.2 mysql/mysql-cluster ndb_mgmd
# 創建兩個MySQL數據節點
docker run -d --net=cluster --name=ndb1 --ip=192.168.0.3 mysql/mysql-cluster ndbd
docker run -d --net=cluster --name=ndb2 --ip=192.168.0.4 mysql/mysql-cluster ndbd
# 創建MySQL查詢節點
# 這里和官方文檔不同,為了方便直接設置了root密碼
docker run -d --net=cluster --name=mysql1 --ip=192.168.0.10 -e MYSQL_ROOT_PASSWORD=password mysql/mysql-cluster mysqld
```

此時,MySQL集群就已經啟動了,我們可以利用`ndb_mgm`來管理集群。
```PowerShell
# 進入交互式的管理命令行
docker run -it --net=cluster mysql/mysql-cluster ndb_mgm
```
在顯示`ndb_mgm>`后鍵入`show`就可以看到該集群信息。

## 使用Docker Compose創建
和網上那些一大堆的配置教程對比是不是簡單很多,但也還是有些不爽,特別是在你要清理資源的時候,你需要手動的刪除容器、網絡、數據集資源。
顯然,我們有更簡潔的方式來啟動MySQL集群——利用Docker Compose。(懶得換順序了,本來docker-compose是在下一篇中介紹的)
那首先,我們需要新建一個目錄,比如**mysql_cluster**。(目錄名稱和默認的容器名稱有關)
然后,在這個目錄中創建一個配置文件`docker-compose.yml`,鍵入以下內容。
```yml
version: '3'
services:
# 管理節點
management:
image: "mysql/mysql-cluster"
command: ndb_mgmd
networks:
cluster:
ipv4_address: 192.168.0.2
# 數據節點1
ndb1:
image: "mysql/mysql-cluster"
command: ndbd
networks:
cluster:
ipv4_address: 192.168.0.3
# 數據節點2
ndb2:
image: "mysql/mysql-cluster"
command: ndbd
networks:
cluster:
ipv4_address: 192.168.0.4
# 查詢節點
mysql:
image: "mysql/mysql-cluster"
command: mysqld
# 設置root密碼
environment:
- MYSQL_ROOT_PASSWORD=password
# 將3306端口暴露到本地
ports:
- "3306:3306"
networks:
cluster:
ipv4_address: 192.168.0.10
# 創建一個B類子網
# 其實改成A類網絡應該也可以,這里就按官方文檔來配置了。
networks:
cluster:
driver: bridge
ipam:
driver: default
config:
- subnet: 192.168.0.0/16
```
最后,在該目錄下啟動PowerShell,鍵入`docker-compose up -d`,即可啟動MySQL集群。
### MySQL集群在測試時的一些小問題
在創建MySQL集群后,相信大家肯定會用各種工具去連接測試一下,但往往并不會順利的連接上。
比如,極有可能碰到的權限問題。
> host ‘192.168.0.1’ is not allowed to connect to this MYSQL server.
這是因為我們的MySQL集群運行在子網中,我們在本地環境中去訪問的話,就相當于遠程訪問。但是MySQL的默認策略是不允許遠程登錄的,所以我們需要進入MySQL容器,添加遠程訪問的權限。
首先,利用`docker exec -it mysqlcluster_mysql_1 mysql -uroot -p`進入查詢節點。
> **注意**:這里的容器名是根據我創建的目錄`mysql-cluster`生成的默認命名。若你創建的目錄名和我不同,請使用`docker ps`來查看你自己查詢節點的容器名。
然后,在驗證密碼之后,鍵入以下內容。
```sql
/*
* 這條命令是賦予任何IP的root用戶全部權限
* 其中,root用戶的密碼為password
*/
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'password' WITH GRANT OPTION;
```
然后,重新訪問就OK了。