在ECS上自建MySQL手工容災環境

回雁發表於2016-12-13

1.環境介紹
很多雲上的客戶因為資料庫規模小,可能最開始只購買了ECS,而他們也需要資料庫伺服器,很可能會採用自建MySQL來實現。阿里雲RDS已經提供了完全的資料庫運維服務,包括監控、優化、主備高可用等。而對小白使用者來說,為了自己業務連續性和學習的需要,也是很有必要了解如何自建MySQL主備以及主備切換流程的。在主從複製實施前,單機單例項缺乏實時資料複製方案來保證例項出現故障時提供另一個完好且獨立的例項迅速切換,短時間內恢復客戶業務。

2.資料庫主從複製實施
2.1.主從複製原理
MySQL提供簡單可靠的主從複製機制供使用者使用,基本原理如下圖所示,分三個步驟:
(1) master將改變記錄到二進位制日誌(binary log)中(這些記錄叫做二進位制日誌事件,binary log events);
(2) slave將master的binary log events拷貝到它的中繼日誌(relay log);
(3) slave重做中繼日誌中的事件,將改變反映它自己的資料。
mysql複製.jpg
2.2.主從複製規劃
MySQL提供了主從複製元件,但是並不提供HA的自動監控切換。阿里集團內部有自研工具可以實現HA功能,開源元件keepalived + lvs也提供類似功能。這裡我們提一個帶SLB的方案,自動HA的實現留給讀者去研究。假設我們有2個MySQL例項,一個例項為A,一個為B,我們考慮使用主從雙向複製,即MM(Master-Master)的方案進行部署,前端掛給SLB,在同一個時刻,SLB只設定一個主用的例項權重為100,另一個備用例項權重為0,且將該例項的read_only引數開啟。在發生故障時,將備用例項的權重設成100,主用例項設成0,這樣通過SLB來實現手工的HA處理。對應用來說,將出現短時間(1-2分鐘)的不可用,當SLB的切換完成後,應用通過連線池的重連機制,能重新恢復業務。
2.3.主從複製實施
(1) 生產例項在一個已經存在的ECS上已經準備好,申請一個新的ECS,保證該ECS不與生產例項的ECS在同一個物理機NC。如果生產例項的MySQL是安裝在系統盤,可以從系統盤建立快照後打映象,新ECS依舊該自定義映象進行建立,這樣可以省略步驟
(2) 在新的ECS上安裝配置MySQL,儘可能保證配置與生產例項完全一致;
(3) 編輯生產例項的的/etc/my.cnf檔案,加入如下內容:
log-bin=/home/mysql/log/mysql-bin
server_id=1241823306
binlog_cache_size=32K
max_binlog_cache_size=2G
max_binlog_size=500M
binlog-format=ROW
sync_binlog=1
log-slave-updates=1
expire_logs_days=0
以上內容重點配置binlog,除server_id需要修改成IP地址後兩位+埠號以外,其他直接複製。比如示例中的3017441834的含義就是該mysql所在伺服器IP地址為:*.*.124.182,mysql佔用的埠是3306。
同時,需要保證/home/mysql/log目錄存在,mysql的起停使用者必須擁有對該目錄的許可權。
(4) 快速重啟MySQL生產例項,然後登入mysql檢視配置是否生效。
mysql資料庫都支援下面語句來停止例項:
mysqladmin -h127.0.0.1 -uroot -P3306 shutdown
檢視配置生效與否採用類似下列的語句進行檢查:
show variables like ’ log-bin%’
(5) 如果配置在生產例項生效,同樣的操作請在備用例項也操作一遍;
(6) 執行flush tables with read lock鎖定生產例項;
(7) 將生產例項的資料同步到備用例項,至少有兩種方案:對於生產例項與備用例項部署完全一樣的,可以直接將datadir目錄下所有檔案和目錄遠端複製到備用例項。對於生產例項和備用例項部署並不相同的,可以採用mysqldump將生產例項資料按DB匯出,然後再匯入到備用例項中。整個過程生產例項不能解鎖;
(8) 解鎖生產例項:unlock tables;
(9) 查詢生產例項的master狀態,記錄下來binlog日誌檔名以及對應的position編號;
(10) 在備用例項執行以下語句:
INSTALL PLUGIN rpl_semi_sync_master SONAME `semisync_master.so`;
INSTALL PLUGIN rpl_semi_sync_slave SONAME `semisync_slave.so`;
SET GLOBAL rpl_semi_sync_master_enabled = 1;
SET GLOBAL rpl_semi_sync_master_timeout = 10000;
SET GLOBAL rpl_semi_sync_slave_enabled = 1;
grant replication slave,replication client on . to repuser@`%`identified by `repuser`;
這裡,預設repuser的密碼也是repuser,但是mysql5.7版本的強制要求,密碼複雜度必須比較高,所以密碼需要設定成複雜密碼。
change master to master_host=`生產例項IP`,master_port=3306(生產例項埠),master_user=`repuser`,master_password=`repuser`, master_log_file=’步驟9記錄下的binlog檔名’, master_log_pos=’步驟9記錄下的binlog position編號’;
(11) 啟動備用例項slave,從生產例項複製資料。執行:start slave
(12) 檢查備用例項slave狀態:show slave status G;重點看兩個引數:
Slave_IO_Running和Slave_SQL_Running,如果這兩個引數值都為yes。則配置正確,已經開始複製;
(13) 接下來配置從備用例項到生產例項的反向資料複製,在備用例項檢查master狀態:show master status;同樣記錄下binlog檔名和位點資訊;
(14) 在生產例項重複步驟10-12完成反向複製配置。
(15) 結合SLB進行業務測試,觀察生產例項的資料是否實時同步到備用例項;
(16) 最後需要向所有例項的/etc/my.cnf檔案新增以下內容:
rpl_semi_sync_master_enabled=ON
rpl_semi_sync_slave_enabled=ON
同時,我們將備用例項設成只讀狀態:
set global read_only=1
3.災備切換流程
災備切換流程.jpg
流程圖裡A例項代表生產例項,例項B代表備用例項。
(1) 當A例項發生故障時,首先考慮重啟或者修復A,如果在短時間(30分鐘內)例項A能正常啟動,且啟動日誌和業務側檢查沒有問題,那麼證明業務恢復正常,緊急處理成功;
(2) 如果例項A緊急重啟成功,但是發現日誌中有報錯,請分析日誌報錯,判斷問題的影響範圍和大小,以決定忽略報錯或者修復報錯。如果在30分鐘內完成,依然可以認為業務成功恢復;
(3) 如果緊急重啟例項A成功,日誌中的報錯無法在30分鐘內修復,那麼我們啟動切換流程。即:
將備用例項可讀可寫開啟:set global read_only=0
在SLB將A例項的權重從100調成0,將B例項的權重從0調成100。保證業務先恢復起來;
(4) 例項B升成主例項對外提供服務時,我們在後臺儘快想辦法修復A例項,如果A例項修復成功,檢查BA兩個例項之間的複製關係是否正常,如果複製恢復正常,我們的緊急處理結束;
(5) 如果例項B生成主例項對外提供服務時,儘管我們修復了例項A。但是兩個例項間的複製關係無法再恢復正常,請根據2.3節中的步驟重新配置主從複製;
(6) 如果例項A在發生故障時完全無法恢復,比如ECS已經不能啟動。那麼直接進入切換流程,將例項B升級成主例項。然後在後臺緊急處理和恢復原來的A例項。

4.MySQL同步失敗修復
4.1.同步初始化失敗
在從庫上面執行:show slave statusG;
正常情況:
複製情況.png
錯誤情況:有NO出現。
修復方式:
在主庫上面執行:
Reset master;
在從庫上面執行:
Stop slave;
Reset slave;
Change master to master_host=`10.101.3.10`,master_port=3301,master_user=`repuser`,master_password=`repuser`,master_auto_position=1;
4.2.同步了部分資料中斷
在從庫上面執行 show slave statusG;
例如:
複製出錯.png
對於Slave_SQL_Running: No 的情況可以做如下處理:
在從庫上面執行:
slave stop;
SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1;
slave start;
然後通過show slave statusG; 檢查是否有兩個YES。


相關文章