docker的一大好處是在本地可以很方便快速的搭建負載均衡,主從同步等需要多主機的環境。
可以說是極大方便了運維成本和難度。
本節在本地搭建mysql的一主一從的集群環境。
關于主從同步的流程圖,放張網上找的流程圖
image.png
以mysql5.7為例
創建 mysql-master-slave 目錄,比如完整路徑是
D:/docker/mysql-master-slave
目錄結構如下:
-- master
-- data
mysqld.cnf
-- slave
-- data
mysqld.cnf其中master目錄底下的 mysqld.cnf 配置文件內容為
[mysqld]
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
datadir = /var/lib/mysql
#log-error = /var/log/mysql/error.log
# By default we only accept connections from localhost
#bind-address = 127.0.0.1
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
# 以下是新增內容
# 標識不同的數據庫服務器,而且唯一
server-id=1
# 啟用二進制日志
log-bin=mysql-bin
log-slave-updates=1
innodb_flush_log_at_trx_commit = 2
innodb_flush_method = O_DIRECT
skip-host-cache
skip-name-resolve
slave 目錄底下的 mysqld.cnf 內容為
[mysqld]
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
datadir = /var/lib/mysql
#log-error = /var/log/mysql/error.log
# By default we only accept connections from localhost
#bind-address = 127.0.0.1
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
# 以下是新增內容
server-id=2
log-bin=mysql-bin
log-slave-updates=1
# 多主的話需要注意這個配置,防止自增序列沖突。
auto_increment_increment=2
auto_increment_offset=2
read-only=1
slave-skip-errors = 1062
skip-host-cache
skip-name-resolve
- 基于官方mysql鏡像,運行兩個容器并指定一些參數
啟動 名稱為mysql_master的容器作為master數據庫
docker run --name mysql_master -d -p 3307:3306 -e MYSQL_ROOT_PASSWORD=123456 -v D:/docker/mysql-master-slave/master/data:/var/lib/mysql -v D:/docker/mysql-master-slave/master/mysqld.cnf:/etc/mysql/mysql.conf.d/mysqld.cnf mysql:5.7
docker run --name mysql_slave -d -p 3308:3306 -e MYSQL_ROOT_PASSWORD=123456 -v D:/docker/mysql-master-slave/slave/data:/var/lib/mysql -v D:/docker/mysql-master-slave/slave/mysqld.cnf:/etc/mysql/mysql.conf.d/mysqld.cnf mysql:5.7
這個時候宿主機的 Navicat 應該可以連上容器里的兩個數據庫了。
- 配置主從同步,新開終端進入容器
docker exec -it mysql_master bash
mysql -u root -p
創建一個同步數據權限的用戶
GRANT REPLICATION SLAVE ON *.* to 'backup'@'%' identified by '123456';
查看狀態,記住File、Position的值,在 Slave 中將用到
show master status;
image.png
進入slave容器
docker exec -it mysql_slave bash
mysql -u root -p
設置主庫鏈接
change master to master_host='172.17.0.2',master_user='backup',master_password='123456',master_log_file='mysql-bin.000001',master_log_pos=0,master_port=3306;
啟動從庫同步
start slave
查看狀態,如果 Slave_SQL_Running_State 是 Slave has read all relay log; waiting for more updates 表示正常運行。
show slave status \G
image.png
- 測試同步,在master上新建一個數據庫
docker exec mysql_master mysql -uroot -p123456 -e "CREATE DATABASE test"
docker exec mysql_slave mysql -uroot -p123456 -e "SHOW DATABASES"
總結:
mysqld.cnf 文件的由來?
答:就是從容器內的/etc/mysql/mysql.conf.d/mysqld.cnf
拷貝出來的主從同步的簡單原理?
答:
MySQL的主從復制是一個異步的復制過程,數據庫從一個Master復制到Slave數據庫,在Master與Slave之間實現整個主從復制的過程是由三個線程參與完成的,其中有兩個線程(SQL線程和IO線程)在Slave端,另一個線程(IO線程)在Master端。
master 數據變化時會產生bin log日志,slave上的線程拉去bin log,然后在slave上重新執行日志。這樣就保證了數據一致性。show slave status 中的Slave_IO_Running和Slave_SQL_Running的含義?
答:Slave 上會同時有兩個線程在工作, I/O 線程從 Master 得到數據(Binary Log 文件),放到被稱為
Relay Log 文件中進行記錄。另一方面,SQL 線程則將 Relay Log 讀取并執行。
為什么要有兩個線程?這是為了降低同步的延遲。因為 I/O 線程和 SQL 線程都是相對很耗時的操作。從服務器同步失敗?
答:看錯誤日志tail /var/log/mysql/error.log
重新執行同步
stop slave;
change master to master_log_file='mysql-bin.000100,master_log_pos=123'
關于 file 和 pos,需在master上執行show master status
獲得。
或者使用mysqlbinlog
命令分析。如何添加多個從節點?
和添加第一個從節點類似,先導出master的數據,復制第一個slave配置文件,唯一要改變的是server-id,不能和其他的重復。之后啟動新的容器,進到容器內執行change master to ...
。
還需要注意當前master沒有寫入等操作,最好先鎖表,同步設置好后在解鎖。參考
問題:
- 如何添加slave節點服務器,如何主主備份
更多細節還得啃官方文檔 - 使用 docker compose 配置mysql主從 http://tarunlalwani.com/post/mysql-master-slave-using-docker/
參考:
https://www.cnblogs.com/w2206/p/6963065.html
https://github.com/Junnplus/blog/issues/1