docker實現mysql主從複製

呂林光發表於2021-08-30

一、概述

1、原理

  • master伺服器將資料的改變記錄二進位制binlog日誌,當master上的資料發生改變時,則將其改變寫入二進位制日誌中;
  • slave伺服器會在一定時間間隔內對master二進位制日誌進行探測其是否發生改變,如果發生改變,則開始一個I/OThread請求master二進位制事件
  • 同時主節點為每個I/O執行緒啟動一個dump執行緒,用於向其傳送二進位制事件,並儲存至從節點本地的中繼日誌中,從節點將啟動SQL執行緒從中繼日誌中讀取二進位制日誌,在本地重放,使得其資料和主節點的保持一致,最後I/OThread和SQLThread將進入睡眠狀態,等待下一次被喚醒。
  • 主從流程圖

2、實現

  • 主庫:192.168.3.13:3310
  • 從庫:192.168.3.14:3310

二、建立master主庫

  • 進入伺服器192.168.3.13

1、安裝映象

docker pull mysql:8.0.26

2、新建目錄

mkdir -p /home/apps/mysql-master/{config,log,data}

3、建立並啟動

docker run -d --name mysql-master \
--restart=always \
--privileged=true \
-p 3310:3306 \
-v /home/apps/mysql-master/config:/etc/mysql/conf.d \
-v /home/apps/mysql-master/log:/var/log/mysql \
-v /home/apps/mysql-master/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
mysql:8.0.26

4、新增/修改master基本配置

vim /home/apps/mysql-master/config/my.cnf

新增以下內容

[client]
default-character-set=utf8
 
[mysql]
default-character-set=utf8
 
[mysqld]
init_connect='SET collation_connection = utf8_unicode_ci'
init_connect='SET NAMES utf8'
character-set-server=utf8
collation-server=utf8_unicode_ci
skip-character-set-client-handshake
skip-name-resolve

三、建立Slave例項

  • 進入伺服器192.168.3.14

1、同上面操作一樣

# 建立目錄
mkdir -p /home/apps/mysql-slave-01/{config,log,data}

# 啟動容器
docker run -d --name mysql-slave-01 \
--restart=always \
--privileged=true \
-p 3310:3306 \
-v /home/apps/mysql-slave-01/config:/etc/mysql/conf.d \
-v /home/apps/mysql-slave-01/log:/var/log/mysql \
-v /home/apps/mysql-slave-01/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
mysql:8.0.26


# 修改Slave基本配置
vim /home/apps/mysql-slave-01/config/my.cnf

# 新增以下內容
[client]
default-character-set=utf8
 
[mysql]
default-character-set=utf8
 
[mysqld]
init_connect='SET collation_connection = utf8_unicode_ci'
init_connect='SET NAMES utf8'
character-set-server=utf8
collation-server=utf8_unicode_ci
skip-character-set-client-handshake
skip-name-resolve

四、主從配置

1、新增master配置

vim /home/apps/mysql-master/config/my.cnf
server_id=1

# 開啟二進位制日誌
log-bin=mysql-bin
read-only=0

# 需要同步的資料庫
binlog-do-db=rapid-cloud
binlog-do-db=rapid-cloud-test

# 需要忽略的資料庫
replicate-ignore-db=mysql
replicate-ignore-db=sys
replicate-ignore-db=information_schema
replicate-ignore-db=performance_schema

2、重啟容器

docker restart mysql-master

3、新增Slave配置

vim /home/apps/mysql-slave-01/config/my.cnf

server_id=2
log-bin=mysql-bin
read-only=1
binlog-do-db=rapid-cloud
binlog-do-db=rapid-cloud-test

replicate-ignore-db=mysql
replicate-ignore-db=sys
replicate-ignore-db=information_schema
replicate-ignore-db=performance_schema

4、重啟容器

docker restart mysql-slave-01

5、master新增帳號,用來同步的使用者

# 進入容器
docker exec -it mysql-master /bin/bash

# 進入主庫mysql資料庫
mysql -u root -p

# 授權root可以遠端訪問( 主從無關,為了方便我們遠端連線mysql)

# 授權遠端
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';

# 重新整理
flush privileges;


# 建立backup使用者

# 應先建立新使用者
create user 'backup'@'%' identified by '123456';

# 執行授權
grant all privileges on *.* to 'backup'@'%';

# 重新整理
flush privileges;

# 授權遠端
ALTER USER 'backup'@'%' IDENTIFIED WITH mysql_native_password BY '123456';

# 重新整理
flush privileges;

# 檢視主庫狀態
show master status;

6、在從庫裡設定主庫連線

# 進入容器
docker exec -it mysql-slave-01 /bin/bash

# 進入主庫mysql資料庫
mysql -u root -p

change master to master_host='192.168.3.13',master_user='backup',master_password='123456',master_log_file='mysql-bin.000001',master_log_pos=0,master_port=3310;

11、啟動從庫同步

  • 先將主庫的資料複製一份到從庫,包含表結構及資料
  • 將主庫binlog清除一下,這樣它的位置就從0開始了
purge master logs to'mysql-bin.000001';
  • 開啟同步
# 開始同步
start slave;

# 停止同步
# stop slave;

# 檢視同步狀態
show slave status\G;

12、錯誤排查

  • 如果無法實現主從同步,可以通過以下排查

13、總結:

  • 主從資料庫在自己配置檔案中宣告需要同步哪個資料庫,忽略哪個資料庫等資訊。並且server-id不能一樣
  • 主庫授權某個賬號密碼來同步自己的資料
  • 從庫使用這個賬號密碼連線主庫來同步資料

五、參考

相關文章