1. 程式人生 > >MySQL之主從複製

MySQL之主從複製

MySQL主從複製原理介紹

MySQL的主從複製是一個非同步的複製過程(雖然一般情況下感覺是實時的),資料將從一個Mysql資料庫(我們稱之為Master)複製到另一個Mysql資料庫(我們稱之為Slave),在Master與Slave之間實現整個主從複製的過程是由三個執行緒參與完成的。其中有兩個執行緒(SQL執行緒和IO執行緒)在Slave端,另一個執行緒(I/O執行緒)在Master端。
  要實現MySQL的主從複製,首先必須開啟Master端的binlog記錄功能,否則就無法實現。因為整個複製過程實際上就是Slave從aster端獲取binlog日誌,然後再在Slave上以相同順序執行獲取的binlog日誌中的記錄的各種SQL操作

MySQL之主從複製

MySQL垂直分割槽

MySQL之主從複製

MySQL水平分片(Sharding)

MySQL之主從複製

對應shard中查詢相關資料
MySQL之主從複製

MySQL複製

###### 擴充套件方式: Scale Up ,Scale Out
  MySQL的擴充套件
 讀寫分離
複製:每個節點都有相同的資料集
向外擴充套件
 二進位制日誌
 單向
###### 複製的功用:
 資料分佈
 負載均衡讀
 備份
 高可用和故障切換
 MySQL升級測試

MySQL讀寫分離

讀寫分離應用:
mysql-proxy:Oracle,https://downloads.mysql.com/archives/proxy/
Atlas:Qihoo,https://github.com/Qihoo360/Atlas/blob/master/README_ZH.md
dbproxy:美團,https://github.com/Meituan-Dianping/DBProxy
Cetus:網易樂得,https://github.com/Lede-Inc/cetus
Amoeba:https://sourceforge.net/projects/amoeba/
Cobar:阿里巴巴,Amoeba的升級版
Mycat:基於Cobar, http://www.mycat.io/
ProxySQL:https://proxysql.com/

一主一從
MySQL之主從複製

一主多從
MySQL之主從複製

MySQL複製

1 主從複製執行緒:
 主節點:
     dump Thread:為每個Slave的I/O Thread啟動一個dump執行緒,用於向其
     傳送binary log events
 從節點:
    I/O Thread:向Master請求二進位制日誌事件,並保存於中繼日誌中
    SQL Thread:從中繼日誌中讀取日誌事件,在本地完成重放
2 跟複製功能相關的檔案:
    master.info:用於儲存slave連線至master時的相關資訊,例如賬號、密碼、
  伺服器地址等
   relay-log.info:儲存在當前slave節點上已經複製的當前二進位制日誌和本地
replay log日誌的對應關係
主從複製特點:
   非同步複製
   主從資料不一致比較常見
複製架構:
  Master/Slave, Master/Master, 環狀複製
  一主多從
  從伺服器還可以再有從伺服器
  一從多主:適用於多個不同資料庫
複製需要考慮二進位制日誌事件記錄格式
  STATEMENT(5.0之前)
  ROW(5.1之後,推薦)
  MIXED
主從配置過程:參看官網

https://mariadb.com/kb/en/library/setting-up-replication/
https://dev.mysql.com/doc/refman/5.5/en/replication-configuration.html

主節點配置:
(1) 啟用二進位制日誌
 [mysqld]
 log_bin
 (2) 為當前節點設定一個全域性惟一的ID號
 [mysqld]
 server_id=#
log-basename=master 可選項,設定datadir中日誌名稱,確保不依賴主機名
 (3) 建立有複製許可權的使用者賬號
 GRANT REPLICATION SLAVE ON *.* TO 'repluser'@'HOST' IDENTIFIED BY'replpass';
從節點配置:
(1) 啟動中繼日誌
 [mysqld]
server_id=# 為當前節點設定一個全域性惟的ID號
relay_log=relay-log relay log的檔案路徑,預設值hostname-relay-bin
relay_log_index=relay-log.index 預設值hostname-relay-bin.index
(2) 使用有複製許可權的使用者賬號連線至主伺服器,並啟動複製執行緒
 mysql> CHANGE MASTER TO MASTER_HOST='host',
