1. 程式人生 > >Mysql5.6雙主複製

Mysql5.6雙主複製

通過lvs和mysql slaves的組合應用,資料庫查詢類的請求可靠性已被大大提升,但是出於核心地位的master節點仍是單點。

通過了解mysql的複製特性可以知道,master節點的資料是有冗餘的,slave節點就是它的冗餘,若但從資料角度上看,可以說master節點不存在單點,因為即使master節點出現故障,正產情況下資料仍然是安全的(只要slave節點沒有跟著宕機)。

Mysql中的主或從兩個角色都是邏輯上定義的,也就是說slave節點和普通的例項沒有區別,也是可以對外提供服務的,從這個角度上看,如果master節點遇到故障,隨便挑一臺slave出來做為新的master節點就好了。這個過程也就是通常講的故障切換。

傳統複製環境中的master節點和slave節點進行切換後,存在兩方面問題,一是當某個slave節點升級為master節點後,即便原master節點從故障中恢復,也回不到複製環境中了,至於原來複制環境中的其他slave,稍有意外,就同樣也不屬於複製環境了。

一. 實現故障隨意切換

第一個問題,由於slave節點是單向從master節點接收資料,一旦故障切換後,原master節點沒有資料來源,與新的master節點資料差異越來越大,因此無法繼續成為複製環境中的一員,如果能夠讓master節點也能獲取並應用salve節點產生的二進位制日誌,另其互為主從,那麼無論怎樣切換,另一個節點也不會脫離複製環境了

1. 實現master和slave的雙向複製

--查詢slave節點的二進位制日誌檔案和讀寫位置

mysql> show master status;
+---------------+----------+--------------+------------------+-------------------+
| File          | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+---------------+----------+--------------+------------------+-------------------+
| binlog.000006 |      120 |              |                  |                   |
+---------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

--在master節點,使其從slave節點的指定位置開始讀取二進位制日誌

mysql> change master to 
    -> master_host='192.168.48.51',
    -> master_port=3306,
    -> master_user='repl',
    -> master_password='mysqld',
    -> master_log_file='binlog.000006',
    -> master_log_pos=120;
Query OK, 0 rows affected, 2 warnings (0.38 sec)

--啟動master節點的slave服務

mysql> start slave;
Query OK, 0 rows affected (0.02 sec)
--驗證資料同步即可

2. 雙向複製的隱患

Mysql的複製環境,主從之間一致性完全依賴於二進位制日誌,這個二進位制日誌不管是生成、接收還是應用,都是邏輯上的,邏輯是沒辦法保證兩者完全相同的。

比如兩個節點同時執行寫操作,並且寫入同一個物件,在高併發的環境中時很有可能出現的。這種場景,如果兩端寫入不同的記錄,sql語句執行後出現問題的機率會比較小,不過若兩端同時寫入相同的記錄,操作風險就比較高了。語句有可能正常進行,但日誌傳送到slave節點在應用時有較大機率出現問題。

尤其是mysql表物件的主鍵通常都是自增長的,插入記錄往往無需指定主鍵值,這種情況下,若同時在兩個節點分別向一個物件中插入資料,即使明確指定列值是不同的,兩邊產生的主鍵也極有可能重複。

模擬上述情景:暫停一端的slave服務,然後在另一端執行插入操作,而後轉回被暫停的節點上也執行插入操作,再啟動該節點的slave服務

--暫停一端(192.168.48.51)的salve服務

mysql> stop slave;
Query OK, 0 rows affected (0.32 sec)

--在另一端(192.168.48.50)插入資料

mysql> insert into test1 (v1) values('192.168.48.50');
Query OK, 1 row affected (0.33 sec)

--在暫停複製的節點也插入一條資料

mysql> select * from test1;
Empty set (0.00 sec)

mysql> insert into test1 (v1) values('192.168.48.51')
    -> ;
Query OK, 1 row affected (0.06 sec)

--啟動本地salve服務

               Last_SQL_Error: Could not execute Write_rows event on table test.test1; Duplicate entry '1' for key 'PRIMARY', Error_code: 1062; handler error HA_ERR_FOUND_DUPP_KEY; the event's master log binlog.000006, end_log_pos 452

--另外一個節點(192.168.48.50)上也在報這個錯誤

3. 處理sql執行緒錯誤

處理salve服務應用過程中出現的錯誤,從操作上分為兩個步驟:

