| ../ |
VPSサーバー(CentOS8.2)にMySQL 8.0をインストールして、character_setを以下のように設定して利用しようと考えた。
mysql> show variables like 'char%';
+--------------------------+----------------------------+
| Variable_name | Value |
+--------------------------+----------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | utf8 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
しかし、GNOMEデスクトップでMySQLコンソールを開いて、mysql>
のプロンプトになっている状態で、日本語が入力できないという現象が起きた。正確には、日本語は入力でき、かな漢字変換もできるが、それをenterキーで確定した後で、変換された文字列を取り込めていない。入力した日本語の文字列も変換された日本語の文字列も、すっかり消えるのである。MySQLコンソールで日本語を入力する場面は、INSERT文やUPDATE文を実行したいときである。このままでは不便である。
原因分析
MySQLコンソールにバグがあるのか、日本語版IMEであるibus-kkcにバグがあるのか、MySQLコンソールとibus-kkcの相性の問題なのかは判断できない。CentOS6.xのときには、IMEはibus-anthyであったが問題はなく、MySQLコンソールで日本語が入力できている。私のところでは、CentOS6.2のサーバーも現役で稼働中なので、確認してみたが問題はなかった。Anthyは2001年にリリースされ、libkkcは2013年にリリースされたそうだ。CentOSでは、2014年にリリースされたCentOS7からlibkkcが採用されたようだ。私はCentOS7は未経験なので、状況を把握できていなかった。Fedoraもlibkkcを採用しているようで、同じ症状はFedoraでも起きているそうだ。
※ibus-kkcやibus-anthyはCentOSのIMEのインタフェースであり、本体のかな漢字変換機能がlibkkcやAnthyである。
localeの設定だけでは解決しないし、MySQLの[client]のdefault-character-setの設定でも解決しないことが分かった。localeは、UTF-8に設定されていれば問題ない。UTF-8でもutf8でもいい。大文字小文字やハイフンの有無は関係ない。
$ locale
LC_ALL=ja_JP.UTF-8
LANG=ja_JP.UTF-8
MySQLの[client]のdefault-character-setは、utf8でもutf8mb4でも関係ない。以下は、utf8mb4を設定した場合である。どちらで設定してもかな漢字変換は機能しているが、その後のMySQLコンソールでibus経由で変換された文字列を取り込む際の挙動がおかしいのである。
$ vi /etc/my.cnf.d/client.cnf
[client]
# default-character-set=
# default-character-set=utf8
default-character-set=utf8mb4
回避策
MySQLコンソールか日本語版IMEであるibus-kkcにバグがあるのだろうが、経験的に回避策があることは掴めた。非常におかしな挙動なのだが、client.cnfでdefault-character-setの行をコメントアウトするとうまくいく。つまり、以下のように記述する。いや、[client]でdefault-character-setの記述をしないと言った方がいいか。
$ vi /etc/my.cnf.d/client.cnf
[client]
# default-character-set=
# default-character-set=utf8
# default-character-set=utf8mb4
mysqldを再起動して、MySQLコンソールで再接続してみる。show variablesで確認すると、client,connection,resultsが初期状態でutf8mb4になる。serverは、私のところではutf8で使いたいので、そこは譲れない。この状態で、日本語が入力でき、INSERT文にも日本語が使えるようになる。
mysql> show variables like 'char%';
+--------------------------+----------------------------+
| Variable_name | Value |
+--------------------------+----------------------------+
| character_set_client | utf8mb4 |
| character_set_connection | utf8mb4 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | utf8mb4 |
| character_set_server | utf8 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
mysql> insert dummy1 values(10,'梶井基次郎');
Query OK, 1 row affected (0.01 sec)
mysql> select * from dummy1;
+------+-----------------+
| id | name |
+------+-----------------+
| 10 | 梶井基次郎 |
+------+-----------------+
1 row in set (0.00 sec)
では、client.cnfで[client]のdefault-character-set=utf8mb4を明示的に設定してみるとどうだろう。以下の感じである。
$ vi /etc/my.cnf.d/client.cnf
[client]
# default-character-set=
# default-character-set=utf8
default-character-set=utf8mb4
明示的にdefault-character-set=utf8mb4を設定して、mysqldを再起動して、MySQLコンソールで再接続してみる。show variablesで確認すると、前述のものと全く同じでclient,connection,resultsがutf8mb4になっている。
mysql> show variables like 'char%';
+--------------------------+----------------------------+
| Variable_name | Value |
+--------------------------+----------------------------+
| character_set_client | utf8mb4 |
| character_set_connection | utf8mb4 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | utf8mb4 |
| character_set_server | utf8 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
しかし、日本語は入力できないのである。さっぱり分からない。character_setを見ただけでは差異はないが、内部的に挙動が異なっているのだ。とりあえずの回避策としては、[client]のdefault-character-setを明示的に設定しないで、初期値としてutf8mb4が選択された場合のみ、日本語が入力できるということはわかった。
default-character-set=utf8で利用したい場合
[client]のdefault-character-set=utf8を設定して利用したい場合、MySQLコンソールからは日本語が入力できないので、別の回避策が必要である。私は、sourceコマンドで読み込みながら、INSERT文やUPDATE文を実行するのがいいかと思う。例えば、作業ディレクトリにwork/temp.sqlといったテキストファイルを作成して、同時に開いて、編集と実行を繰り返す。
# create table dummy1 (id int, name varchar(50));
# insert dummy1 values (10,'梶井基次郎');
insert dummy1 values (20,'中島敦');
MySQLのコンソールからは、適宜、sourceコマンドでファイルを読み込めばいい。編集する、読み込む、編集する、読み込むの繰り返しでなんとかなるだろう。
$ mysql -uroot -p dummydb;
mysql> source work/temp.sql;
mysql> select * from dummy1;
+------+-----------------+
| id | name |
+------+-----------------+
| 10 | 梶井基次郎 |
| 20 | 中島敦 |
+------+-----------------+
以上