一個(gè)月后,我們又從 MySQL 雙主切換成了主-從!
你好,我是悟空。
一、遇到的坑
一個(gè)月前,我們?cè)跍y(cè)試環(huán)境部署了一套 MySQL 高可用架構(gòu),也就是 MySQL 雙主 + Keepalived 的模式。詳情看這篇:
??實(shí)戰(zhàn) MySQL 高可用架構(gòu)??
在這一個(gè)月遇到了很多坑:
- 因?yàn)閮蓚€(gè) MySQL 節(jié)點(diǎn)都可以寫入,極其容易造成主鍵重復(fù),進(jìn)而導(dǎo)致主從同步失敗。
- 同步失敗后,Slave_SQL_Thread 線程就停了,除非解決了同步的錯(cuò)誤,才能繼續(xù)進(jìn)行同步。
- 同步失敗的錯(cuò)誤,不會(huì)只有一條記錄有問題,往往是一大片的同步問題。
- 兩個(gè)節(jié)點(diǎn)互相缺少對(duì)方的數(shù)據(jù)。
- 主從的同步延遲,切換到新主庫后,數(shù)據(jù)不是最新。
- 當(dāng)出現(xiàn)不一致時(shí),無法確定以哪個(gè)庫為準(zhǔn)。
造成上面問題的主要原因就是因?yàn)閮蓚€(gè)節(jié)點(diǎn)都支持寫入 + 雙主可以隨時(shí)切換。
解決這種問題的方案有 改進(jìn)自增主鍵的步長(zhǎng)(影響未評(píng)估),使用 GTID 方案(未驗(yàn)證)。即使這樣,雙主同步的風(fēng)險(xiǎn)還是有,而且不同步后,如何處理是個(gè)大難題。
那么回到我們最初的想法:為什么會(huì)選擇雙主?
最開始的目的就是為了高可用。雙主就是說有一臺(tái) MySQL 節(jié)點(diǎn)掛了,另外一臺(tái)能夠頂上,對(duì)于用戶來說是無感的,給運(yùn)維人員一定的緩沖時(shí)間來排查 MySQL 故障。另外老的主節(jié)點(diǎn)恢復(fù)后,不用改配置就能立即成為從節(jié)點(diǎn)。
經(jīng)過這一個(gè)月的 MySQL 雙主模式的試運(yùn)行,最后我們還是決定切換到 MySQL 主-從模式。
雙主模式就是兩個(gè)節(jié)點(diǎn)即是主節(jié)點(diǎn)也是從節(jié)點(diǎn),那我們現(xiàn)在切換到一主一從模式,就可以認(rèn)為是降級(jí)。接下來我們聊聊雙主換成主從的思路和步驟。
二、雙主降為主從
雙主模式
雙主模式的原理圖如下:
兩個(gè)主節(jié)點(diǎn),都安裝了 KeepAlived 高可用組件,對(duì)外提供了一個(gè) VIP,只有一個(gè)節(jié)點(diǎn)接管 VIP,客戶端訪問的請(qǐng)求都是到這個(gè) VIP,另外一個(gè)節(jié)點(diǎn)處于待機(jī)狀態(tài)。
主從模式
和雙主不一樣的地方如下,從節(jié)點(diǎn)是只讀的。
一主一從是主從模式中的一種,具有以下特點(diǎn):
- 一個(gè)主節(jié)點(diǎn),一個(gè)從節(jié)點(diǎn),主節(jié)點(diǎn)提供給客戶端訪問,從節(jié)點(diǎn)只通過主節(jié)點(diǎn)的 binlog 進(jìn)行數(shù)據(jù)同步。
- 從節(jié)點(diǎn)是只讀的。從節(jié)點(diǎn)可以作為只讀節(jié)點(diǎn)提供類似報(bào)表查詢等耗時(shí)讀操作。
- 主節(jié)點(diǎn)宕機(jī)后,從節(jié)點(diǎn)成為主節(jié)點(diǎn),也是高可用的一種方案。
相對(duì)于雙主的高可用方案,不同之處如下:
- 主從切換需要用腳本將從庫設(shè)置為可讀可寫。
- 主從切換后,需要將從庫設(shè)置為不同步老主庫。
- 主從切換后,老的主庫恢復(fù)后,需要人工設(shè)置為只讀,且開啟同步新主庫的功能。
這樣來看,主從模式在異常情況下,多了些人工操作。
在異常情況下,主從切換一般是這樣處理的:通過腳本監(jiān)測(cè)主節(jié)點(diǎn)是否宕機(jī),如果主庫宕機(jī)了,則從庫自動(dòng)切換為新的主庫,待老主庫恢復(fù)后,就作為從庫同步新主庫數(shù)據(jù),新主庫上的 Keepalived 接管 VIP。
目前改為主從模式有兩種方式:
- 簡(jiǎn)單方式:人工切換模式,主節(jié)點(diǎn)故障后需要人工切換主從。
- 復(fù)雜方式:高可用方式,主節(jié)點(diǎn)故障后,主從自動(dòng)切換,讀寫分離自動(dòng)切換。
本篇只涉及簡(jiǎn)單方式,復(fù)雜方式的原理和配置步驟放到下篇專門講解。
三、改為主從的簡(jiǎn)單方式
簡(jiǎn)單方式的主從切換流程如下:
和雙主模式的主從切換的區(qū)別是,從節(jié)點(diǎn)是只讀的,Keepalived 沒有啟動(dòng),需要人工操作主從切換和啟動(dòng) Keepalived。
修改配置的步驟如下:
① 為了避免從節(jié)點(diǎn)上的 Keepalived 自動(dòng)接管 VIP 的情況出現(xiàn),將從節(jié)點(diǎn)的 Keepalived 停止,如果遇到主節(jié)點(diǎn)故障,則需要人工干預(yù)來進(jìn)行主從切換。從節(jié)點(diǎn)切換為主節(jié)點(diǎn)后,重新啟動(dòng)從節(jié)點(diǎn) Keepalived。
systemctl status keepalived
② 保留主節(jié)點(diǎn)的 Keepalived,保證 MySQL 的連接信息都不需要變。
③ 主節(jié)點(diǎn) node1 停用 MySQL 的同步線程。
STOP SLAVE
④ 從節(jié)點(diǎn) node2 設(shè)置 MySQL 為只讀模式。
# 修改 my.cnf 文件
read_only = 1
⑤ 移除主節(jié)點(diǎn) node1 同步 node2 MySQL 的權(quán)限。
⑥ 從節(jié)點(diǎn) node1 的開機(jī)啟動(dòng)項(xiàng)中移除 keepalived 服務(wù)自啟動(dòng)。
# 修改啟動(dòng)項(xiàng)配置
sudo vim /etc/rc.local
# 移除以下腳本
systemctl start keepalived
四、總結(jié)
雙主高可用的坑確實(shí)比較多,沒有 MySQL 的硬核知識(shí)真的很難搞定。筆者在這一個(gè)月的實(shí)踐中,深刻體會(huì)到了雙主同步的難點(diǎn)所在,最后還是選擇了一主一從的模式。
另外因?yàn)樽铋_始的配置都是雙主模式下的,所以要修改一些配置,來改為主從模式。因項(xiàng)目時(shí)間比較緊,目前采取的是非高可用的主從模式。
對(duì)于高可用的主從模式,因涉及的原理和步驟較多,我會(huì)在下篇中進(jìn)行講解。各位卷王也請(qǐng)給我一點(diǎn)時(shí)間進(jìn)行探索和實(shí)踐。