最近一個與qq有關的服務遷到騰訊雲上,相應的數據庫也要從原阿里雲RDS遷移到騰訊雲CDB上,通過一番摸索,不帶任何政治色彩的說,CDB跟RDS相比弱的不止一條街。好比看個錯誤日誌還要提工單,數據庫訪問沒有白名單,數據傳輸服務競不支持源庫的開啓GTID,自帶的後臺管理是phpMyAdmin,要臨時看查詢日誌也要提工單,固然這些都是能夠容忍經過其它方法解決的,可是若是使用上帶來了mysql數據庫自己的影響,就用的不太爽了。php
最近2個月一直在弄與字符集相關的工做,卻仍是在cdb踩到一個大坑。狀況是這樣的,咱們舊的RDS上的數據庫表定義都是utf8,但因爲歷史緣由,開發一直使用 latin1 去鏈接的。如今要把這樣的一個db遷移到CDB,騰訊雲的數據傳輸服務出了點問題,因而想了辦法用阿里雲的DTS反向遷。現象是:html
用Navicat客戶端latin1鏈接,舊數據顯示都okmysql
但程序端看到歷史數據全是亂碼,新數據正常web
並且新數據經過navicat去看用 utf8 鏈接才正常sql
在mysql命令行下手動 set names latin1
讀取舊數據ok,但新數據亂碼數據庫
這明顯是新寫入的時候就是以 utf8 鏈接的,讀取的時候新舊數據也以 utf8 鏈接。但應用端已明確設置使用 latin1 鏈接來讀寫。爲了驗證是否CDB的問題,在相同環境下自建了個mysql實例,一切都ok。this
騰訊雲工程師先是懷疑遷移有問題,後來講多是character_set_server設置的問題,我站在2個月來處理字符集的經驗看了雖然不太可能,仍是配合截了幾個圖,在工單、電話了裏撕了幾個來回:阿里雲
由於跟騰訊有合做關係,上頭就直接聯繫到了騰訊雲的人,這才找到問題根源:都是--skip-character-set-client-handshake
惹的禍。spa
--character-set-client-handshake Do not ignore character set information sent by the client. To ignore client information and use the default server character set, use --skip-character-set-client-handshake; this makes MySQL behave like MySQL 4.0
<!-- more -->
一看到這個選項就恍然大悟了,官方文檔FAQ裏有專門介紹:A.11.11(我的感受最後一段貼的結果有問題),大意是說爲了兼容 mysql 4.0 的習慣,mysqld啓動時加上 --skip-character-set-client-handshake
來忽略客戶端字符集的設置,強制使用服務端character-set-server
的設置。命令行
但這個選項默認是沒有開啓的,當你在web控制檯修改了實例字符集時,CDB自做自做主張修改了這個參數並重啓 character_set_client_handshake = 0 。而這個參數在 show variables
看不到的,隱藏的比較深。正好我建實例的時候選擇了utf8,而後修改成utf8mb4,但應用端要求latin1,便中槍了。
主要是之前沒聽過這個參數,後來發現老葉也有篇文章講到它 MySQL字符集的一個坑,實際上是很小的東西,結果排查驗證問題先後花了2天。。。