此文已由做者溫正湖受權網易雲社區發佈。
html
歡迎訪問網易雲社區,瞭解更多網易技術產品運營經驗。數據庫
開宗明義,keepsync和trysync是網易MySQL分支版本InnoSQL的兩個參數,很是重要的兩個參數。從某種程度上說,他們決定了MySQL主從複製實例是採用異步複製(async)仍是半同步複製(semi-sync)。爲何不得不說呢,由於不斷有同窗問怎麼看當前RDS實例是同步仍是異步狀態,keepsync和trysync這兩個參數是幹嗎用的,怎麼進行設置?因而簡單寫下semi-sync和這兩個參數關係。服務器
MySQL semi-sync異步
在MySQL中有個很是著名的semi-sync插件(plugin),或者叫半同步插件。若是將主從複製做爲一個系統, 處於半同步下的主從複製系統,即便主庫MySQL宕機且沒法修復,只要從庫MySQL正常, 用戶向該系統發送的已經返回commit的請求數據仍然不會丟失,知足事務ACID中的D(Durability)。這是在MySQL傳統的異步複製體系下邁出的很是具備里程碑意義的一步,其實在這一點上,InnoSQL一直處於領先的位置。爲何叫半同步複製,而不是同步(全同步)複製,這是由於在semi-sync複製下,主庫MySQL上事務記錄的Binlog信息,發送給從庫MySQL,在從庫MySQL的IO Thread將其以Relay-Log形式(本質上仍是Binlog,只不過披了一個馬甲)持久化後即向主庫MySQL返回ACK信息,而不是在SQL Thread(其實已經不是一個Thread了,姑且這麼說吧)將該事務對應的Relay-Log在從庫MySQL上執行後才返回ACK(這個就是全同步)。semi-sync之因此不丟數據,緣由就在於主庫只有收到從庫ACK信息後,纔會給用戶/客戶端返回事務已提交。顯然此時只要從庫存放Relay-Log的硬盤不壞,數據是不會丟的。不過最近看來,很不樂觀。:)async
雖然有這麼牛X一個插件,但默認狀況下MySQL複製仍是異步的。要開啓semi-sync,仍是簡單作幾個操做。先要在主從上都安裝semi-sync插件(主: INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';從:INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';);而後還要設置幾個參數(主:rpl_semi_sync_master_enabled=1;從:rpl_semi_sync_slave_enabled=1);固然,要從異步狀態切爲同步狀態,還須要從新start slave。在上述都作了以後,經過Rpl_semi_sync_slave_status 狀態值能夠查看當前複製是否已是semi-sync狀態(狀態爲ON)。是否是敲簡單。正常的,人一旦理解了一個技術或掌握了一個知識點,就會以爲其實挺簡單的。須要注意的是,semi-sync在某些場景下會退化爲異步,若是用戶不知情,恰好這個時候主庫MySQL掛了,那就悲劇了(丟數據了),因此,監控Rpl_semi_sync_slave_status狀態挺重要,固然,MySQL還提供了其餘幾個狀態用來觀察semi-sync複製狀態。那麼何時會退化爲異步呢,就得來講說rpl_semi_sync_master_timeout,超過所設置的微秒數後,主庫MySQL退化爲異步複製。默認時間爲1000,也就是若是主庫發送Binlog後,從庫1s以內沒有返回ACK,主庫就切異步了。若是用戶不想輕易切異步,就須要設置一個更大的值。但設置大了又會帶來了其餘問題。工具
InnoSQL加強.net
爲了更好得掌控實例semi-sync和async狀態切換,在InnoSQL中新增了兩個參數rpl_semi_sync_master_keepsyncrepl和rpl_semi_sync_master_trysyncrepl。用來更靈活得控制狀態切換行爲,部分取代rpl_semi_sync_master_timeout的做用,二者的取值均爲ON/OFF。固然,這兩個參數不是獨立起做用的,而是在前面所述的參數基礎上發揮做用的。不知不過前面所述的參數變爲了必要條件而非充分條件。插件
也就是說,即便rpl_semi_sync_master_enabled、rpl_semi_sync_slave_enabled均爲1,若是rpl_semi_sync_master_trysyncrepl爲OFF,複製狀態也沒法從async切換爲semi-sync。處於semi-sync狀態,即便rpl_semi_sync_master_timeout微秒內從庫未返回ACK信息,若是rpl_semi_sync_master_keepsyncrepl爲ON,則複製狀態也沒法從semi-sync切爲async。只有在用戶/系統管理員將rpl_semi_sync_master_keepsyncrepl改成OFF後才能切爲async。orm
這裏引出一個問題,用戶怎麼決定要不要切異步,根據什麼狀態來進行判斷呢? 顯然,一個事務已經花了多少時間等待ACK這個狀態很是關鍵,但MySQL並無提供該信息給用戶,因而在InnoSQL中加入了事務的ACK等待時間狀態,可用經過show processlist獲取ACK_WAIT_TIME或information_schema.processlist中的ACK_WAIT_TIME來了解每一個事務已花費的等待ACK時間狀態。用戶可規定一個閾值,經過查詢ACK_WAIT_TIME字段,若是有事務超過了閾值,那麼就設置rpl_semi_sync_master_keepsyncrepl爲OFF切異步。htm
RDS使用方式
接下來進一步聊下網易雲RDS如何使用semi-sync。RDS提供了兩種高可用實例,分別是同步實例和異步實例,但無論同步仍是異步實例,semi-sync插件均啓用,且rpl_semi_sync_master_enabled、rpl_semi_sync_slave_enabled均爲ON。區別在於rpl_semi_sync_master_trysyncrepl和rpl_semi_sync_master_keepsyncrepl值,同步實例兩個參數均爲ON,異步實例兩個參數均爲OFF。RDS支持用戶將異步實例修改成同步實例,重要的一步就是rpl_semi_sync_master_trysyncrepl和rpl_semi_sync_master_keepsyncrepl設置爲ON,也支持同步實例修改成異步實例,即將其設置爲OFF。
同步實例在出現從庫MySQL返回ACK超時(卡主)的時候,目前超時設置爲5s,會由RDS管理服務器將該實例設置爲修復中,實例複製臨時轉爲異步模式(關閉rpl_semi_sync_master_trysyncrepl和rpl_semi_sync_master_keepsyncrepl),重試從庫MySQL重啓,從新創建到主庫的複製關係,並嘗試轉爲同步模式(開啓rpl_semi_sync_master_trysyncrepl和rpl_semi_sync_master_keepsyncrepl),確認Rpl_semi_sync_slave_status爲ON以後(即轉同步成功),將實例從新置爲可用/運行中。
最後,上述描述僅聚焦於semi-sync的一些參數和狀態,並無詳細介紹semi-sync的原理、實現,介紹說明啓用semi-sync的具體步驟。
網易雲數據庫RDS是一種穩定可靠、可彈性伸縮的在線關係型數據庫服務,當前支持MySQL引擎,提供基礎版,高可用版,金融版針對不一樣業務場景的高可用解決方案,點擊可免費試用。
網易雲免費體驗館,0成本體驗20+款雲產品!
更多網易技術、產品、運營經驗分享請點擊。
相關文章:
【推薦】 遭遇各類內容監管,有些企業到底欠缺的是什麼,僅僅是價值觀嗎?
【推薦】 教你如何選擇BI數據可視化工具
【推薦】 關於《金字塔原理》的主要內容