PolarDB支持會話級連接池和事務級連接池,您可以根據業務場景選擇合適的連接池,幫助降低因大量連接導致的數據庫負載壓力。
注意事項
更改連接池設置后,僅對新建連接生效。如何修改連接池設置,請參見配置數據庫代理。
當前連接池功能不支持同一個賬號對不同IP有不同的權限。如果您為同一個賬號的不同IP設置了不同的庫或者表權限,開通連接池可能會導致權限錯誤問題。例如,
user@192.xx.xx.1
設置了database_a
的權限,而user@192.xx.xx.2
沒有database_a
的權限,可能會導致連接復用時權限出錯。如果業務頻繁使用
COM_STATISTICS
命令時,不建議啟用連接池功能。該命令在數據庫上的實現是先進行上鎖,然后再遍歷所有連接。而開啟連接池功能是將短連接轉變為長連接,這可能會導致長連接的數量增加,從而觸發該命令的瓶頸,進而導致性能下降。同時建議非必要情況下,盡量減少對該命令的調用,頻繁調用會造成嚴重的性能下降,進而影響整體業務的響應時間。本文介紹的功能是PolarDB數據庫代理的連接池功能。該功能并不影響客戶端的連接池功能,如果客戶端已經支持連接池,則可以不使用PolarDB數據庫代理的連接池功能。
會話級連接池
工作原理
會話級連接池用于減少短連接業務頻繁建立新連接導致MySQL負載高。當您的連接斷開時,系統會判斷當前的連接是否是一個閑置的連接,如果是閑置連接,系統將會代理該連接并保留在連接池中一小段時間,如果這時新的連接建立的話就會直接從連接池里獲得連接(命中的條件包括
user
、clientip
和dbname
等),從而減少與數據庫的建連開銷。如果沒有可用的連接,則走正常連接流程,重新與數據庫建立一個新的連接。使用限制
會話級連接池并不能減少數據庫的并發連接數。該優化只能通過降低應用與數據庫的建連速率來減少MySQL主線程的開銷,從而更好地處理業務請求,但是連接池里空閑的連接會短暫占您的連接數。
會話級連接池也不能解決由于存在大量慢SQL,導致的連接堆積問題,此類問題的核心是先解決慢SQL問題。
事務級連接池
工作原理
事務級連接池主要用于減少直接連接到數據庫的業務連接數,以及減少短連接場景下頻繁建連帶來的負載。
開啟事務級連接池后,客戶端與PolarDB代理間可以存在上千個連接,但代理與后端數據庫間可能只存在幾十或幾百個連接。
PolarDB代理本身并沒有最大連接數的限制,連接數的限制主要由后端數據庫中計算節點的規格決定。未開啟事務級連接池時,每條由客戶端發起的連接都需要在后端主節點和所有只讀節點上各創建一個對應的連接。
開啟事務級連接池后,當客戶端發送請求時,會先與PolarDB代理建連,代理不會馬上將其與后端數據庫建連,而是先從事務級連接池里查找是否存在可用的連接(判斷是否為可用連接的條件:
user
、dbname
和系統變量這3個參數值是否一致)。若不存在,代理會與數據庫創建一個新連接;若存在,則從連接池里直接拿出并使用,并在當前事務結束后將該連接放回事務級連接池,方便下個請求繼續使用。使用限制如下:
當執行以下行為時,鎖定連接,直至連接結束,即該連接不會再被放到連接池里供其它用戶連接使用。
執行PREPARE語句
創建臨時表
修改用戶變量
大報文(例如16 MB以上)
使用lock table
多語句
存儲過程調用
不支持FOUND_ROWS、ROW_COUNT和LAST_INSERT_ID函數的調用,這些函數可以調用成功,但是無法保證調用結果的正確性。其中:
1.13.11及以上的數據庫代理版本支持在
SELECT SQL_CALC_FOUND_ROWS * FROM t1 LIMIT *
語句后直接使用SELECT FOUND_ROWS()
命令。但MySQL官方已不推薦該用法,建議您將SELECT FOUND_ROWS()
替換為SELECT COUNT(*) FROM tb1
進行查詢,詳情請參見FOUND_ROWS()。支持在
INSERT
后直接使用SELECT LAST_INSERT_ID()
語句,來保證查詢結果正確性。
對于設置了
wait_timeout
的連接,wait_timeout
在客戶端的表現可能不會生效。因為每次請求都會從連接池中獲取連接,當wait_timeout
超時后,只有連接池中的后端連接會斷開,而后端連接斷開并不會導致客戶端連接斷開。除了
sql_mode
、character_set_server
、collation_server
、time_zone
這四個變量以外,如果業務依賴其他會話級別的系統變量,那么需要客戶端在建連之后顯式進行SET語句執行,否則連接池可能會復用系統變量已經被更改過的連接。由于連接可能會被復用,所以使用
select connection_id()
查詢當前連接的thread id
可能會變化。由于連接可能會被復用,所以
show processlist
或者SQL洞察中顯示的IP地址和端口,可能會與客戶端實際的IP地址和端口不一致。數據庫代理會將所有節點上的SHOW PROCESSLIST結果合并后再返回最終結果,而在事務級連接池開啟后,前端連接和后端連接的
thread id
無法對應。這導致執行KILL命令時可能會返回錯誤:ERROR 1094 (HY000): Unknown thread id:xxx。
連接池的選擇
您可以根據如下建議評估選擇是否開啟連接池以及開啟何種類型的連接池:
若業務使用的多為長連接且連接數較少,或者業務本身已具備較好的連接池,那么您可以不使用PolarDB的連接池功能。
若業務使用的連接數較多(如連接數需求上萬)或使用的是Serverless服務(即連接數會隨著業務端服務器的擴容而線性增加),且確認您的業務不涉及上述事務級連接池使用限制的場景,那么您可以選擇開啟事務級連接池。
若業務使用的純短連接,且業務使用場景中包含上述事務級連接池使用限制的場景,那么您可以考慮開啟會話級連接池。