近日,騰訊云CDB迎來MySQL
5. 7 版本的更新。MySQL 5.7GA版本從5.7. 9 到如今的5.7.18,版本已經越來越不變。從oracle官方版本發布的Release
Notes中,看到比來的兩個版本5.7. 17 和5.7. 18 主要是以bug修改為主。
眾所周知,騰訊云CDB for MySQL5. 7 版本除了性能的極大提升之外,也增加了很多新功能特性,好比GIS數據類型和空間索引,Json數據類型,Generated colum以及函數索引, 數據加密,還有Group Relication等等重磅功能。
而騰訊云上已經有用戶需要用到上述的一些功能,,所以也是從本年四月份就開始做TXSQL 5.7(TXSQL是騰訊云數據庫團隊維護的MySQL內核分支)的版本,并在四月底提交了版本進行測試。本次,騰訊云的TXSQL 5. 7 是基于MySQL 5.7. 18 版本。
目前騰訊云TXSQL 5. 7 的第一版,在復制強制一致、自動轉換MyISAM表為InnoDB表、增加差別的工作模式等方面有著非常重大的突破。
1. 復制強制一致
了解的人都知道,在MySQL的semisync設有超時機制,配置參數為rpl_semi_sync_master_timeout。一旦master在設定的時間內沒有比及slave的確認(好比網絡故障),semisync就會關閉,主動降級為默認的異步復制模式。異步復制模式最大的問題就是master不消等待slave的確認。那么當master掛掉的時候,切換到slave,就存在丟數據的可能。
針對數據可能丟失這一點,騰訊云在TXSQL
5. 7 增加了一個新的選項rpl_semi_sync_wait_forever。在其為ON的時候,master會一直等待slave的確認。如果長時間等不到確認,系統告警,這時候可以設置rpl_semi_sync_wait_forever為OFF,來喚醒master中的等待線程,同時將semisync降級為異步模式。在這種情況下,如果master在最終收到slave確認,并且slave追趕到最新的binglog后會自動開啟semisync。
11. 方案設計
(1) 設置rpl_semi_sync_master_timeout到一個無限大的值
這樣可以實現master一直等待,但是當想回到正常的timeout模式時,我們需要記住之前的rpl_semi_sync_master_timeout的設置值。這樣可能需要加一個系統的狀態變量來生存這個值。別的,這樣會導致在處理rpl_semi_sync_master_timeout值變革時的邏輯變復雜。
(2) 增加新變量rpl_semi_sync_wait_forever
既然在上一種方案需要一個新的狀態變量,騰訊云就直接增加一個變量來作為一直等待的開關。在rpl_semi_sync_wait_forever為ON的時候,master會一直等待slave的確認。如果長時間等不到確認,系統告警,則可以設置rpl_semi_sync_wait_forever為OFF,來喚醒master中的等待線程,同時將semisync降級為異步模式。在這種情況下,如果master在最終收到slave確認,并且slave追趕到最新的binglog后會自動開啟semisync。
(3)基于paxos的semisync
MySQL5. 7 中支持rpl_semi_sync_master_wait_for_slave_count,但在某一個slave沒有在rpl_semi_sync_master_timeout時間內返回確認,即即是master比及了rpl_semi_sync_master_wait_for_slave_count個slave的確認,master還是會從semisync降級到異步模式。在semisync中支持paxos協議會從根本上解決這個問題,實現真正意義上的強一致。
目前,騰訊云選擇的為(2)方案,這主要是因為,現網實例中基本都是一主一備,(3)的方案比較重,(2)的實現明顯優于(1)。方案(3)適合對強一致要求更高的應用場景,目前,騰訊云已經列入開發計劃,預計下半年推出。
1.2 實現原理
(1) 設置rpl_semi_sync_wait_forever為ON之后
a. 新進來的事務需要一直等待。

b. 之前老的事務如果發生超時,需要繼續等待。

因為如果用戶設置為ON之后,預期是不會發生超時。
(2)設置rpl_semi_sync_wait_forever為OFF
如果此時有一直在等待的事務,要喚醒。最初的方案是
signal_waiting_sessions_all()來喚醒這些事務,然后如果事務等待的時間超過了rpl_semi_sync_master_timeout,降級為異步模式。如果等待的時間wait_time
< rpl_semi_sync_master_timeout,那么繼續等待rpl_semi_sync_master_timeout -
wait_time。但是通過sysbench壓測發現這樣的方案會導致死鎖,。
所以最終的簡化方案是:

1.3 新增狀態

2. 自動轉換MyISAM表為InnoDB表
MyISAM表因為不支持事務,所以存在故障恢復丟數據的可能。在復制環境下,如果使用MyISAM表,master和slave就可能出現紛歧致情況。即使騰訊云強烈建議用戶只使用InnoDB表,但是還是無法制止用戶在某些情況仍然去使用MyISAM表。為了解決這個問題,騰訊云提供了新的選項,在建表的時候默認將MyISAM表轉為InnoDB表。
新增變量
可選值

由于InnoDB內部的一些限制,會導致有些情況下轉換失敗。
(1) auto-increment
在InnoDB中只允許定義一個自增列,而且這個列必需被定義為主鍵。在MyISAM中則無此限制。
(2) max key length
在InnoDB中,innodb_large_prefix關閉的情況下,max key length不能大于767,而在MyISAM中,則不能大于1000。
(3) row format
在InnoDB中,innodb_strict_mode開啟的情況下,row format FIXED是不支持的。
3. 增加差別的工作模式
除了復制強制一致、自動轉換MyISAM表為InnoDB表,這兩項功能的實現以外,在TXSQL 5. 7 中,騰訊云還為其增加了READ_ONLY模式。