mysql錯誤SQLstate[HY000];errorcode[1366];Incorrectstringvalue:'\xF0\xBF\xAA\xB7\xEF\xBF...'解決辦法

今天在運行程序插入數據庫時,出現瞭如下的bug:

org.springframework.jdbc.UncategorizedSQLException: PreparedStatementCallback; uncategorized SQLException for SQL [replace into task_result values(?,?,?,?)]; SQL state [HY000]; error code [1366]; Incorrect string value: '\xF0\xBF\xAA\xB7\xEF\xBF...' for column 'ip_info' at row 1; nested exception is java.sql.SQLException: Incorrect string value: '\xF0\xBF\xAA\xB7\xEF\xBF...' for column 'ip_info' at row 1。

網上百度了一下,是Emoji字符導致的。

雖然我修改了mysql的默認字符集爲utf8,但是爲3個字節,存儲Emoji字符需要4個字節的utfm8。修改my.cnf。

修改前:

\

修改字符集:

\

修改後再次查看字符。

\

 

 

今天分享一個mysql數據插入異常的問題,由於工作排期問題,沒有時間去深入研究這個問題,也因此困擾了我很久,問題大概是這樣的,當我們把4個字節的字符插入到數據表列字符集爲3個字節的表中時,會拋出以下異常,在沒有異常捕獲的情況下,導致程序崩潰以及事務持續性不健全

環境

mysql version: 5.6.35
JDK : 1.6.0_38

異常拋出:

nested exception is java.sql.SQLException: Incorrect string value: '\xF4\x80\x80\x8062...' for column 'ERROR' at row 1 
     at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:83) 
     at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80) 
     at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80) 
     at org.springframework.orm.hibernate3.HibernateAccessor.convertJdbcAccessException(HibernateAccessor.java:424) 
     at org.springframework.orm.hibernate3.HibernateAccessor.convertHibernateAccessException(HibernateAccessor.java:410) 
     at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:424) 
     at org.springframework.orm.hibernate3.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:374) 
     at org.springframework.orm.hibernate3.HibernateTemplate.saveOrUpdate(HibernateTemplate.java:748) 
     at com.cargosmart.sime.core.persistence.dao.BaseDao.saveOrUpdate(BaseDao.java:39) 
     at ....
    Caused by: java.sql.SQLException: Incorrect string value: '\xF4\x80\x80\x8062...' for column 'ERROR' at row 1 
     at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1073) 

問題分析:
我們可以看到上面異常中:Incorrect string value: '\xF4\x80\x80\x8062...' for column 'ERROR' at row 1,大致意思就是說對某數據庫表列ERROR 插入了不正確的字符串值\xF4\x80\x80\x8062...,那到底爲什麼是錯誤的呢,首先我們可以看到那個不正確的字符串的特徵,是一個4字節的十六進制的字符\xF4\x80\x80\x80,再查查表字符集發現爲UTF-8,到這裏還沒發現根本問題,再仔細翻看了mysql官方version release notes,發現在version 5.5.3中發現有如下發布改進記錄:

  • Changes in MySQL 5.5.3 (2010-03-24, Milestone 3)
Incompatible Change: The Unicode implementation has been extended to provide support for 
supplementary characters that lie outside the Basic Multilingual Plane (BMP). Noteworthy features:

utf16 and utf32 character sets have been added. These correspond to the UTF-16 and UTF-32 
encodings of the Unicode character set, and they both support supplementary characters.

The utf8mb4 character set has been added. This is similar to utf8, but its encoding allows up to 
four bytes per character to enable support for supplementary characters.

可以發現在version 5.5.3之後,增加了一種和utf-8類似的字符集utf8mb4,並且它的編碼支持4個字節每個字符,再看看mysql的字符集所支持的字節範圍:

mysql> SHOW CHARACTER SET;
+----------+---------------------------------+---------------------+--------+
| Charset  | Description                     | Default collation   | Maxlen |
+----------+---------------------------------+---------------------+--------+
...
| utf8     | UTF-8 Unicode                   | utf8_general_ci     |      3 |
...
| utf8mb4  | UTF-8 Unicode                   | utf8mb4_general_ci  |      4 |
...

可以發現utf8最大支持3個字節的字符,到這裏就基本確定是因爲這個字符集設定所引起的異常,於是我試着修改對應列的字符集,這裏的字符集分爲表級字符集以及列級字符集,如果沒有特別設定,列級字符集默認繼承表級字符集,於是爲了降低產品的影響面,我試着將發生異常的列的字符集改成utf8mb4,

ALTER TABLE `<db name>`.`<table name>` CHANGE COLUMN `ERROR` `ERROR` 
VARCHAR(500) CHARACTER SET 'utf8mb4' NULL DEFAULT NULL  ;

糾正:5.7往上版本

change改成modify

 

然後再重現了一下上面的異常,發現數據插入成功。至此,問題解決。

總結,這個異常的發生是由於4字節的字符插入到字符集爲3字節的列中,在插入數據之前,字符集驗證失敗,字節溢出導致插入失敗異常。
解決方法: 將對應列的字符集改成utf8mb4



作者:eason02
鏈接:https://www.jianshu.com/p/992bd01dbf60
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯繫作者獲得授權並註明出處。

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章