在RDS MySQL實例進行切換類的運維操作時,應用程序與代理的連接會有短暫的斷開,會對業務造成一定影響,您可以參考本文使用連接保持功能,保證連接不斷開,提升產品可用性,降低運維成本。
關于RDS數據庫代理的使用問題和更多相關信息,歡迎加入用戶釘釘群(106730000316)進行咨詢、反饋和交流 。
功能簡介
RDS MySQL代理的連接保持功能,即在發生實例切換類的操作時,能保持應用程序與代理的連接不斷開,用戶通過代理地址訪問數據庫的應用程序不會收到連接斷開的報錯,如下圖所示。
實現原理
數據庫代理連接分為前端連接(代理與客戶端的連接)和后端連接(代理與數據庫的連接),在執行實例切換類操作時,能夠在后端連接斷開的情況下,保留前端連接,代理在此基礎上實現了連接保持能力。
對于后端數據庫是RDS MySQL的連接,連接保持的關鍵在于后端連接(代理與后端RDS MySQL連接)的連接狀態恢復。
RDS MySQL的連接狀態通常包括系統變量、用戶變量、臨時表、字符集編碼、事務狀態和Prepare語句狀態信息等。本文將以set names utf8mb4作為連接狀態為例介紹RDS MySQL連接保持的實現原理。
主動切換:
主動切換場景下,RDS MySQL數據庫代理實現連接保持分為三個步驟:
包含主動切換的運維操作:
主動主備切換
升級小版本
修改重啟類參數(修改參數時需重啟實例)
變更主實例配置
開始切換:阻塞新的連接和新的請求
由于代理不具備事務保持能力,因此,對于不同狀態的會話,采取不同的處理方式:
阻塞期間事務活躍的會話:代理將放行請求到后端數據庫主節點執行。
阻塞期間新開啟的事務的會話:代理將阻塞請求,客戶端的現象是阻塞等待服務端回包。
阻塞結束事務仍活躍的會話:客戶端與代理的連接將會斷開,后端數據庫會對未提交的事務進行回滾。
切換中:切換存量連接
切換過程中會修改存量連接的切換狀態:
無法保持的連接:代理會將整個連接斷開。
能夠保持的連接:連接將會切換至新的數據庫節點。
連接池中原數據庫主節點的連接:會被清理。
切換完成:恢復連接
對于能成功保留的連接,代理與后端新的數據庫主節點建立連接,并且恢復連接狀態。
故障切換:
當系統出現故障時,RDS實例會自動進行主備切換,提升一個備節點為主節點,這種切換是非預期的,稱為故障切換(Failover)。
代理會緩存當前正在數據庫上執行或將要轉發的SQL語句。當數據庫發生故障時,代理與后端數據庫的連接將會斷開。代理感知到數據庫Failover后,不會立刻斷開與客戶端的連接,代理會將失敗的讀請求重新轉發到可用的數據庫節點,并且恢復連接狀態。
對于失敗的寫請求,代理不能確定數據庫是否寫成功,因此故障切換時的會話保持不支持寫請求。
開啟連接保持
您可以在線體驗(免費)基于連接保持功能的實例無感切換,實時觀察實例性能變化與功能效果,詳情請參見免費體驗RDS MySQL數據庫代理無感切換。
2024年01月09日起,符合開啟連接保持功能條件的RDS MySQL實例在開通數據庫代理時,會默認開啟連接保持功能。開啟連接保持功能后,您可以隨時關閉該功能。
前提條件
主動切換的連接保持
RDS實例滿足以下條件:
版本:MySQL 5.6或5.7或8.0
系列:高可用系列、集群系列
存儲類型:云盤、本地盤
代理類型:通用型、獨享型
已開通數據庫代理,且代理的內核版本不低于1.14.5_20231207。
故障切換的連接保持
RDS實例滿足以下條件:
版本:MySQL 5.6或5.7或8.0
系列:高可用系列、集群系列
存儲類型:云盤、本地盤
代理類型:獨享型
說明通用型數據庫代理僅支持主動切換場景下的連接保持,獨享型數據庫代理支持主動切換和故障切換場景下的連接保持。
已開通數據庫代理,且代理的內核版本不低于2.9.1。
開啟步驟
訪問RDS實例列表,在上方選擇地域,然后單擊目標實例ID。
在左側導航欄,單擊數據庫代理。
在基本信息區域,單擊連接保持右側的開啟。
說明若無連接保持字樣,說明您的實例不符合連接保持的開通條件。
使用連接保持
前提條件
已開通數據庫代理。
數據庫代理已開啟連接保持。
操作步驟
訪問RDS實例列表,在上方選擇地域,然后單擊目標實例ID。
在左側導航欄,單擊數據庫代理。
根據業務需要配置目標代理連接地址的訪問策略,詳情請參見配置數據庫代理連接地址訪問策略。其中讀寫類型設置為讀寫(讀寫分離)。
根據業務需要申請目標代理連接地址的內網/外網地址,詳情請參見設置數據庫代理連接地址。
在應用程序中,使用目標代理連接地址的內網/外網地址與端口號進行數據庫的連接。
數據庫實例進行切換的運維類操作時,數據庫代理會自動實現連接保持功能,使用代理連接地址的應用程序與代理的連接不會斷開。
使用限制
在切換過程中,連接保持功能無法保持如下場景中的連接:
MySQL服務端還沒有完全返回包的連接。例如,100 MB的結果集,只返回了50 MB的結果集,剩余的結果集還在返回中。
存在未提交的事務。
連接上使用過change user語句。
連接上使用過LOAD DATA語句。
存在臨時表。
通過代理地址進行Binlog訂閱的連接。
不支持FOUND_ROWS、ROW_COUNT和LAST_INSERT_ID函數的調用,這些函數可以調用成功,但是無法保證調用結果的正確性。其中
SELECT FOUND_ROWS()
的用法MySQL官方已不推薦,建議您將SELECT FOUND_ROWS()
替換為SELECT COUNT(*) FROM tb1
進行查詢,詳情請參見FOUND_ROWS()。
注意事項
由于連接會重連,所以使用
select connection_id()
查詢當前連接的thread id可能會變化。由于連接會重連,所以
show processlist
或者SQL洞察中顯示的IP地址和端口,可能會與客戶端實際的IP地址和端口不一致。如果連接上存在用戶自定義的變量,連接能保持,但用戶變量會失效。
關閉連接保持
前提條件
實例已開啟連接保持功能。
操作步驟
訪問RDS實例列表,在上方選擇地域,然后單擊目標實例ID。
在左側導航欄,單擊數據庫代理。
在基本信息區域,在連接保持右側單擊關閉。
功能測試
本文僅對主動切換場景進行測試。
測試環境
測試用RDS MySQL實例如下:
MySQL 8.0版本、高可用系列。
實例規格為8核16 GB獨享型規格(mysql.x2.xlarge.2c)。
測試工具:Sysbench
測試數據如下:
100張表,其中每張表包含40000行數據。
并發線程數為128。
測試方法
在不同運維場景下,測試RDS MySQL實例的連接保活率(即執行運維操作前后的連接保持比例)。
執行測試語句如下:
sysbench --db-driver=mysql --mysql-host=127.X.X.1 --mysql-port=3306 --mysql-user=username --mysql-password='' --tables=100 --table-size=40000 --threads=128 --mysql-db=sbtest --report-interval=5 --time=600 oltp_read_write run
上述測試語句中的關鍵參數含義如下:
db-driver:數據庫引擎
mysql-host:數據庫代理地址
tables:數據庫中的表數量
table-size:每張表包含的記錄條數
threads:并發線程數
time:測試時間,單位: 秒
測試結果
在如下測試的運維場景中,RDS MySQL實例均能保持100%的連接保活率。
主動切換場景 | 保活率 |
升級小版本 | 100% |
主動主備切換 | 100% |
變更主實例配置 | 100% |
修改重啟類參數 | 100% |
相關API
API | 描述 |
修改RDS實例的數據庫代理功能。 | |
查詢RDS實例的數據庫代理詳情。 |