上一篇博客寫了MYSQL主從複製原理 : MySQL(13)---MYSQL主從複製原理html
這篇咱們來寫 Docker搭建MYSQL主從複製(一主一從)mysql
說明
系統爲阿里雲服務器,操做系統爲CentOS7.6。MYSQL版本 8.0.22sql
sudo apt-get update sudo apt install docker.io
# 沒有指定版本表明拉取最新版本 目前這裏最新的是8.0.22。若是想指定版本能夠docker pull mysql:5.7 表明下載5.7版本 docker pull mysql
運行完以上命令以後,鏡像就已經下載下來了,能夠用 docker images 命令查看是否已經下載成功docker
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 便可。vim
新裝了MYSQL8.0後再用navicat鏈接就會報2059的錯誤。上網查了發現是8.0以後MYSQL更改了密碼的加密規則,只要在命令窗口把加密方法改回去便可。segmentfault
1) 首先使用如下命令進入MySQL的Docker容器bash
# MYSQL8是上面啓動的時候 爲該容器起的名稱 docker exec -it MYSQL8 bash
2)而後登陸MySQL服務器
#這裏的密碼就是上面設置的密碼 mysql -uroot -p123456
3)最後運行如下SQL便可ide
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的版本是 8.0.22
注意
我這邊Master庫和Slave庫不在同一個服務器,因此Slave安裝MYSQL的步驟和Master同樣就能夠了。必定要記住Msater庫和Slave庫的MYSQL版本號要一致。
這裏假設主從服務器的IP以下
由於是經過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配置完成。
和上面同樣進入到 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
上面兩步Master和Slave都配置成功了,並且Master也爲Slave讀取Master數據專門設置了一個帳號,下面就來實現同步。
進入Master庫
查看Master狀態
--經過該命令能夠查看master數據庫當前正在使用的二進制日誌及當前執行二進制日誌位置 show master status
記住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
命令
從這張圖很明顯看出,對於Slave的兩個線程都成功了,那就說明整個MYSQL主從搭建成功了。若是有一個爲NO,那就須要到後面看錯誤日誌,是什麼緣由出錯了,解決下就行了。
Slave_IO_Running: 從服務器中I/O線程的運行狀態,YES爲運行正常 Slave_SQL_Running: 從服務器中SQL線程的運行狀態,YES爲運行正常
這裏簡單作一個測試
如今 只在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
查看
發現 SQL線程都變NO了。緣由很簡單,錯誤日誌也說明了(Error 'Table 'user' already exists')。由於你在Master建立User表的SQL會記錄到bin-log日誌中,而後Slave
去讀取這個操做,而後寫入Slave中的時後發現這個SQL執行失敗,由於你Slave已經存在該User表,而後這整個主從複製就卡在這裏了。這是個很嚴重的問題。
因此一旦搭建主從複製成功,只要在Master作更新事件(update、insert、delete),不要在從數據作,不然會出現數據不一致甚至同步失敗。
INSERT INTO `user` (`id`, `user_name`, `password`, `create_time`) VALUES (0, '張三', '123456', '2020-11-25 04:29:43');
再去Slave數據庫查看
發現從數據庫已經寫入成功了。
總結
:在搭建的過程可能還有其它的問題出現 你只要在Slave服務器,經過show slave status,若是兩個IO是否爲YES就表明是否成功,若是有爲NO的,
後面有字段說明是什麼緣由致使的,你再根據相關錯誤信息去查詢下解決方案,那就能夠了。
別人罵我胖,我會生氣,由於我內心認可了我胖。別人說我矮,我就會以爲可笑,由於我內心知道我不可能矮。這就是咱們爲何會對別人的攻擊生氣。 攻我盾者,乃我心裏之矛(33)