1. 程式人生 > >MySQL主從復制(一)

MySQL主從復制(一)

mysql 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主從復制(一)