1.搜索mysql鏡像,拉取指定版本

docker search mysql 實際上是去https://hub.docker.com/ 搜索的,
如果直接用命令直接拉取搜索的鏡像名稱,如docker pull mysql,則下載的是最新版的。
如果要安裝指定版本,則拉取時就需要指定版本,先到https://hub.docker.com/ ,搜索mysql,查看所有發布的版本

切換到tag標簽,可以看到列出的mysql各個版本

我這里選擇5.7版本的,拉取命令就是:docker pull mysql:5.7
mysql 鏡像下載完成后,可以查看一下

2.安裝mysql鏡像
在https://hub.docker.com/_/mysql 有介紹怎么安裝mysql鏡像

我這里選擇上面的兩種分別介紹一下:
1.掛載自定義配置的方式,這種的好處時,我們可以直接在宿主機配置mysql
使用自定義MySQL配置文件啟動mysql 默認情況下,MySQL的啟動配置文件是/etc/mysql/my.cnf,而/etc/mysql/conf.d目錄下的存在任何.cnf格式的文件時,都會使用該文件中配置項替換默認配置。 因此,如果要使用自定義配置,可以在宿主機創建一個配置文件,然后在創建容器時通過-v參數,以數據卷的方式將自定義配置掛載到mysql容器的/etc/mysql/conf.d目錄下。 如,在宿主機中存在/my/mysql/conf/config-file.cnf配置文件,這時就可以通過以下方式啟動MySQL容器:
舉例:
docker run --name mysql5.7 -p 3306:3306 -v /my/mysql/data:/var/lib/mysql -v /my/mysql/conf:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7
2. 直接安裝命令后面跟參數的方式,這種方式比較簡單直接
docker run --name mysql5.7_1 -e MYSQL_ROOT_PASSWORD=123456 -p 3307:3306 -d mysql:5.7 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
我這里采取第2種方式,快速安裝兩台mysql
#安裝第1台
docker run --name mysql5.7_1 -e MYSQL_ROOT_PASSWORD=123456 -p 3307:3306 -d mysql:5.7 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
#安裝第2台
docker run --name mysql5.7_2 -e MYSQL_ROOT_PASSWORD=123456 -p 3308:3306 -d mysql:5.7 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
查看安裝后的容器,可以看到mysql狀態為up,正在運行

可以在遠程用命令或客戶端鏈接任意一台,檢查是否能正常連上。
用windows的命令行來連接測試,登錄命令:mysql -uroot -p123456 -h 192.168.220.102 -P 3307

用Navicat客戶端連接測試

至此,安裝完成。
3.搭建一主一從集群
配置主從就需要修改mysql的配置文件,就需要進入mysql容器內修改配置文件
- 配置主機
這里把mysql_5.7_1這台做M主機,先進入配置它
通過docker exec -it a1c7de8adce4 /bin/bash命令進入到Master容器內部,也可以通過docker exec -it mysql_5.7_1 /bin/bash命令進入。a1c7de8adce4 是容器的id,而mysql_5.7_1是容器的名稱。
[root@localhost ~]# docker exec -it a1c7de8adce4 /bin/bash
繼續進入mysql配置目錄
root@a1c7de8adce4:/# cd /etc/mysql
查看配置文件ls -l

會看到有兩個配置文件my.cnf和mysql.cnf,這個兩個的關系是my.cnf是mysql.cnf的軟鏈接,下圖給予證實。所以編輯任意一個都行

但是我們在用vim時,發現容器中並沒有安裝,所以如果要用vim編輯,需要先安裝

使用apt-get install vim命令安裝vim,又會出現如下問題

執行apt-get update,然后再次執行apt-get install vim即可成功安裝vim。
然后vim my.cnf,增加以下配置,保存退出。
[mysqld] #這行很重要,如果my.cnf有這行則不用再重復寫,如果沒有則添加。
server-id=1 #服務器唯一ID
log-bin=mysql-bin #開啟二進制日志,主從復制的數據文件
binlog-do-db=mycat-m-s #需要同步的數據庫名字
binlog_format=STATEMEN #設置logbin格式

補充一下:上面是在mysql容器中修改mysql的配置文件,需要安裝vim。
其實完全可以把mysql的配置文件從容器中拷貝的宿主機,修改完成后再拷貝回mysql容器,這樣更方便寫。
具體步驟為:
因為進入mysql容器,我們發現真正的配置文件是 /etc/mysql/mysql.cnf,所以我們先在宿主機把此文件拷貝下來:
docker cp a1c7de8adce4:/etc/mysql/mysql.cnf /usr/local/
然后vim編輯拷貝下來的mysql.cnf:
!includedir /etc/mysql/conf.d/
!includedir /etc/mysql/mysql.conf.d/
#新增如下配置
[mysqld]
server-id=1
log-bin=mysql-bin
binlog-do-db=mycat_m_s
binlog_format=STATEMEN
編輯保存后,再拷貝回mysql容器中,進行覆蓋
docker cp mysql.cnf a1c7de8adce4:/etc/mysql/
- 配置從機
同樣的方式進入從機mysql5.7_2,修改my.cnf,增加以下配置,保存退出。退出容器。
[mysqld]
server-id=2 #服務器唯一ID
relay-log=mysql-relay #啟用
重啟兩台mysql容器,命令:docker restart 容器id或名稱