a. 修復匯出出現錯誤的sql語句涉及的資料,就本例而言,由於主鍵衝突導致兩端寫入的資料未能同步,手工在兩端各自執行報錯的sql語句是不行的,一方面會導致資料不一致,另一方面是治標不治本,後面還會出現資料衝突的錯誤,以致沒完沒了,如果可以的話最好刪除源端對應的記錄,然後重新執行一遍

b. 跳過錯誤,繼續應用後面的日誌。Mysql複製環境中的slave節點在應用二進位制日誌時,只要碰到錯誤,就會暫停應用程序,在錯誤被修正之前,該執行緒是無法啟動的。然而mysql的複製屬於邏輯複製,因此遇到無法在salve節點應用的事件,可以選擇先跳過它,繼續後面的變更事件,對此,mysql提供了sql_slave_skip_counter系統變數,該變數用於執行跳過最近的n次事件,預設為0.

基於上面的兩點,處理sql執行緒應用錯誤:

--在兩個節點上都要執行

mysql> set global sql_slave_skip_counter=1;
Query OK, 0 rows affected (0.00 sec)

mysql> start slave;
Query OK, 0 rows affected (0.00 sec)

--在任意節點上執行

mysql> delete from test1 where v1 in ('192.168.48.50','192.168.48.51');
Query OK, 1 row affected (0.05 sec)

mysql> insert into test1 (v1) values('192.168.48.50');
Query OK, 1 row affected (0.01 sec)

mysql> insert into test1 (v1) values('192.168.48.51');
Query OK, 1 row affected (0.01 sec)

mysql> select * from test1;
+----+---------------+
| id | v1            |
+----+---------------+
|  2 | 192.168.48.50 |
|  3 | 192.168.48.51 |
+----+---------------+
2 rows in set (0.00 sec)

3. 避免自增列值衝突

要解決自增列值衝突問題,簡單且直接的方式,是同時只允許應用層連線雙主環境中的某一個節點,或者說寫入操作只允許在一個節點上執行,這樣就可以避免自增列因為多節點併發寫的緣故造成重複,不過它並不能完全避免自增列衝突。

比如當前提供寫入服務的master節點出現故障,由於一些原因,二進位制日誌未能完全傳播到待切換的master節點,那麼在新的master節點上在生成自增列的列值時,就會生成原master節點已經生成過的自增值,當原master節點從故障中恢復過來時,複製程序的應用又會出現錯誤。


可以從mysql自增列的生成規則上考慮這個問題:

Auto_increment_increment:執行遞增列增長時的遞增值,範圍從1-65535,預設值為1,也可以指定為0,不過當指定為0時,效果等同於1.

Auto_increment_offset:指定自增列增長時的偏移量,也就是自增列的初始值。

結合這兩個值,我們可以為不同的例項指定不同的自增值規則,比如講兩個節點的遞增至都改為2,其中一個節點的偏移量設定為1,另外一個節點的偏移量改為2,這樣其中一個節點生成的值始終為奇數,另外一個節點始終為偶數。但這樣設定之後,批量插入的序號之間會有間隙(gap),如果業務對記錄序號連續性有要求,就不適用了。

二. keepalived實現ip自動漂移

由於雙機讀寫可能會遇到眾多的問題,所以實際應用中,最好的方式還是由前端應用層執行寫操作時只連線DB環境中的某一個master節點,另外的節點將其視為slave節點,對外提供只讀服務。儘管沒有了負載均衡的能力,但加強了高可用性並降低了應用層開發的難度。當發生故障時,原master節點的ip能夠漂移到新的master節點(當前slave),這樣切換對前端應用也是透明的,無需進行額外改造。

這次將keepalived安裝到執行mysql服務的兩個master節點上。設定keepalived服務持有vip:192.168.48.56 ,這個ip地址由keepalived服務託管,他會自動將之繫結到某一臺mysql例項,前端應用連線該ip地址即可,當繫結的例項出現故障時,keepalived自動把vip繫結到另一臺處於活動狀態的mysql例項。

1. 在兩臺master節點安裝keepalived

2. 配置master節點

--keepalived配置檔案

[[email protected] keepalived]# vi /etc/keepalived/keepalived.conf
vrrp_script check_run {
script "/usr/local/keepalived/bin/ka_check_mysql.sh"
interval 10
}

