字符編碼問題是 MySQL 運維中最隱蔽、最令人頭疼的故障之一。本文通過實驗復現 Incorrect string value 錯誤,深度剖析字符集轉換鏈路,提供系統性排查與修復方案。
ERROR 1366 (HY000): Incorrect string value: '\xD0\xC2\xC8A\xBEW' for column 'ctnr' at row 1
十六進制 \xD0\xC2\xC8A\xBEW 是 GBK 編碼的「新華網」三個漢字。
| 變量名 | 作用層級 | 說明 |
|---|---|---|
| character_set_server | 服務器級 | 服務端默認字符集 |
| collation_server | 服務器級 | 服務端默認校對規則 |
| character_set_database | 數據庫級 | 當前數據庫默認字符集 |
| character_set_client | 連接級 | 客戶端發送數據的字符集 |
| character_set_connection | 連接級 | 連接層轉換目標字符集 |
| character_set_results | 連接級 | 結果集返回客戶端前轉換字符集 |
客戶端發送數據 (character_set_client)
↓
服務端接收並轉換 (character_set_connection)
↓
內部處理/存儲 (表/列字符集)
↓
結果集轉換返回 (character_set_results)
↓
客戶端接收顯示
-- 方式 A: SET NAMES (推薦)
SET NAMES 'utf8mb4';
-- 等價於:
SET character_set_client = utf8mb4;
SET character_set_results = utf8mb4;
SET character_set_connection = utf8mb4;
-- 同時設置 collation_connection
-- 方式 B: SET CHARACTER SET
SET CHARACTER SET 'utf8mb4';
-- 等價於:
SET character_set_client = utf8mb4;
SET character_set_results = utf8mb4;
SET collation_connection = @@collation_database;
-- 1. 檢查服務端配置
SHOW VARIABLES LIKE 'character_set_%';
SHOW VARIABLES LIKE 'collation_%';
-- 2. 檢查數據庫/表/列字符集
SHOW CREATE DATABASE db_name;
SHOW CREATE TABLE tbl_name;
SHOW FULL COLUMNS FROM tbl_name;
-- 3. 檢查客戶端連接字符集
STATUS; -- mysql 客戶端命令
-- 或應用代碼中檢查驅動配置
-- 4. 檢查數據實際編碼
SELECT HEX(col_name) FROM tbl_name WHERE id=xxx;
characterEncoding=utf8mb4、Python charset='utf8mb4'、PHP mysqli_set_charset()SET NAMES utf8mb4-- 修改表默認字符集(僅影響新建列)
ALTER TABLE tbl_name DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 修改列字符集(重建表,鎖表操作)
ALTER TABLE tbl_name MODIFY col_name VARCHAR(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 大表零停機修改
pt-online-schema-change --alter "MODIFY col_name VARCHAR(100) CHARACTER SET utf8mb4" D=db,t=tbl --execute
[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
[client]
default-character-set = utf8mb4
[mysql]
default-character-set = utf8mb4
| 特性 | utf8 (utf8mb3) | utf8mb4 |
|---|---|---|
| 最大字符長度 | 3 字節 | 4 字節 |
| Emoji 支持 | ❌ | ✅ |
| 生僻字支持 | 部分缺失 | 完整 Unicode |
| 索引長度限制 | 767 字節 | 767 字節 (需開啟 innodb_large_prefix) |
強烈建議:全鏈路統一使用 utf8mb4,避免 Emoji/生僻字截斷錯誤。
PG 類似錯誤:invalid byte sequence for encoding "UTF8",排查邏輯一致:客戶端編碼 (client_encoding) 與數據庫編碼 (server_encoding) 不匹配。
utf8mb4SET NAMES utf8mb4字符編碼問題本質是「編碼聲明與實際不一致」導致的解碼失敗。建立全鏈路 utf8mb4 標準,配合自動化檢測機制,才能從根源上杜絕亂碼故障。