MySQL(14)---Docker搭建MySQL主從複製(一主一從)

雨點的名字發表於2020-12-08

Docker搭建MySQL主從複製(一主一從)

上一篇部落格寫了MYSQL主從複製原理 : MySQL(13)---MYSQL主從複製原理

這篇我們來寫 Docker搭建MYSQL主從複製(一主一從)

一、Docker安裝MYSQL

說明 系統為阿里雲伺服器,作業系統為CentOS7.6。MYSQL版本 8.0.22

1、安裝Docker

sudo apt-get update
sudo apt install docker.io

2、拉取MySQL的映象

# 沒有指定版本代表拉取最新版本 目前這裡最新的是8.0.22。如果想指定版本可以docker pull mysql:5.7 代表下載5.7版本
docker pull mysql

執行完以上命令之後,映象就已經下載下來了,可以用 docker images 命令檢視是否已經下載成功

3、第一次啟動MySQL

docker run -p 3306:3306 --name MYSQL8 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:latest

引數說明

-p 3306:3306:  將容器內的3306埠對映到實體機3306埠
--name MYSQL8: 給這個容器取一個容器記住的名字
-e MYSQL_ROOT_PASSWORD=123456: docker的MySQL預設的root密碼是隨機的,這是改一下預設的root使用者密碼
-d mysql:latest: 在後臺執行mysql:latest映象產生的容器

之後的第二次啟動直接用 docker start MYSQL8 即可。

4、連線navicat

新裝了MYSQL8.0後再用navicat連線就會報2059的錯誤。上網查了發現是8.0之後MYSQL更改了密碼的加密規則,只要在命令視窗把加密方法改回去即可。

1) 首先使用以下命令進入MySQL的Docker容器

# MYSQL8是上面啟動的時候 為該容器起的名稱
docker exec -it MYSQL8 bash

2)然後登入MySQL

#這裡的密碼就是上面設定的密碼
mysql -uroot -p123456

3)最後執行以下SQL即可

alter user 'root'@'%' identified by '123456' password expire never;
alter user 'root'@'%' identified with mysql_native_password by '123456';
flush privileges;

這樣就可以通過navicat工具連線當前資料庫了。這裡順便看下當前MYSQL的版本,通過 select version();

MySQL(14)---Docker搭建MySQL主從複製(一主一從)

明顯可以看到當前MYSQL的版本是 8.0.22

注意 我這邊Master庫和Slave庫不在同一個伺服器,所以Slave安裝MYSQL的步驟和Master一樣就可以了。一定要記住Msater庫和Slave庫的MYSQL版本號要一致


二、配置Master和Slave

這裡假設主從伺服器的IP如下

MySQL(14)---Docker搭建MySQL主從複製(一主一從)

1、配置Master

因為是通過Docker部署的MYSQL,所以要進入Docker內部修改MYSQL配置檔案

# MYSQL8是上面啟動的時候 為該容器起的名稱
docker exec -it MYSQL8 bash

進入容器後,切換到 /etc/mysql 目錄下,使用vim命令編輯 my.cnf 檔案。

注意 此時用vim 命令會報 vim: command not found,因此我們需要在Docker內部安裝vim工具。安裝步驟推薦一篇部落格:vi: command not found

在my.cnf新增如下配置

## 同一區域網內注意要唯一
server-id=100  
## 開啟二進位制日誌功能,可以隨便取(關鍵)
log-bin=mysql-bin

新增完後儲存,同時退出當前Docker容器。因為修改了配置檔案,所以要重啟下該MYSQL,這裡重啟下該Docker容器就好了。

#  MYSQL8是上面啟動的時候 為該容器起的名稱
docker restart MYSQL8

這個時候我們通過工具連線該MYSQL伺服器,你可以通過navicat或者Sequel pro等等,連線登上後。

建立使用者並授權

