整理 MySQL8.0 文檔時(shí)發(fā)現(xiàn)一個(gè)變更:默認(rèn)字符集由 latin1 變?yōu)?utf8mb4。想起以前整理過(guò)字符集轉(zhuǎn)換文檔粘招,升級(jí)到 MySQL8.0 后大概率會(huì)有字符集轉(zhuǎn)換的需求曹质,在此正好分享一下鸳碧。
當(dāng)時(shí)的需求背景是:部分系統(tǒng)使用的字符集是 utf8报强,但 utf8 最多只能存 3 字節(jié)長(zhǎng)度的字符妇穴,不能存放四字節(jié)的生僻字或者表情符號(hào)爬虱,因此打算遷移到 utf8mb4。
遷移方案一
1. 準(zhǔn)備新的數(shù)據(jù)庫(kù)實(shí)例腾它,修改以下參數(shù):
[mysqld]
## Character Settings
init_connect='SET NAMES utf8mb4'
#連接建立時(shí)執(zhí)行設(shè)置的語(yǔ)句跑筝,對(duì)super權(quán)限用戶(hù)無(wú)效
character-set-server = utf8mb4
collation-server = utf8mb4_general_ci
#設(shè)置服務(wù)端校驗(yàn)規(guī)則,如果字符串需要區(qū)分大小寫(xiě)瞒滴,設(shè)置為utf8mb4_bin
skip-character-set-client-handshake
#忽略應(yīng)用連接自己設(shè)置的字符編碼曲梗,保持與全局設(shè)置一致
## Innodb Settings
innodb_file_format = Barracuda
innodb_file_format_max = Barracuda
innodb_file_per_table = 1
innodb_large_prefix = ON
#允許索引的最大字節(jié)數(shù)為3072(不開(kāi)啟則最大為767字節(jié),對(duì)于類(lèi)似varchar(255)字段的索引會(huì)有問(wèn)題,因?yàn)?55*4大于767)
2. 停止應(yīng)用稀并,觀察仅颇,確認(rèn)不再有數(shù)據(jù)寫(xiě)入
可通過(guò) show master status 觀察,GTID或者 binlog position 沒(méi)有變化則沒(méi)有寫(xiě)入
3. 導(dǎo)出數(shù)據(jù)
先導(dǎo)出表結(jié)構(gòu):
mysqldump -u -p --no-data --default-character-set=utf8mb4 --single-transaction --set-gtid-purged=OFF --databases testdb > /backup/testdb.sql
后導(dǎo)出數(shù)據(jù):
mysqldump -u -p --no-create-info --master-data=2 --flush-logs --routines --events --triggers --default-character-set=utf8mb4 --single-transaction --set-gtid-purged=OFF --database testdb > /backup/testdata.sql
4. 修改建表語(yǔ)句
修改導(dǎo)出的表結(jié)構(gòu)文件碘举,將表忘瓦、列定義中的 utf8 改為 utf8mb4
5. 導(dǎo)入數(shù)據(jù)
先導(dǎo)入表結(jié)構(gòu):
mysql -u -p testdb < /backup/testdb.sql
后導(dǎo)入數(shù)據(jù):
mysql -u -p testdb < /backup/testdata.sql
6. 建用戶(hù)
查出舊環(huán)境的數(shù)據(jù)庫(kù)用戶(hù),在新數(shù)據(jù)庫(kù)中創(chuàng)建
7. 修改新數(shù)據(jù)庫(kù)端口引颈,啟動(dòng)應(yīng)用進(jìn)行測(cè)試
關(guān)閉舊數(shù)據(jù)庫(kù)耕皮,修改新數(shù)據(jù)庫(kù)端口重啟,啟動(dòng)應(yīng)用
遷移方案二
1. 修改表的字符編碼會(huì)鎖表蝙场,建議先停止應(yīng)用
2. 停止mysql凌停,備份數(shù)據(jù)目錄(也可以其他方式進(jìn)行全備)
3. 修改配置文件,重啟數(shù)據(jù)庫(kù)
[mysqld]
## Character Settings
init_connect='SET NAMES utf8mb4'
#連接建立時(shí)執(zhí)行設(shè)置的語(yǔ)句售滤,對(duì)super權(quán)限用戶(hù)無(wú)效
character-set-server = utf8mb4
collation-server = utf8mb4_general_ci
#設(shè)置服務(wù)端校驗(yàn)規(guī)則罚拟,如果字符串需要區(qū)分大小寫(xiě),設(shè)置為utf8mb4_bin
skip-character-set-client-handshake
#忽略應(yīng)用連接自己設(shè)置的字符編碼完箩,保持與全局設(shè)置一致
## Innodb Settings
innodb_file_format = Barracuda
innodb_file_format_max = Barracuda
innodb_file_per_table = 1
innodb_large_prefix = ON
#允許索引的最大字節(jié)數(shù)為3072(不開(kāi)啟則最大為767字節(jié)赐俗,對(duì)于類(lèi)似varchar(255)字段的索引會(huì)有問(wèn)題,因?yàn)?55*4大于767)
4. 查看所有表結(jié)構(gòu)弊知,包括字段阻逮,修改庫(kù)和表結(jié)構(gòu),如果字段有定義字符編碼秩彤,也需要修改字段屬性叔扼,sql語(yǔ)句如下:
修改表的字符集,會(huì)同時(shí)將字段的字符編碼修改:
alter table t convert to character set utf8mb4;
影響:拷貝全表漫雷,速度慢瓜富,會(huì)加鎖,阻塞寫(xiě)操作
修改database的默認(rèn)字符集珊拼,之后新建表默認(rèn)即使用這個(gè)字符編碼:
alter database sbtest CHARACTER SET utf8mb4;
影響:只需修改元數(shù)據(jù)食呻,速度很快