CHARACTER SET = utf8mb4CHARACTER SET = gbkstrcasecmp 比對主庫連接字符集 = utf8 → 返回 UTF-8 編碼字節流 (如 '中' = E4 B8 AD)
備庫連接字符集 = gbk → 返回 GBK 編碼字節流 (如 '中' = D6 D0)
程序直接比較字節流 → 不相等 → 誤報不一致
客戶端請求 → character_set_client → character_set_connection → 數據庫內部編碼
數據庫響應 → 內部編碼 → character_set_connection → character_set_results → 客戶端
關鍵參數:
character_set_client:客戶端發送數據編碼character_set_connection:連接層處理編碼character_set_results:結果集返回編碼character_set_database:當前庫默認編碼character_set_system:系統元數據編碼 (固定 utf8)| 方案 | 主庫連接 | 備庫連接 | 校驗結果 | 客戶端顯示 | 修復可行性 |
|---|---|---|---|---|---|
| 1. 各用各的 | utf8 | gbk | ✗ 失敗 | 正常 | 不可修復 |
| 2. 統一 gbk | gbk | gbk | ✓ 成功 | 正常 | ✗ 可能丟字 (utf8→gbk 不可逆) |
| 3. 統一 utf8 (推薦) | utf8 | utf8 | ✓ 成功 | 亂碼 (若客戶端 gbk) | ✓ 完全可修復 |
跨字符集校驗/修復,必須統一連接字符集為「編碼範圍最大」的那一方(utf8mb4 > gbk > gb2312 > latin1)。
-- 統一 utf8 連接後,備庫讀取的值已轉為 UTF-8 字節流
UPDATE slave_table
SET col = master_value
WHERE pk = ? AND col = slave_value; -- slave_value 為 UTF-8 編碼,精確匹配
若用方案 2 (統一 gbk):
-- 主庫 utf8 數據轉 gbk 時,Emoji/生僻字丟失 → slave_value 已殘缺
UPDATE slave_table SET col = master_value WHERE pk = ? AND col = slave_value;
-- WHERE 條件不匹配 (slave_value 丟字) → 0 rows affected → 修復失敗
# 校驗/修復程序連接參數 (統一)
charset = 'utf8mb4' # 或 utf8
use_unicode = True
# 禁用服務端字符集握手 (強制以客戶端為準)
# MySQL 連接串
jdbc:mysql://host:3306/db?characterEncoding=utf8mb4&connectionCollation=utf8mb4_general_ci
# 或代碼中顯式設置
SET NAMES utf8mb4; -- 等價於
SET character_set_client = utf8mb4;
SET character_set_connection = utf8mb4;
SET character_set_results = utf8mb4;
ALTER TABLE ... CONVERT TO CHARACTER SET utf8mb4,驗證無數據截斷/丟失。iconv/mb_convert_encoding 將兩邊統一到 UTF-8 後再比較。SHOW VARIABLES LIKE 'character_set%',發現非 utf8mb4 告警。