MyCat 默認字符集 UTF-8,但後端 MySQL 實例字符集可能不一致(latin1/utf8/utf8mb4)。本文通過四組對照實驗,驗證 character_set_client、character_set_server 對 MyCat 初始化連接池、心跳檢測、SQL 執行同步三個階段的影響,得出配置最佳實踐。
| 實驗組 | client | connection | database | results | server | system |
|---|---|---|---|---|---|---|
| 一(默認) | utf8 | utf8 | latin1 | utf8 | latin1 | utf8 |
| 二 | latin1 | latin1 | latin1 | latin1 | latin1 | utf8 |
| 三 | latin1 | latin1 | utf8 | latin1 | utf8 | utf8 |
| 四(推薦) | utf8 | utf8 | utf8 | utf8 | utf8 | utf8 |
觀測:日志輸出 charset= 值與後端 character_set_server 一致。
結論:連接池建立時,MyCat 作為客戶端連接後端,受後端 server 字符集影響(Server 端會話級字符集初始化)。
觀測:心跳 SQL SELECT USER() 返回的字符集信息與後端 character_set_server 一致。
結論:心跳檢測復用連接池連接,字符集行為同初始化階段,由後端 server 決定。
現象:多節點字符集不一致時,心跳日志會顯示不同節點返回不同 charset(如 localhost=utf8,其餘=latin1)。
觀測:日志中 charset= 值與前端應用設置的 character_set_client 一致。
結論:MyCat 接收前端連接時,根據前端攜帶的字符集(或默認 UTF-8),在執行 SQL 前向後端發送 SET NAMES charset 同步連接字符集。
機制:MyCat 連接池管理器在借出連接前,會根據前端會話字符集調用 SET CHARACTER SET/SET NAMES 確保編碼一致。
| 階段 | 決定因素 | 影響範圍 | 配置建議 |
|---|---|---|---|
| 連接池初始化 | 後端 character_set_server | 連接建立、心跳 | 後端統一設置為 utf8mb4 |
| 心跳檢測 | 後端 character_set_server | 健康檢查、主從切換判斷 | 同上,避免心跳字符集不一致誤判 |
| SQL 執行同步 | 前端 character_set_client | 業務數據讀寫、編碼轉換 | 應用層統一設置 UTF-8/utf8mb4;MyCat 默認即可 |
[mysqld]
character_set_server = utf8mb4
collation_server = utf8mb4_general_ci
init_connect = 'SET NAMES utf8mb4'
jdbc:mysql://mycat:8066/db?characterEncoding=utf8&useUnicode=true
# 或
spring.datasource.hikari.data-source-properties.characterEncoding=utf8
Incorrect string value、Illegal mix of collationsMyCat 字符集處理遵循「後端決定連接池基礎字符集,前端決定業務執行字符集」的雙層機制。生產環境**強制統一後端 server=utf8mb4、應用 client=utf8mb4**,消除編碼轉換風險。心跳檢測字符集差異僅為現象,不影響業務正確性,但建議統一以便觀測排查。