Bug #87717 | character_set_server is not dynamic and requires restart server | ||
---|---|---|---|
Submitted: | 9 Sep 2017 10:08 | Modified: | 22 Sep 2017 5:24 |
Reporter: | Ke Lu | Email Updates: | |
Status: | Not a Bug | Impact on me: | |
Category: | Connector / J | Severity: | S3 (Non-critical) |
Version: | 5.1.35 ~ 5.1.44 | OS: | Linux |
Assigned to: | Alexander Soklakov | CPU Architecture: | Any |
Tags: | charset |
[9 Sep 2017 10:08]
Ke Lu
[15 Sep 2017 13:33]
Chiranjeevi Battula
Hello Luke, Thank you for the bug report. Can you please clarify more on what you are trying? 1) Connect to server with Connector/J, change values on server and try the connection charset on the same connection. or 2) Connect to server with Connector/J, change values on server, reconnect and try the connection charset on the new connection. Connector/J can handle mixed charsets in results, which means you can create some tables or columns in utf8mb4. Thanks, Chiranjeevi.
[16 Sep 2017 5:17]
Ke Lu
Hi, I mean the second one: Connect to server with Connector/J, change values on server, reconnect and try the connection charset on the new connection. dynamically setting the character_set_server=utf8mb4 and collation-server=utf8mb4_unicode_ci will not work for the new connection, the charset for the new connection is still utf8. We can insert utf8mb4 chars into table , but when you compare a utf8mb4 column to some string it will cause illegal mix of collations errors. e.g. select * from some_table where utf8mb4_column = 'aaaa'; because collate for utf8mb4 column using utf8mb4_unicode_ci and 'aaaa' use utf8_general_ci as the connect charset is still utf8.
[18 Sep 2017 6:50]
Chiranjeevi Battula
Hello Luke, Thank you for your feedback. Verified based on internal discussion with dev's. Thanks, Chiranjeevi.
[19 Sep 2017 13:00]
Alexander Soklakov
Hi Luke, This issue is caused by server. Though you change the character_set_* variables globally the server still sends an original charset and collation number in a protocol greeting, thus c/J does a mistake about actual server state. I'm not sure if it's an intentional behaviour, looks like a server bug for me. The difference between MySQL client and c/J is that c/J does additional charset configuration work at the beginnig to reduce the number of intermediate data conversion on results retrieving. And c/J can handle your case, you just need to use connectionCollation=utf8mb4_unicode_ci connection option on secondary connections. Please, look at example below. public void testBug87717() throws Exception { Properties p = new Properties(); p.setProperty("useSSL", "false"); // to check on-wire packets in clear text System.out.println("\nOriginal server state"); System.out.println("====================="); Statement s1 = getConnectionWithProps(p).createStatement(); ResultSet rs1 = s1.executeQuery("show variables like '%chara%'"); while (rs1.next()) { System.out.println(rs1.getString(1) + " = " + rs1.getString(2)); } rs1 = s1.executeQuery("show variables like '%colla%'"); while (rs1.next()) { System.out.println(rs1.getString(1) + " = " + rs1.getString(2)); } s1.execute("set global character_set_server=utf8mb4"); s1.execute("set global collation_server=utf8mb4_unicode_ci"); s1.execute("set global character_set_client=utf8mb4"); s1.execute("set global character_set_connection=utf8mb4"); s1.execute("set global character_set_results=utf8mb4"); System.out.println("\nModified server state"); System.out.println("====================="); // do not use this property to avoid unnecessary SET NAMES query //p.setProperty("characterEncoding", "UTF-8"); p.setProperty("connectionCollation", "utf8mb4_unicode_ci"); Connection c2 = getConnectionWithProps(p); ResultSet rs2 = c2.createStatement().executeQuery("show variables like '%chara%'"); while (rs2.next()) { System.out.println(rs2.getString(1) + " = " + rs2.getString(2)); } rs2 = c2.createStatement().executeQuery("show variables like '%colla%'"); while (rs2.next()) { System.out.println(rs2.getString(1) + " = " + rs2.getString(2)); } // restoring original state s1.execute("set global character_set_server=utf8"); s1.execute("set global collation_server=utf8_general_ci"); s1.execute("set global character_set_client=utf8"); s1.execute("set global character_set_connection=utf8"); s1.execute("set global character_set_results=utf8"); } And the output is: Original server state ===================== character_set_client = utf8 character_set_connection = utf8 character_set_database = latin1 character_set_filesystem = binary character_set_results = character_set_server = utf8 character_set_system = utf8 character_sets_dir = /opt/mysql-5.7.17-linux-glibc2.5-x86_64/share/charsets/ collation_connection = utf8_general_ci collation_database = latin1_swedish_ci collation_server = utf8_general_ci Modified server state ===================== character_set_client = utf8 character_set_connection = utf8mb4 character_set_database = latin1 character_set_filesystem = binary character_set_results = character_set_server = utf8mb4 character_set_system = utf8 character_sets_dir = /opt/mysql-5.7.17-linux-glibc2.5-x86_64/share/charsets/ collation_connection = utf8mb4_unicode_ci collation_database = latin1_swedish_ci collation_server = utf8mb4_unicode_ci
[22 Sep 2017 3:11]
Ke Lu
Yes,set connectionCollation to utf8mb4_unicode_ci does solve this problem although i have already restarted my production server with new configuration. Thanks!
[22 Sep 2017 5:24]
Alexander Soklakov
Luke, Thanks for the confirmation!