- 登錄主機mysql5.7_1,建立授權賬戶 slave
#在主機MySQL里執行授權命令 GRANT REPLICATION SLAVE ON *.* TO 'slave'@'%' IDENTIFIED BY '123456';
執行完后,登錄Matater查看一下用戶信息:mysql> select user,host from user; 看到slave用戶已經創建成功。

-
Master(主)和Slave(從)建立鏈接
登錄Master,執行show master status;查看主從復制需要的配置信息

File和Position字段的值在接下來配置從機復制主機信息時會用到,所以在后面的操作完成之前,需要保證Master庫不能做任何操作,否則將會引起File和Position字段的值變化。
登錄slave,執行鏈接master配置命令
change master to master_host='主機的ip地址',
master_port=端口號,
master_user='slave',
master_password='123456',
master_log_file='mysql-bin.具體數字',
master_log_pos=位置具體值,
master_connect_retry=60;
-------------------------------------------------------------------------
詳細解釋:
master to master_host: Master的ip
master_port:Master的端口號,因為用的是docker中的mysql,所以這里指的是宿主機映射到到mysql容器的端口
master_user:用於數據同步的用戶
master_password:用於同步的用戶的密碼
master_log_file:指定 Slave 從哪個日志文件開始復制數據,即上文中提到的 File 字段的值
master_log_pos:從哪個 Position 開始讀,即上文中提到的 Position 字段的值
master_connect_retry:如果連接失敗,重試的時間間隔,單位是秒,默認是60秒
具體執行命令如下:
change master to master_host='192.168.220.102',
master_port=3307,
master_user='slave',
master_password='123456',
master_log_file='mysql-bin.000003',
master_log_pos=1821,
master_connect_retry=60;
將上面的命令復制到從mysql命令窗口執行。
查看從機狀態 mysql> show slave status\G;
mysql> change master to master_host='192.168.220.102',
-> master_port=3307,
-> master_user='slave',
-> master_password='123456',
-> master_log_file='mysql-bin.000003',
-> master_log_pos=1821,
-> master_connect_retry=60;
Query OK, 0 rows affected, 2 warnings (0.00 sec)
mysql> show slave status \G;
*************************** 1. row ***************************
Slave_IO_State:
Master_Host: 192.168.220.102
Master_User: slave
Master_Port: 3307
Connect_Retry: 60
Master_Log_File: mysql-bin.000003
Read_Master_Log_Pos: 1821
Relay_Log_File: mysql-relay.000005
Relay_Log_Pos: 320
Relay_Master_Log_File: mysql-bin.000003
Slave_IO_Running: No
Slave_SQL_Running: No
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 1281
Relay_Log_Space: 523
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 1236
Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: 'log event entry exceeded max_allowed_packet; Increase max_allowed_packet on master; the first event 'mysql-bin.000003' at 1281, the last event read from './mysql-bin.000003' at 123, the last byte read from './mysql-bin.000003' at 1300.'
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 1
Master_UUID: 16d94e7b-7f17-11ea-bb5e-0242ac110003
Master_Info_File: /var/lib/mysql/master.info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp: 200417 06:26:09
Last_SQL_Error_Timestamp:
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set:
Executed_Gtid_Set:
Auto_Position: 0
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:
1 row in set (0.00 sec)
可以看到從機進行主從同步的兩個主要線程SlaveIORunning 和 SlaveSQLRunning 都是No,正常應該是yes才對。這是因為我們還沒有開啟從服務器的復制功能。
使用start slave開啟主從復制,然后再次查詢主從同步狀態show slave status \G;。

至此,主從復制搭建完成。
- 驗證主從復制
截圖如下:

4.一主雙從搭建
用docker構建一台mysql容器,作為第二台從機mysql5.7_2_3

