MySQL 8.0 のクライアントで MySQL 5.7 サーバに接続すると Charset の指定がクライアントからできない

2021-08-07 16:03 (3年前) ytyng
View in English

MySQL 8.0のクライアントでMySQL 5.7のサーバーに接続するとcharsetが設定されないかもしれない

↑こちらで詳しい説明がある。現象としてはページの件名の通り、文字コードがクライアント側から指定できない。

概要

Ubuntu を 18 -> 20 にアップグレードして、その上で動いている Django から MySQL 5.7 RDS のデータを取得した時に、日本語がすべて ???????? と表示された。

ライブラリのバージョン

$ cat /etc/issue
Ubuntu 20.04.2 LTS \n \l

$ apt list --installed | grep mysql

WARNING: apt does not have a stable CLI interface. Use with caution in scripts.

default-libmysqlclient-dev/focal,now 1.0.5ubuntu2 amd64 [installed]
libmysqlclient-dev/focal-updates,focal-security,now 8.0.26-0ubuntu0.20.04.2 amd64 [installed,automatic]
libmysqlclient21/focal-updates,focal-security,now 8.0.26-0ubuntu0.20.04.2 amd64 [installed,automatic]
mysql-client-core-8.0/focal-updates,focal-security,now 8.0.26-0ubuntu0.20.04.2 amd64 [installed]
mysql-common/focal,now 5.8+1.0.5ubuntu2 all [installed,automatic]

調査

ためしに、

./manage.py dbshell

してみて、

mysql> show variables like "%chara%";

すると

mysql> show variables like "%chara%";
+--------------------------+-------------------------------------------+
| Variable_name | Value |
+--------------------------+-------------------------------------------+
| character_set_client | latin1 |
| character_set_connection | latin1 |
| character_set_database | utf8mb4 |
| character_set_filesystem | binary |
| character_set_results | latin1 |
| character_set_server | latin1 |
| character_set_system | utf8 |
| character_sets_dir | /rdsdbbin/mysql-5.7.33.R2/share/charsets/ |
+--------------------------+-------------------------------------------+
8 rows in set (0.01 sec)

こうなる。

本来は、character_set_client などの文字コードが utf8mb4 にならなければいけない。実際、ubuntu18 で同じことをすると、utf8mb4 になる。

また、このキャラクタセットが latin1 になる現象は、 ubuntu18 上の mysql コマンドで、 --default-character-set=utf8mb4 をつけてみたり、/etc/mysql/conf.d/mysql.cnf の中に 文字コードの設定を書いても一切変わらない。

クライアント側で(無理やり)対応させる方法

mysql に接続後、

SET NAMES utf8mb4

すると、日本語は化けなくなる。

ちなみに実運用時は無駄なSQLは出したくないため、プロダクション環境でこれは行わないが、Django であれば DB設定をこのようにすることで実現できそう。

DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
...
'OPTIONS': {
'charset': 'utf8mb4',
'init_command': 'set names utf8mb4',
},
},
}

解決方法

この状態なら、クライアント側の設定では(上記 SET NAMES utf8mb4 以外では)回避できなそうなので、サーバ側で文字コードを設定する。RDS なら、パラメータグループで

character_set_client
character_set_connection
character_set_database
character_set_results
character_set_server

これらをすべて utf8mb4 に設定すれば良い。

実際は utf8mb4 以外の文字コードを使うことって通常無いので、最初からやっとけよって気もするが。

これらのパラメータは dynamic 属性のものなので、設定したら RDS の再起動なしに適用できる。

現在未評価
タイトルとURLをコピー

コメント

アーカイブ

2025
2024
2023
2022
2021
2020
2019
2018
2017
2016
2015
2014
2013
2012
2011