utf8mb4 and the load data infileIn this post, I’ll discuss how MySQL 5.7 handles UTF8MB4 and the load data infile.

Many of my clients have told me that they do not like using the LOAD DATA INFILE statement and prefer to manually parse and load the data. The main reason they do it are issues with the character sets, specifically UTF8MB4 and the load data infile. This was surprising to me as nowadays everyone uses UTF8. MySQL 5.7 (as well as 5.6) has full support for UTF8MB4, which should fix any remaining issues (i.e., you can now load new emoji, like ?).

Last week I was investigating an interesting case where we were loading data and got the following error:

The load data statement:

The table uses the correct character set (global character set applied to all varchar fields):

The string looked like “Casa Nº 24”. So this should be N + U+00BA (MASCULINE ORDINAL INDICATOR, hex code: c2ba). When I do “less input.tsv”, it shows N<BA> 24. So why can’t MySQL load it?

After further investigation, we discovered the original encoding is not UTF8. WE found out by running:

So the code <BA> was misleading. Also, when I got the actual character from the file, it was just one byte (UTF8 for this character should be two bytes). When MySQL parsed the UTF8 input file, it found only the first part of the multibyte UTF8 code and stopped with an error.

The original character in hex is “ba”:

(0a is a carriage return, and “ba” is “masculine ordinal indicator”)

The UTF8 equivalent:

This is now two bytes (+ carriage return): c2ba

To solve the problem we can simply change the CHARACTER SET utf8mb4 to CHARACTER SET latin1 when doing a load data infile. This fixed the issue:

Another option will be to detect the character set encoding (iconv can do it) and convert to UTF8.

But it worked before…?

It worked a bit differently in MySQL 5.6:

MySQL 5.7 is more strict and doesn’t allow you to insert data in the wrong format. However, it is not 100% consistent. For some characters, MySQL 5.7 will also throw a warning if disabling strict SQL mode.

Another character that caused the same issue was xC9. When loading to MySQL 5.7 with the default sql_mode (ONLY_FULL_GROUP_BY, STRICT_TRANS_TABLES, NO_ZERO_IN_DATE, NO_ZERO_DATE, ERROR_FOR_DIVISION_BY_ZERO, NO_AUTO_CREATE_USER, NO_ENGINE_SUBSTITUTION) it throws an error:

When disabling the strict mode it now defaults to warnings:

Emoji in MySQL

With UTF8MB4 support (in MySQL 5.6 and 5.7), you can also insert a little dolphin into a MySQL table:

This should help you clear up issues with UTF8MB4 and the load data infile. Have fun!

4 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Vidyadhar

It is really good information. I guess if we don’t mention character set in load data command then by default it loads the data with the database character set. Please correct me if I am wrong. Also le me know, Is it a good idea to use iconv linux command to convert the character set ?

Roch

Thanks a lot!

David % TekOps, Inc.

GREAT INFO and Thank you! We had a situation where a client upgraded from MySQL 5.1 to MariaDB through MySQLDump but did not do any upgrades to their application. They were getting insert errors with utf8mb4 complaints into the (default) latin1 charset types of the MySQL 5.1 database. Nobody really talked about what to do in this situation anywhere. We solved it by telling MariaDB to look at the MySQL 5.1 database with this in the mariadb.cnf (e.g., my.cnf) file:

[mysqld]
character-set-server=latin1
character-set-server=latin1
collation-server = latin1_general_ci

This also solved copy/paste issues in the web-browser.

Down mariadb. Add this to my.cnf in the [mysqld] section. Comment out any utf8 or utf8mb4 stuff. Save the file then restart the database. Watch for errors. Start your application and voila, it should work.

Thanks
David

oziboy

thanks a lot men you save my life 🙂