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をコピー

コメント

アーカイブ

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