MySQL主從復制(一)
web一般是拒絕用戶上傳的,webdav可以實現數據上傳
MySQL的擴展方式:
scale up:
scale out:
一、MySQL的擴展:
復制:每個node都有相同的數據集
從node請求主node的二進制日誌,在本地進行重放實現
復制的作用:
數據分布:
負載均衡://讀均衡,寫操作不能負載均衡
數據備份://主node掛了,切換從為主 //冷備是最可靠的
高可用性能提升
可以寫腳本實現故障轉移。//mysql內部沒有提供故障轉移
MySQL升級測試:
【master】【slave】 //主從復制功能,主node必須啟用二進制日誌功能。
slave使用msyql協議請求master的二進制日誌文件事件
master所有的寫操作,除了在本地保存到數據庫中,還會將寫入[語句]保存到二進制日誌
slave請求binary log的時候,可以指定位置,不指定的話
就從第一個文件的最開始,逐個發送給slave
從node收到master二進制日誌後,保存到自己的中繼日誌中,記錄讀取到的位置[position]
master啟動一個dump線程接受slave的請求,然後用dump線程響應客戶端
slave留到中繼日誌中,然後在本地reply一次
二、復制相關線程:
主node:
主node的dump線程;為每個slave的I/O線程啟動一個dump線程,用於向其發送binary log events
從node:
io thread:從node負責從master獲取並保存到中級日誌
sql thread: 讀取並應用中級日誌
從node需要保存binary log嗎?
binary log:用於實現重放和恢復
但是一個slave可以其另外一個slave的master
//slave有自己的slave的話,該slave需要開啟二進制日誌
級聯復制:
[master]--[slave]--[slave]
三、mysql復制的特點:
1.異步,主node並不需要等待從node返回寫入結果
同步問題:一旦網絡故障,master不能訪問,將癱瘓
異步問題:通過slave未必能讀到完整的數據
slave會落後於master的內容
好處:在master上操作失誤,可以在slave上進行還原,slave切換為主
例如在master上誤操作:drop tables
2.延遲:
master在二進制日誌中寫入的速度一定會慢於本地執行的速度
而slave獲取二進制的速度也會慢於二進制日誌的寫入速度
本地執行>二進制日誌>slave獲取二進制日誌
調度器/LB //七層調度,能夠識別sql語句的寫和讀操作,並且能夠實現負載均衡
/ |\
[] [] []
//調度器一般稱為:r/w spliter :讀寫分離
從node不可避免的要落後於master,也可以把最新的請求,調度到master進行讀
r/w spliter:檢查狀態
mysql的query cache:假如查詢調度到同一個slave提高緩存命中率,但是損害LB效果
可以在[調度器/LB] + memcahed //
slave宕機:重新調度即可
master宕機:不能執行w操作。可以把一個slave提升為master
如何選取哪一個為主:
A:1,2,3
B:1,2,5
C:1,2,3,4
//選舉哪一個呢?各有自己的
//恢復有很多問題,
在mysql 5.6之後,引入了gtid:全局事務id
在此之前tid都是本地的,無法判斷哪一個slave完成的事務多
A要想成為master:從B獲取5,從C獲取4,然後自己成為master
//這種方案,不推薦,很難實現。需要結合gtid和oracle為mysql提供的大量的工具實現
其他方案:
corosync高可用mysql
[master][passive] [slave][slave]
\ /
[共享存儲]
//passive節點和master共享vip,故障轉移即可
SAN:存儲區域網絡
passive和master可使用共享存儲
但是共享存儲:存在單點故障
drbd:分布式磁盤快識別,兩個塊設備實現跨主機同步
MySQL的內存和io消耗量比較大
硬件性能也非常好
到一定階段就再擴展,性能可能不會上升,反而會下降
四、如何實現節點間數據同步 //scale out
方案一:共享存儲
【LB】
/ \
[] []
\ /
[ ] //共享存儲,需要使用集群fs
//對數據施加鎖,對於集群fs來說,他的擴展數量是有限的,到達4-8個,差不多到上線了
//該方案可看不可用
方案二:多個數據集
【LB】
/\
[][]
||
[][] //使用副本集,一個node rw,其他node只能讀
//每一個node保存完整的數據副本,只有一個node接收w請求,其他節點都通過同步或者復制的機制事先復制。
雙主模型:
A和B都即是主node也是對方的從node
[A][B]
[2][relay][file][2][relay][file]
//2:二進制日誌
//A和B本地有數據文件、中繼日誌、二進制日誌
通過serverid避免循環復制,根據serverid區分是自己傳輸給別人的。
A和B都能讀和寫
讀請求被負載了,寫請求雖然被LB了,但是實際還是需要A和B都寫入
目的:冗余,不用做讀寫分離了,實現了HA
雙主模型可能會導致數據不一致?
兩個節點互為條件的,
tom 20歲
A:年齡>=20的工資翻倍
B:年齡大於20的,減去2歲,
那麽最後怎麽合並
MMM:雙主模型解決方案
MHA:現在用的較多
percona:Galera-Cluster:在塊級別實現復制 //較可靠的方案
mysql的主從復制:
1.異步復制
2.主從復制不一致比較常見
復制架構:
1.M/S
2.M/M
3.環狀復制:每一個node都是上家的slave,又是下家的master
一主多從,一從再從:級聯復制
一從只能有一個主
現在一從可以多主,可以從兩個master復制不同的數據庫
Mairadb 5.6 之後的版本,支持最後進行匯聚
主從
master需要接受w請求,並且啟動n個線程,分發二進制日誌給各slave
//master的壓力依然有點大
如果master只需要復制一份二進制日誌
級聯可以實現
master->slave1-->[A,B] //slave1負責讀和二進制日誌分發
master->black hole引擎->[A,B] //black hole引擎所在node不存儲數據,只負責分發二進制日誌
二進制日誌事件記錄格式:
STATEMENT 基於語句的
ROW 基於行的,最好的方案,但是最占用空間
MIXED 混合模式,這種方案
演示的模型:
主從、主主、半同步復制(google)、復制過濾
半同步復制:
一主多從
master接受到請求後,至少等待一個從node同步完成,並告訴master數據已經存儲ok,才會返回給client ok
//一個slave同步,其他異步:半同步模型
復制過濾:
主從復制架構中,主有10個庫,但是從只想復制5個庫
過濾器:可以在主node過略,也可以在slave實現
主:二進制日誌記錄的時候,只記錄指定的庫,因此從只能獲取有限的二進制日誌
從:浪費帶寬,我只要5個,但是你給我發送10個
五、實現主從復制
192.168.100.67 master
192.168.100.68 slave
配置過程:
master:
1.啟動二進制日誌
2.為當前node設置一個全局唯一的id號
3.創建一個有復制 權限的用戶賬號
replication slave,replication client //權限
slave:
1.啟動中繼日誌
2.位當前node設置一個全局唯一的id號
3.使用有復制權限的用戶賬號連接至master,並啟動復制線程
master
vim my.cnf
[mysqld]
log-bin=mysql-bin //註意log_bin和log-bin都可以使用,建議統一
server-id=1
innodb_file_per_table=ON
skip_name_resolve=ON
systemctl start mariadb.service
mysql> show global variables like ‘%log%‘
查看log_bin是否啟用
mysql> show logs //查看二進制日誌
mysql> show variables like ‘%server%‘
mysql> grant replication slave,replication client on *.* to [email protected]%.%‘ identified by ‘replpass‘;
註意卡其3306端口的防火墻
slave:
relay_log=reley_log
relay_log_index=relay-log.index
server-id=7 //
innodb_file_per_table=ON
skip_name_resolve=ON
systemctl start mariadb.service
mysql> show gloabl variables like ‘%log%‘;
rely_log = rely_log //日誌開啟
mysql> show global variables like ‘%server%‘;
change master to master_host=‘192.168.100.67‘,master_user=‘repouser‘,master_password=‘repopass‘,maser_log_file=‘master-bin.00003‘,master_log_pos=245;
master_user= //
master_host= //主機
master_port= //端口
master_password=
master_connect_retry= //多長時間重連一次,假如不能連接的話
master_log_pos= //復制的二進制日誌的位置
master_heartbeat_period= //多長時間進行一次心跳檢測
ignore_server_ids= //忽略哪些server id 的
show slave status //查看自己的狀態
help start //啟動復制線程
start slave; //默認啟動sql_thread和io_thread
show slave staus ; //stop slave關閉線程
master:
crete database mydb;
show master status //查看二進制文件到哪一步了
slave:
show slave status;
//查看復制到哪裏了
MySQL主從復制(一)