vrrp_instance VPS {
state BACKUP #初始時指定兩臺伺服器均為備份狀態,以避免服務重啟時可能造成的震盪(master角色爭奪)
interface eth0
virtual_router_id 34
priority 100 #優先順序,另一節點本引數值可設定的捎小一些。
advert_int 1
nopreempt #不搶佔,只在優先順序高的機器上設定即可,優先順序低的不設定
authentication {
auth_type PASS
auth_pass 3141
}
virtual_ipaddress {
192.168.48.56
}
track_script {
check_run
}
}
--建立mysql檢測指令碼
[[email protected] ~]# cat /usr/local/keepalived/bin/ka_check_mysql.sh
#!/bin/bash
MYSQL_USER=root
MYSQL_PASS=mysqld
MYSQL_CMD=/u01/my3306/bin/mysql
CHECK_TIME=3 #check three times
MYSQL_OK=1 #MYSQL_OK values to 1 when Mysql service working fine,else values to 0

function check_mysql_health() {
$MYSQL_CMD -u${MYSQL_USER} -p${MYSQL_PASS} -S /u01/my3306/run/mysql.sock -e "show status;" > /dev/null 2>&1
if [ $? = 0 ] ;then
MYSQL_OK=1
else
MYSQL_OK=0
fi
return $MYSQL_OK
}

while [ $CHECK_TIME -ne 0 ]
do
let "CHECK_TIME -= 1"
check_mysql_health
if [ $MYSQL_OK = 1 ] ; then
CHECK_TIME=0
exit 0
fi

if [ $MYSQL_OK -eq 0 ] && [ $CHECK_TIME -eq 0 ]
then
/etc/init.d/keepalived stop
exit 1
fi
sleep 1
done

--啟動keepalived服務

[[email protected] keepalived]# service keepalived start
Starting keepalived:                                       [  OK  ]
--keepalived持有的虛擬ip,通過ifconfig命令查不到,通過ip addr可以檢視到
此時vip在此master節點上
[[email protected] bin]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:0c:29:38:88:35 brd ff:ff:ff:ff:ff:ff
    inet 192.168.48.50/24 brd 192.168.48.255 scope global eth0
    inet 192.168.48.56/32 scope global eth0
    inet6 fe80::20c:29ff:fe38:8835/64 scope link 
       valid_lft forever preferred_lft forever

現在應用就可以通過192.168.48.56這個vip來訪問mysql例項了。

3. 配置另外一臺master節點

配置另外一臺master節點,唯一的不同是權重值低於第一個節點

4. 高可用測試

當前的檢測指令碼中,設定檢測時間為10s,也就是說當停止mysql服務後,最長可能需要等待10s,keepalived檢測到異常,然後出發ip地址漂移。

三. 雙主架構設計

前的架構,如果相應寫請求的master節點發生故障,vip切換至另外一臺master節點後,舊的master節點所屬的slave節點資料就無法更新,只有等到master節點恢復正常後,才能恢復資料。所以可以將slave節點分配個不同的master節點,保證master節點有slave在提供服務

注:mysql資料庫有一個read_only的系統引數,用於控制系統是否允許執行寫操作,建議在slave節點開啟,即設定為1以避免使用者將資料寫入slave節點。


相關推薦

Mysql5.6複製

通過lvs和mysql slaves的組合應用,資料庫查詢類的請求可靠性已被大大提升,但是出於核心地位的master節點仍是單點。 通過了解mysql的複製特性可以知道,master節點的資料是有冗餘的,slave節點就是它的冗餘,若但從資料角度上看,可以說master節點

MySQL高可用之複製模式

MySQL雙主模式高可用實現   生產案例:VIP:10.105.98.211MASTERHOSTNAME IPADDR PORTmy-prod01.oracle.com 192.168.10.97 3306 my-prod02.oracle.com 192.168.10.5 3306 SL

46、mysql複製實戰

雙主複製潛在的問題: 雙主模型恰巧雙方同時操作一組資料,左伺服器鎖住A欄位修改B欄位,右伺服器鎖住B欄位修改A欄位。雙方一同步資料可能出現不一致。 1、在兩臺伺服器上各自建立一個具有複製許可權的使用者; mysql GRANT REPLICATION SLAVE,REPLICATION CLIEN

CentOS6中MySql5.6資料庫主從複製/讀寫分離(二)

程式碼層面實現讀寫分離 在文章(一)中我們已經有了兩個資料庫而且已經實現了主從資料庫同步,接下來的問題就是在我們的業務程式碼裡面實現讀寫分離,假設我們使用的是主流的ssm的框架開發的web專案,這裡面我們需要多個數據源。 在此之前,我們在專案中一般會使用一

MySQL 高可用:複製複製

########################################################################################### linux: CentOS 5.6 mysql: 5.6.22

Heartbeat + haproxy + MySQL複製 實現讀寫負載均衡及高可用