MASTER_USER='repluser', MASTER_PASSWORD='replpass',
MASTER_LOG_FILE='mysql-bin.xxxxx', MASTER_LOG_POS=#;
 mysql> START SLAVE [IO_THREAD|SQL_THREAD];

聯機複製

如果主節點已經運行了一段時間,且有大量資料時,如何配置並啟動slave節點
   1 通過備份恢復資料至從伺服器
   2 複製起始位置為備份時,二進位制日誌檔案及其POS
  3 如果要啟用級聯複製,需要在從伺服器啟用以下配置
[mysqld]
log_bin
log_slave_updates
複製架構中應該注意的問題:
1、限制從伺服器為只讀
 在從伺服器上設定read_only=ON
注意:此限制對擁有SUPER許可權的使用者均無效
 阻止所有使用者, 包括主伺服器複製的更新
 mysql> FLUSH TABLES WITH READ LOCK;
2、RESET SLAVE
在從伺服器清除master.info ,relay-log.info, relay log ,開始新的relay
log ,注意:需要先STOP SLAVE
RESET SLAVE ALL 清除所有從伺服器上設定的主伺服器同步資訊如:
PORT, HOST, USER和 PASSWORD 等
3、sql_slave_skip_counter = N 從伺服器忽略幾個主伺服器的複製事件,
global變數
4、如何保證主從複製的事務安全
參看https://mariadb.com/kb/en/library/server-system-variables/
   在master節點啟用引數:
sync_binlog=1 每次寫後立即同步二進位制日誌到磁碟,效能差
 如果用到的為InnoDB儲存引擎:
 innodb_flush_log_at_trx_commit=1 每次事務提交立即同步日誌寫磁碟
 innodb_support_xa=ON 預設值,分散式事務MariaDB10.3.0廢除
sync_master_info=# #次事件後master.info同步到磁碟
   在slave節點啟用伺服器選項:
skip_slave_start=ON 不自動啟動slave
   在slave節點啟用引數:
 sync_relay_log=# #次寫後同步relay log到磁碟
 sync_relay_log_info=# #次事務後同步relay-log.info到磁碟

主主複製

主主複製:互為主從
容易產生的問題:資料不一致;因此慎用
   考慮要點:自動增長id
   配置一個節點使用奇數id
   auto_increment_offset=1 開始點
   auto_increment_increment=2 增長幅度
   另一個節點使用偶數id
   auto_increment_offset=2
   auto_increment_increment=2
###### 主主複製的配置步驟:
(1) 各節點使用一個惟一server_id
(2) 都啟動binary log和relay log
(3) 建立擁有複製許可權的使用者賬號
(4) 定義自動增長id欄位的數值範圍各為奇偶
(5) 均把對方指定為主節點,並啟動複製執行緒

半同步複製

預設情況下,MySQL的複製功能是非同步的,非同步複製可以提供最佳的效能,主
庫把binlog日誌傳送給從庫即結束,並不驗證從庫是否接收完畢。這意味著當
主伺服器或從伺服器端發生故障時,有可能從伺服器沒有接收到主伺服器傳送
過來的binlog日誌,這就會造成主伺服器和從伺服器的資料不一致,甚至在恢
復時造成資料的丟失

MySQL之主從複製

半同步複製實現:

主伺服器配置:
 mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME
'semisync_master.so';
 mysql>SET GLOBAL rpl_semi_sync_master_enabled=1;
mysql>SET GLOBAL rpl_semi_sync_master_timeout = 1000;超時長為1s
 mysql>SHOW GLOBAL VARIABLES LIKE '%semi%';
 mysql>SHOW GLOBAL STATUS LIKE '%semi%‘;
從伺服器配置:
mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME
'semisync_slave.so';
 mysql> SET GLOBAL rpl_semi_sync_slave_enabled=1;