看完還不懂Mysql主從複製來hu我

本文使用 Docker 搭建mysql一主一從的集羣環境 ,帶你一步步揭開mysql主從複製的神祕面紗

關於主從同步的流程圖,參考網上找的一張流程圖:
undefined

主從模式的優點

  1. 負載均衡:通常情況下,會使用 主服務器 對數據進行 更新、刪除 和 新建 等操作,而將 查詢 工作落到 從庫 頭上。
  2. 異地容災備份:可以將主服務器上的數據同步到 異地從服務器 上,極大地提高了 數據安全性。
  3. 高可用:數據庫的複製功能實現了 主服務器 與 從服務器間 的數據同步,一旦主服務器出了 故障,從服務器立即擔當起主服務器的角色,保障系統持續穩定運作。
  4. 高擴展性:主從複製 模式支持 2 種擴展方式:
    scale-up
    向上擴展或者 縱向擴展,主要是提供比現在服務器 性能更好 的服務器,比如 增加 CPU 和 內存 以及 磁盤陣列等,因爲有多臺服務器,所以可擴展性比單臺更大。
    scale-out
    向外擴展或者 橫向擴展,是指增加 服務器數量 的擴展,這樣主要能分散各個服務器的壓力。

主從模式的缺點

  1. 成本增加: 搭建主從肯定會增加成本,畢竟一臺服務器和兩臺服務器的成本完全不同,另外由於主從必須要開啓 二進制日誌,所以也會造成額外的 性能消耗。
  2. 數據延遲: 從庫 從 主庫 複製數據肯定是會有一定的 數據延遲 的。所以當剛插入就出現查詢的情況,可能查詢不出來。當然如果是插入者自己查詢,那麼可以直接從 主庫 中查詢出來,當然這個也是需要用代碼來控制的。
  3. 寫入更慢:主從複製 主要是針對 讀遠大於寫 或者對 數據備份實時性 要求較高的系統中。因爲 主服務器在寫中需要更多操作,而且 只有一臺 可以寫入的 主庫,所以寫入的壓力並不能被分散。

主從複製的前提條件

主從服務器 操作系統版本 和 位數 一致。
主數據庫和從數據庫的 版本 要一致。
主數據庫和從數據庫中的 數據 要一致。
主數據庫 開啓 二進制日誌,主數據庫和從數據庫的 server_id 在局域網內必須 唯一。

搭建集羣

本示例使用Mysql 5.7 作爲鏡像,使用docker-compose進行資源編排。

首先先對mysql 的master和slave進行配置,創建如下目錄問價結構
D:/docker/mysql-master-slave
結構樹:

  • master
    • data
    • mysqld.conf
  • slave
    • data
    • mysqld.conf

接着開始配置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

接着使用docker-compose進行資源編排:

version: '3'
services:
    mysql_master:
        #構建mysql鏡像
        image: mysql:5.7
        container_name: mysql_master
        command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci #設置utf8字符集
        restart: always
        environment:
          MYSQL_ROOT_PASSWORD: "root"
          MYSQL_USER: "root"
          MYSQL_PASSWORD: "root"
        ports:
          - '3307:3306' 
        volumes:
            #mysql數據庫掛載到host物理機目錄/d/docker/mysql/data
          - D:/docker/mysql-master-slave/master/data:/var/lib/mysql
          - D:/docker/mysql-master-slave/master/mysqld.cnf:/etc/mysql/mysql.conf.d/mysqld.cnf
    
    mysql_slave:
        #構建mysql鏡像
        image: mysql:5.7
        container_name: mysql_slave
        command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci #設置utf8字符集
        restart: always
        environment:
          MYSQL_ROOT_PASSWORD: "root"
          MYSQL_USER: "root"
          MYSQL_PASSWORD: "root"
        ports:
          - '3308:3306' 
        volumes:
          - D:/docker/mysql-master-slave/slave/data:/var/lib/mysql
          - D:/docker/mysql-master-slave/slave/mysqld.cnf:/etc/mysql/mysql.conf.d/mysqld.cnf

使用命令docker-compose up -d 啓動。

如果沒問題,進入mysql的master配置遠程連接,

docker exec -it mysql_master bash
# 剛開始默認沒密碼
mysql

# 支持root用戶允許遠程連接mysql數據庫
mysql> grant all privileges on *.* to 'root'@'%' identified by 'root';
mysql> flush privileges;
退出mysql:
mysql> exit

接着,使用數據庫連接工具就可以連上了。

下一步就是進入數據庫配置主從配置了,在終端中進入容器:

docker exec -it mysql_master bash
mysql -uroot -p

創建一個同步數據權限的用戶:

GRANT REPLICATION SLAVE ON *.* to 'backup'@'%' identified by 'root';

接着查看狀態,記住File、Position的值,在 Slave 中將用到

show master status;

image.png

退出當前容器,進入slave容器

docker exec -it mysql_slave bash
mysql -u root -p

設置主庫鏈接,注意master_log_file和master_log_pos要替換成自己相應的master信息,master_host的host可以通過docker inspect 容器id 獲得IPAddress

change master to master_host='172.17.0.2',master_user='backup',master_password='root',master_log_file='mysql-bin.000003',master_log_pos=439,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 -p -e "CREATE DATABASE test"
docker exec mysql_slave mysql -uroot -p -e "SHOW DATABASES"

image.png

可以看到同步成功了。

主從同步的簡單原理?
答:
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沒有寫入等操作,最好先鎖表,同步設置好後在解鎖。參考

基於主從配置搭建雙主備份配置

參考鏈接:
docker學習系列12 輕鬆實現 mysql 主從同步
https://blog.csdn.net/u012562943/article/details/86589834

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章