字符集不一致是「亂碼」「數據截斷」「索引失效」的元兇。本文系統講解 MySQL 字符集變量傳遞鏈路、客戶端-轉換器-服務端三層轉換模型、動態修改與持久化配置、存量數據庫 latin1 遷移至 utf8mb4 的四步導出導入法,附生產環境巡檢清單。
SHOW VARIABLES LIKE 'character%'; +--------------------------+----------------------------+ | Variable_name | Value | +--------------------------+----------------------------+ | character_set_client | latin1 <-- 客戶端聲明 | | character_set_connection | latin1 <-- 轉換器目標 | | character_set_database | latin1 <-- 庫默認 | | character_set_filesystem | binary <-- 文件系統 | | character_set_results | latin1 <-- 結果集編碼 | | character_set_server | latin1 <-- 服務端默認 | | character_set_system | utf8 <-- 元數據固定 | | character_sets_dir | /usr/share/mysql/charsets/ | +--------------------------+----------------------------+
客戶端 (gbk) → 字符集轉換器 (client→connection) → 服務端 (utf8)
↑ ↑
character_set_client character_set_connection
↑ ↑
character_set_results ← character_set_server
SET NAMES 或驅動屬性聲明 character_set_client。client 轉為 connection,再按 server 存儲。character_set_results 編碼返回給客戶端。| 現象 | 根因 | 對策 |
|---|---|---|
| 亂碼 | client 與實際編碼不符(如 Windows cmd 默認 gbk 卻設 utf8) | 客戶端正確聲明編碼 |
| 亂碼 | results 與客戶端顯示編碼不符 | 統一 results = client |
| 數據截斷/丟失 | connection 字符集容量 < client(如 client=utf8, connection=latin1) | connection ≥ client,建議均為 utf8mb4 |
-- 會話級(當前連接生效) SET NAMES utf8mb4; -- 等價於 client/connection/results 三者同設 -- 全局級(需配合配置文件持久化) SET GLOBAL character_set_server = utf8mb4; SET GLOBAL character_set_database = utf8mb4;
# my.cnf 永久生效 [client] default-character-set = utf8mb4 [mysql] default-character-set = utf8mb4 [mysqld] character-set-client-handshake = FALSE character-set-server = utf8mb4 collation-server = utf8mb4_unicode_ci init_connect = 'SET NAMES utf8mb4'
mysqldump -uroot -p --default-character-set=latin1 -d DB_NAME > createtable.sql # -d 僅導結構
CHARSET=latin1 批量替換為 CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_cimysqldump -uroot -p --default-character-set=latin1 \ --quick --no-create-info --extended-insert DB_NAME > data.sql
SET NAMES latin1 → SET NAMES utf8mb4CREATE DATABASE DB_NAME DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; mysql -uroot -p DB_NAME < createtable.sql mysql -uroot -p DB_NAME < data.sql
SHOW VARIABLES LIKE 'character_set%':client/connection/database/results/server 全為 utf8mb4。SELECT TABLE_SCHEMA, TABLE_NAME, TABLE_COLLATION FROM information_schema.TABLES WHERE TABLE_SCHEMA NOT IN ('mysql','sys','performance_schema','information_schema') AND TABLE_COLLATION NOT LIKE 'utf8mb4%':零行通過。SELECT TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, COLLATION_NAME FROM information_schema.COLUMNS WHERE TABLE_SCHEMA NOT IN (...) AND COLLATION_NAME NOT LIKE 'utf8mb4%':零行通過。charset=utf8mb4。CHARSET=utf8mb4,CI/CD 流水線集成 pt-table-checksum 校驗主從字符集一致性。