目錄 四、總結 參考:         上一篇我們使用Heartbeat的HA功能,實現MySQL主從複製的自動故障切換。它的工作原理是:當Heartbeat啟動時,會將VIP繫結到haresources檔案中指定

MySQL5.7架構搭建(基於GTID方式)

系統:Centos6.5資料庫IP:192.168.0.103、192.168.0.104資料庫埠:都是3306搭建MySQL步驟 略(詳見:https://blog.csdn.net/xiaoyi23000/article/details/53200205)1、在103節點

MySQL5.6 機HA高可用部署方案

注:主、備機只有ucast一個引數不一樣。 8、新增資源配置檔案 vi /etc/ha.d/haresources mysql1 192.168.2.9/24/eth0:1 Filesystem::/dev/sdb1::/hadata::ext4 mysqld 注:主、備機的設定一致。 9、新增認證檔

使用MMM實現MySQL複製高可用

一、MMM簡介 1. 概述         MMM(Master-Master replication manager for MySQL)是一套支援雙主故障切換和雙主日常管理的指令碼程式。MMM使用Perl語言開發,主要用來監控和管理MySQL Master-Maste

CENTOS6.5 安裝 mysql5.6 以及搭建

關於 base ucc status mysq automake tables ++ 哪些 一、Mysql5.6.10安裝 1.1、必要軟件 yum -y install gcc gcc-c++ autoconf automake bison ncurses-dev

cool-2018-03-10-windows下實現mysql5.6讀寫分離、主從複製和一多從

mysql壓縮包移步下載:mysql5.6--主從資料庫的安裝第一步:複製mysql到自定義目錄中,我現在放的是 E:\cool\mysql,資料庫叫3380第二步: 刪除3380\logs目錄下的所有日誌檔案第三步驟: 刪除3380\datas所有的log檔案(注意不是所有

mysql5.6資料庫同步,單多從配置。

windows下MySQL5.6實現主從資料庫同步資料  mysql5.6資料庫同步,單向雙向同步問題 一.單向同步 主資料庫(mysql5.6)192.168.1.104 從資料庫(mys

mysql5.6版本基於GTID-docker方式-新環境沒有數據

.com gist mas hostname master system always bin 6.0 #(0)環境規劃 mysql版本:5.6 master01 : 192.168.19.131 master02 : 192.168.19.132 #(1)安裝doc

mysql5.6版本基於GTID-docker方式-庫有數據

bee wait host cti file word global gtid soc #(0)環境規劃 mysql版本:5.6 master01 : 192.168.19.131 master02 : 192.168.19.132 #(1)安裝docker和dock

mysql之 mysql 5.6不停機一從搭建(活躍一從基於日誌點復制)

stat 5.6 create 文件夾 eat ima send spec tar 環境說明:版本 version 5.6.25-log 主1庫ip: 10.219.24.25主2庫ip: 10.219.24.22從1庫ip:10.219.24.26os 版本: cento

MySQl5.6復制配置

MySQL5.6 主主復制實現原理 主主復制即在兩臺MySQL主機內都可以變更數據,而且另外一臺主機也會做出相應的變更。就是將兩個主從復制有機合並起來就好了。只不過在配置的時候我們需要註意一些問題,例如,主鍵重復,server-id不能重復等等。 安裝環境 server-1 IP:192.168.4.58

Mysql5.7.22+Keepalived互備高可用集群

msu ria 自己的 進行 pos 執行 elif 通知 file DB1:192.168.254.128DB2:192.168.254.129配置前進行校時操作#安裝ntpdate工具yum install ntpdate -y#使用ntpdate校時(後面的是ntp服

RocketMQ學習筆記(16)----RocketMQ搭建從(非同步複製)叢集

1. 修改RocketMQ預設啟動埠   由於只有兩臺機器,部署雙主雙從需要四個節點,所以只能修改rocketmq的預設啟動埠,從官網下載rocketmq的source檔案,解壓後使用idea開啟,全域性搜尋9876,將所有使用9876埠的地方改為9877。   在終端開啟,使用:mvn -Preleas

MySQL5.7多一從(多源複製)同步配置

MySQL5.7多主一從(多源複製)同步配置(抄襲) 原文地址:https://my.oschina.net/u/2399373/blog/2878650 多主一從,也稱為多源複製,資料流向: 主庫1 -> 從庫s 主庫2 -> 從庫s 主庫n -> 從庫s 應用場

mysql5.1.73 的玩法

A機: [client] #password       = your_password port            = 3306 socket