修改容器mysql5.7_2_3的配置文件 /etc/mysql/mysql.cnf,增加以下內容
[mysqld]
server-id=5
relay-log=mysql-relay
然后重啟該容器服務。
查看要要掛載主機mysql5.7_1的binlog日志信息
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000006 | 5625 | mycat_m_s | | |
+------------------+----------+--------------+------------------+-------------------+
進入容器mysql5.7_2_3,且進入mysql客戶端,在命令行執行如下鏈接復制主機的命令
change master to master_host='192.168.220.102',
master_port=3307,
master_user='slave',
master_password='123456',
master_log_file='mysql-bin.000006',
master_log_pos=5625,
master_connect_retry=60;
啟動從機功能 start slave;
查看從機狀態 show slave status \G;
mysql> show slave status \G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.220.102
Master_User: slave
Master_Port: 3307
Connect_Retry: 60
Master_Log_File: mysql-bin.000006
Read_Master_Log_Pos: 6356
Relay_Log_File: mysql-relay.000002
Relay_Log_Pos: 1051
Relay_Master_Log_File: mysql-bin.000006
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 6356
Relay_Log_Space: 1254
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 1
Master_UUID: 16d94e7b-7f17-11ea-bb5e-0242ac110003
Master_Info_File: /var/lib/mysql/master.info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp:
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set:
Executed_Gtid_Set:
Auto_Position: 0
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:
1 row in set (0.00 sec)
說明掛載成功,一主mysql5.7_1雙從mysql5.7_2和mysql5.7_2_3 搭載完成。
5.雙主雙從搭建
- 再創建兩個mysql容器,分別做備主備從

- 修改雙主雙從的配置文件
修改Master1(mysql5.7_1)的配置文件mysql.cnf
[mysqld]
server-id=1
log-bin=mysql-bin
binlog-do-db=mycat_m_s
binlog_format=STATEMEN
log-slave-updates
auto-increment-increment=2
auto-increment-offset=1
修改Master2(mysql5.7_1_1)的配置文件mysql.cnf
[mysqld]
server-id=3
log-bin=mysql-bin
binlog-do-db=mycat_m_s
binlog_format=STATEMEN
log-slave-updates
auto-increment-increment=2
auto-increment-offset=2
修改Slave1(mysql5.7_2)的配置文件mysql.cnf
[mysqld]
server-id=2
relay-log=mysql-relay
修改Slave2(mysql5.7_2_2)的配置文件mysql.cnf
[mysqld]
server-id=4
relay-log=mysql-relay
修改完成后,重啟4台mysql容器。
[root@localhost local]# docker restart 16ac52f8e7a5
16ac52f8e7a5
[root@localhost local]# docker restart a1c7de8adce4
a1c7de8adce4
[root@localhost local]# docker restart 0bea5a5c10b3
0bea5a5c10b3
[root@localhost local]# docker restart 9269c1b9802f
9269c1b9802f
- 分別登錄各個mysql服務器

- 在兩台主機Master1(mysql5.7_1),Master2(mysql5.7_1_1)的mysql命令窗口,建立帳戶並授權 slave
#在主機MySQL里執行授權命令 GRANT REPLICATION SLAVE ON *.* TO 'slave'@'%' IDENTIFIED BY '123456';

- 查詢Master1的狀態 和 Master2的狀態,分別記錄下File和Position的值,為后面配置從機復制主機信息做准備

- 因為Slave1(mysql5.7_2) 之前設置過屬於Master1(mysql5.7_1)的從機,所以這里需要重置一下,以便重新設置
執行命令:
mysql> stop slave;
Query OK, 0 rows affected (0.07 sec)
mysql> reset master;
Query OK, 0 rows affected (0.01 sec)
- 兩台從機上執行配置需要復制主機的命令
Slava1 復制 Master1,Slava2 復制 Master2 ,具體命令如下:
#Slava1 復制 Master1命令
change master to master_host='192.168.220.102',
master_port=3307,
master_user='slave',
master_password='123456',
master_log_file='mysql-bin.000005',
master_log_pos=333,
master_connect_retry=60;
#Slava2復制Master2命令
change master to master_host='192.168.220.102',
master_port=3309,
master_user='slave',
master_password='123456',
master_log_file='mysql-bin.000002',
master_log_pos=443,
master_connect_retry=60;
執行效果圖:

- 啟動兩台從服務器的復制功能 start slave;並查看從服務器狀態 show slave status\G;

兩個參數# Slave_IO_Running: Yes ,Slave_SQL_Running: Yes 都是Yes,則說明主從配置成功!
- 兩個主機互相復制
Master1 復制 Master2 ,Master2 復制 Master1
#主機2復制主機1命令
change master to master_host='192.168.220.102',
master_port=3307,
master_user='slave',
master_password='123456',
master_log_file='mysql-bin.000005',
master_log_pos=333,
master_connect_retry=60;
#主機1復制主機2命令
change master to master_host='192.168.220.102',
master_port=3309,
master_user='slave',
master_password='123456',
master_log_file='mysql-bin.000002',
master_log_pos=443,
master_connect_retry=60;
執行效果圖:

- 啟動兩台主服務器的復制功能 start slave;並查看從服務器狀態 show slave status\G;

兩個參數# Slave_IO_Running: Yes ,Slave_SQL_Running: Yes 都是Yes,則說明主從配置成功!
- 驗證雙主雙從復制


