【问题标题】:Why does --default-character-set=utf8mb4 have no impact on the client connection?为什么 --default-character-set=utf8mb4 对客户端连接没有影响?
【发布时间】:2021-08-11 10:49:04
【问题描述】:

根据https://dev.mysql.com/doc/refman/5.6/en/charset-connection.html,当我使用mysql 8.0客户端使用命令连接到mysql 5.6服务器时:

/usr/bin/mysql -h ${DB_HOST} -u ${DB_USER} -p --default-character-set=utf8mb4

我希望客户端会建立到服务器的 utf8mb4 连接。但是,连接设置为 latin1:

mysql> SELECT * FROM INFORMATION_SCHEMA.SESSION_VARIABLES WHERE VARIABLE_NAME IN (
 'character_set_client', 'character_set_connection', 'character_set_results', 'collation_connection' ) 
ORDER BY VARIABLE_NAME;
+--------------------------+-------------------+
| VARIABLE_NAME            | VARIABLE_VALUE    |
+--------------------------+-------------------+
| CHARACTER_SET_CLIENT     | latin1            |
| CHARACTER_SET_CONNECTION | latin1            |
| CHARACTER_SET_RESULTS    | latin1            |
| COLLATION_CONNECTION     | latin1_swedish_ci |
+--------------------------+-------------------+

使用另一个字符集,例如: /usr/bin/mysql -h ${DB_HOST} -u ${DB_USER} -p --default-character-set=koi8r 将导致客户端使用提供的字符集进行连接:

mysql> SELECT * FROM INFORMATION_SCHEMA.SESSION_VARIABLES WHERE VARIABLE_NAME IN ( 'character_set_client', 'character_set_connection', 'character_set_results', 'collation_connection' ) ORDER BY VARIABLE_NAME;
+--------------------------+------------------+
| VARIABLE_NAME            | VARIABLE_VALUE   |
+--------------------------+------------------+
| CHARACTER_SET_CLIENT     | koi8r            |
| CHARACTER_SET_CONNECTION | koi8r            |
| CHARACTER_SET_RESULTS    | koi8r            |
| COLLATION_CONNECTION     | koi8r_general_ci |
+--------------------------+------------------+

我可以改变客户端连接的唯一方法是在连接到服务器后执行charset utf8mb4SET NAMES utf8mb4

mysql> SET NAMES utf8mb4;
Query OK, 0 rows affected (0.01 sec)

mysql> SELECT * FROM INFORMATION_SCHEMA.SESSION_VARIABLES WHERE VARIABLE_NAME IN ( 'character_set_client', 'character_set_connection', 'character_set_results', 'collation_connection' ) ORDER BY VARIABLE_NAME;
+--------------------------+--------------------+
| VARIABLE_NAME            | VARIABLE_VALUE     |
+--------------------------+--------------------+
| CHARACTER_SET_CLIENT     | utf8mb4            |
| CHARACTER_SET_CONNECTION | utf8mb4            |
| CHARACTER_SET_RESULTS    | utf8mb4            |
| COLLATION_CONNECTION     | utf8mb4_general_ci |
+--------------------------+--------------------+

为什么 --default-character-set=utf8mb4 不起作用?我想使用其他客户端工具,如 mysqldump 和 mysqlimport,但如果没有这个标志,我将获得 latin1 编码而不是 utf8mb4 编码。在这种情况下,无法更改默认服务器设置,必须从客户端完成。

更多信息:我正在尝试安装 20.04 的 ubuntu WSL2,因此没有可用的 5.6 或 5.7 客户端。但是,使用 5.6 或 5.7 windows mysql 客户端会遵守 --default-character-set=utf8mb4,但 8.0 windows 客户端的行为与 WSL2 客户端相同。

【问题讨论】:

    标签: mysql mysql-5.6 mysql-cli


    【解决方案1】:

    8.0 文档中解释了此行为:https://dev.mysql.com/doc/refman/8.0/en/charset-connection.html

    同样的问题出现在更微妙的上下文中:当客户端告诉服务器使用服务器识别的字符集时, 但客户端上该字符集的默认排序规则是 在服务器端未知。例如,当 MySQL 8.0 客户端想要使用 utf8mb4 作为客户端字符集连接到 MySQL 5.7 服务器。指定的客户端 --default-character-set=utf8mb4 能够连接到服务器。但是,与前面的示例一样,服务器回退到它的 默认字符集和排序规则,不是客户要求的:

       mysql> SHOW SESSION VARIABLES LIKE 'character\_set\_%';
       +--------------------------+--------+ 
       | Variable_name            | Value  |
       +--------------------------+--------+
       | character_set_client     | latin1 | 
       | character_set_connection | latin1 | 
       ...
       |character_set_results    | latin1 | 
       ...
       +--------------------------+--------+ 
       mysql> SHOW SESSION VARIABLES LIKE 'collation_connection';
       +----------------------+-------------------+ 
       | Variable_name        | Value             |
       +----------------------+-------------------+ 
       | collation_connection | latin1_swedish_ci |
       +----------------------+-------------------+ 
    

    为什么会发生这种情况?毕竟utf8mb4是8.0客户端和5.7服务器都知道的,所以 他们都认得。要理解这种行为,它是 有必要了解当客户端告诉服务器哪个 它要使用的字符集,它确实告诉服务器默认值 该字符集的排序规则。因此,上述 行为的发生是由多种因素共同造成的:

    • utf8mb4 的默认排序规则在 MySQL 5.7 和 8.0 之间有所不同 (utf8mb4_general_ci 用于 5.7,utf8mb4_0900_ai_ci 用于 8.0)。

    • 8.0客户端请求utf8mb4字符集时,发送什么 到服务器是默认的 8.0 utf8mb4 排序规则;那就是 utf8mb4_0900_ai_ci.

    • utf8mb4_0900_ai_ci 仅在 MySQL 8.0 中实现,因此 5.7 服务器无法识别它。

    • 因为5.7服务器不识别utf8mb4_0900_ai_ci,所以 无法满足客户端字符集请求,并回退到其 默认字符集和排序规则(latin1 和 latin1_swedish_ci)。

    在这种情况下,客户端仍然可以通过发出 SET NAMES 来使用 utf8mb4 连接后的“utf8mb4”语句。结果排序规则是 5.7 默认 utf8mb4 排序规则;即utf8mb4_general_ci。如果客户端还想要一个 utf8mb4_0900_ai_ci 的排序规则,它不能 实现这一点是因为服务器无法识别该排序规则。这 客户端必须愿意使用不同的 utf8mb4 排序规则,或者 从 MySQL 8.0 或更高版本连接到服务器。

    【讨论】:

      猜你喜欢
      • 2022-01-10
      • 1970-01-01
      • 2021-02-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-28
      相关资源
      最近更新 更多