--為從庫伺服器 設定使用者名稱和密碼(表明從伺服器的ip必須為47.00.00.02,賬號為slave 密碼123456
CREATE USER 'slave'@'47.00.00.02' IDENTIFIED BY '123456'; 
grant replication slave, replication client on *.* to 'slave'@'47.00.00.02'; --設定許可權
flush privileges;  --許可權生效

至此,Master配置完成。

2、配置從庫

和上面一樣進入到 etc/mysql 路徑,使用vim命令編輯 my.cnf 檔案:

## 設定server_id,注意要唯一 和master也不能一樣
server-id=101 
## 開啟二進位制日誌功能,以備Slave作為其它Slave的Master時使用
log-bin=mysql-slave-bin  
## 設定為只讀,該項如果不設定,表示slave可讀可寫
read_only = 1

配置完成後也需要重啟Docker容器。

#  MYSQL是上面啟動的時候 為該容器起的名稱
docker restart MYSQL8

3、開啟Master-Slave主從複製

上面兩步Master和Slave都配置成功了,而且Master也為Slave讀取Master資料專門設定了一個賬號,下面就來實現同步。

進入Master庫

檢視Master狀態

--通過該命令可以檢視master資料庫當前正在使用的二進位制日誌及當前執行二進位制日誌位置
show master status
MySQL(14)---Docker搭建MySQL主從複製(一主一從)

記住File和Position,後面Slave庫會在這個檔案這個位置進行同步資料。此時一定不要操作Master庫,否則將會引起Master狀態的變化,File和Position欄位也將會進行變化。

進入Slave庫

執行SQL

change master to
master_host='47.00.00.01',
master_user='slave',
master_password='123456',
MASTER_LOG_FILE='mysql-bin.000002',
MASTER_LOG_POS=156 ;

命令說明

master_host :Master庫的地址,指的是容器的獨立ip,可以通過:
master_port :Master的埠號,指的是容器的埠號(預設3306)
master_user :用於資料同步的使用者
master_password :用於同步的使用者的密碼
master_log_file :指定 Slave 從哪個日誌檔案開始複製資料,即上文中提到的 File 欄位的值
master_log_pos :從哪個 Position 開始讀,即上文中提到的 Position 欄位的值

使用start slave命令開啟主從複製過程

start slave;  -- 順便提供下其它命令 stop slave 停止slave。reset slave重啟slave。 reset master重啟master。

啟動之後我們來看下有沒有成功。

show slave status命令

MySQL(14)---Docker搭建MySQL主從複製(一主一從)

從這張圖很明顯看出,對於Slave的兩個執行緒都成功了,那就說明整個MYSQL主從搭建成功了。如果有一個為NO,那就需要到後面看錯誤日誌,是什麼原因出錯了,解決下就好了。

Slave_IO_Running: 從伺服器中I/O執行緒的執行狀態,YES為執行正常
Slave_SQL_Running: 從伺服器中SQL執行緒的執行狀態,YES為執行正常

三、測試

這裡簡單做一個測試

1、只在Mater 建立一張User表

現在 只在Mater 建立一張User表,如果現在Slave也同樣生成這張User表,那就說明成功了。

CREATE TABLE `user` (
  `id` bigint NOT NULL COMMENT '主鍵',
  `user_name` varchar(11) NOT NULL COMMENT '使用者名稱',
  `password` varchar(11) NOT NULL COMMENT '密碼',
  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '建立時間',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='使用者表';

實際測試結果是成功的。

注意

這裡如果我們先手動在Slave建立這張User表,然後再到Master建立User表那就出事情了。我們按照上面的步驟建立完後,去Slave通過 show slave status 檢視

MySQL(14)---Docker搭建MySQL主從複製(一主一從)

發現 SQL執行緒都變NO了。原因很簡單,錯誤日誌也說明了(Error 'Table 'user' already exists')。因為你在Master建立User表的SQL會記錄到bin-log日誌中,然後Slave

去讀取這個操作,然後寫入Slave中的時後發現這個SQL執行失敗,因為你Slave已經存在該User表,然後這整個主從複製就卡在這裡了。這是個很嚴重的問題。

所以一旦搭建主從複製成功,只要在Master做更新事件(update、insert、delete),不要在從資料做,否則會出現資料不一致甚至同步失敗。

2、Master插入一條資料

INSERT INTO `user` (`id`, `user_name`, `password`, `create_time`)
VALUES
	(0, '張三', '123456', '2020-11-25 04:29:43');

再去Slave資料庫檢視

MySQL(14)---Docker搭建MySQL主從複製(一主一從)

發現從資料庫已經寫入成功了。

總結:在搭建的過程可能還有其它的問題出現 你只要在Slave伺服器,通過show slave status,如果兩個IO是否為YES就代表是否成功,如果有為NO的,

後面有欄位說明是什麼原因導致的,你再根據相關錯誤資訊去查詢下解決方案,那就可以了。


參考

1、Docker安裝MySQL8.0

2、MySQL主從同步機制和同步延時問題追查

3、Docker搭建MySQL主從複製



別人罵我胖,我會生氣,因為我心裡承認了我胖。別人說我矮,我就會覺得好笑,因為我心裡知道我不可能矮。這就是我們為什麼會對別人的攻擊生氣。
攻我盾者,乃我內心之矛(33)

相關文章