某次信創環境Oceanbase數據庫偶發亂碼問題
當前位置:點晴教程→知識管理交流
→『 技術文檔交流 』
資料遷移,整理分享。 問題發生在2023年 一、環境介紹及問題簡述
在客戶方搭建的信創環境中,使用麒麟Linux作為操作系統,Oceanbase作為應用數據庫,東方通TongWeb作為Web應用容器,在此環境下 部署我司JAVA應用(后續表述中將使用簡稱WebA),在WebA使用過程中,偶發的出現中文字符入庫后亂碼的問題,導致業務數據無法正常查看。 其中,oceanbase數據庫編碼使用GBK,TongWeb中HTTP通道也使用了默認的GBK編碼,WebA則采用UTF8編碼,應用與數據庫的連接,交由TongWeb中的數據源配置進行池化管理。 該亂碼問題隨機出現,無規律,時間隨機,針對同一個功能,即便是相同的數據,也不會重復觸發。 二、結論聲明
三、原因解釋1、作為前提,需要知道,每一種編碼方式會有自己的字符映射表。同樣的字節序列在不同的編碼方式中代表的是不同的字符。 2、在向數據庫服務器發送一條SQL指令時,指令及指令中的數據是以字節序列的形式發送到后臺的。 3、在數據庫中,可以通過 show variables like '%char%' 命令獲取當前連接下的數據庫編碼,如下圖 其中,character_set_client 是數據庫服務器認為的請求端使用的字符編碼方式,如上圖,即便客戶端在發送sql語句時,使用的是GBK編碼,服務器也會將其認為是UTF8編碼進行處理。 character_set_connection 數據庫服務器會把按照 character_set_client 編碼處理的字符再轉換為 character_set_connection 對應的編碼方案。此時,如果兩者的配置值相同,就可以省略一個轉換的操作。 服務器的后續操作中,還會發生 character_set_connection到數據庫表或數據表列的字符轉換。 character_set_results 是服務器向請求端返回數據時使用的字符集,服務器會采用該變量指定的字符集對返回給客戶端的數據進行編碼。 針對入庫亂碼的問題,此處重點關注 character_set_client 與 character_set_connection 4、set names gbk的作用 該 語句將三個會話系統變 量 character_set_client , character_set_connection 和 character_set_results 設置為給定的GBK字符集。 該命令僅作用于當前數據庫會話,SESSION級別,詳情見SET NAMES_用戶指南_云數據庫OceanBase_敏捷版通用版本 (aliyun.com)。 另外,在OB數據中,支持在租戶級、Database 級、表級、字段級、session 級設置字符集,詳見字符集規范-OceanBase 數據庫 -OceanBase文檔中心-分布式數據庫使用文檔 5、測試(MySQL環境,OceanBase環境)。 MySQL測試用例一 :
MySQL測試用例二: 定義如下數據庫表
修改 當前數據庫連接 的字符編碼設置,執行insert插入語句,查看插入的數據是否亂碼。
由上結果可證: 在mysql的innodb引擎下,當 character_set_client 的編碼與請求端的實際編碼方式不匹配時,會出現數據的亂碼情況。 OceanBase測試用例一 :
根據上方表格及輸出截圖發現,oceanbase中,character_set_connection與請求端編碼一致時不會出現亂碼的情況。 Oceanbase測試用例二:字段,測試代碼沿用mysql測試示例二中的內容,下方繼續以表格形式展示:
這里有一個很奇怪的地方是: 直 接運行 set character_set_client = gbk, character_set_connection = gbk, character_set_results = gbk, 然后執行插入,有時可以得到正常數據,有時候又是亂碼的數據。 運行 set names gbk后執行插入,則可以穩定觸發亂碼現象。下方為對比圖: 根據以上測試結果發現,在oceanbase中當 character_set_connection 的編碼與請求端的實際編碼方式不匹配時,會出現數據的亂碼情況,且該亂碼情況也是隨機出現,無法確認規律。 四、使用建議1、 建議將 character_set_client , character_set_connection 和 character_set_results 都設置為應用使用的編碼方式,在WebA應用的環境下使用時,應該將參數默認設置為 utf8mb4。具體設置方式請參考:
五、當前采用的修復方案1、使用jdbc初始化征信接口使用的數據庫連接,避免與框架使用的數據庫連接池沖突。 ?轉自https://www.cnblogs.com/imzx/p/18688135 該文章在 2025/2/7 9:53:26 編輯過 |
關鍵字查詢
相關文章
正在查詢... |