現象:RHEL 7.9上のMySQL 8クライアントで日本語が入力できない
Red Hat Enterprise Linux (RHEL) 7.9環境でRed Hat Software Collections (RHSCL) を利用してMySQL 8のクライアントをインストールし、MySQLサーバーへ接続したところ、コマンドラインクライアントで日本語が入力できない問題が発生しました。
インストールしたパッケージは下記の通り
yum install rh-mysql80-mysql
MySQLに接続できますが、日本語入力しても文字が消える現象になりました。
切り分けと調査
問題解決のために、以下の項目を確認しましたが、いずれも解決には至りませんでした。
ロケール設定の確認
システムのロケールを ja_JP.UTF-8
に設定しましたが、状況は改善されませんでした。
# locale
LANG=ja_JP.UTF-8
LC_CTYPE="ja_JP.UTF-8"
LC_NUMERIC="ja_JP.UTF-8"
LC_TIME="ja_JP.UTF-8"
LC_COLLATE="ja_JP.UTF-8"
LC_MONETARY="ja_JP.UTF-8"
LC_MESSAGES="ja_JP.UTF-8"
LC_PAPER="ja_JP.UTF-8"
LC_NAME="ja_JP.UTF-8"
LC_ADDRESS="ja_JP.UTF-8"
LC_TELEPHONE="ja_JP.UTF-8"
LC_MEASUREMENT="ja_JP.UTF-8"
LC_IDENTIFICATION="ja_JP.UTF-8"
LC_ALL=ja_JP.UTF-8
この設定でも、mysql
クライアント内で日本語を入力すると、Enterキーで確定した時点で文字が消える現象は変わりませんでした。
#''内に日本語入力をしてもEnterキーで確定した時点で文字が消える
mysql> select '';
+--+
| |
+--+
| |
+--+
MySQLクライアント設定(my.cnf)の確認
クライアント側の設定ファイル (my.cnf
) に default-character-set=utf8mb4
を追記する方法を試しましたが、効果はありませんでした。
utf8mb4、utf8設定でも同様の状態でした。
環境の比較
RHEL 7.9 + MySQL 5.7: 日本語入力は問題なく動作しました。
RHEL 8 / Ubuntu + MySQL 8: こちらも問題なく動作しました。
この結果から、問題は「RHEL 7.9とMySQL 8 (RHSCL版)」という特定の組み合わせで発生する固有の問題であると推測しました。
原因の特定:古いバージョンのlibedit
調査を進めた結果、RHSCL版のMySQL 8クライアントが使用しているコマンドライン編集ライブラリ libedit
に原因があることが判明しました。
RHEL 7.9のシステムに標準でインストールされているlibedit
のバージョンは 3.0-12.20121213cvs.el7(バージョン40)
です。一方、libedit
のUTF-8サポートは、2016年6月18日以降のバージョン54以降となっています。
2016-06-18 Jess Thrysoee * version-info: 0:54:0 * all: sync with upstream source * deprecate option --enable-widec. Upstream now always build with unicode (wide-char/UTF-8) support.Editline Library (libedit) ChangeLog
解決策:libeditのアップデートと適用
libeditをUTF-8に対応した新しいバージョンにアップデートし、MySQLクライアントがその新しいライブラリを参照するように設定します。
最新版libeditのコンパイルとインストール
Editline Libraryから最新版をダウンロードしてconfigure→makeします。
デフォルトでインストールすると「/usr/local/lib」に入るのですが、指定してインストールしたい場合はconfigureにlibdirの引数を追加します。
ビルドツールのインストール
yum install gcc ncurses-devel
ソースコードのダウンロードと展開
wget https://www.thrysoee.dk/editline/libedit-20221030-3.1.tar.gz
tar -zxvf libedit-20221030-3.1.tar.gz
cd libedit-20221030-3.1
コンパイルとインストール システムの他の部分への影響を避けるため、インストール先を /usr/local/lib64 に指定します。
./configure --prefix=/usr/local --libdir=/usr/local/lib64
make
sudo make install
MySQLクライアントへの適用
そのままだとインストールしたlibeditは使われないため、mysqlの設定を行っていきます。
システムの安定性を保つため、MySQLクライアントを実行するときだけ、新しいライブラリを読み込むように設定します。
LD_LIBRARY_PATHを指定して実行
環境変数 LD_LIBRARY_PATH に新しいライブラリのパスを追加して mysql コマンドを実行します。RHSCLでインストールした mysql のパスは /opt/rh/rh-mysql80/root/usr/bin/mysql です。
LD_LIBRARY_PATH=/usr/local/lib64:$LD_LIBRARY_PATH /usr/bin/mysql -uroot -ppassword -h 192.168.xxx.xxx
エイリアス(alias)の設定で恒久化
毎回コマンドを長く入力するのは手間がかかるため、シェルの設定ファイル(~/.bashrcなど)にエイリアスを登録しておくと便利です。
設定を反映させるために、source ~/.bashrc
を実行するか、ターミナルに再ログインしてください。
alias mysql="LD_LIBRARY_PATH=/usr/local/lib64:$LD_LIBRARY_PATH /usr/bin/mysql"
動作確認:
# 実際にログインして文字入力できることを確認する
mysql> select 'あああ';
+-----------+
| あああ |
+-----------+
| あああ |
+-----------+
1 row in set (0.00 sec)
システム全体への適用(非推奨)
ldconfig を使って新しいライブラリのパスをシステムに認識させる方法もありますが、他のアプリケーションに予期せぬ影響を及ぼすリスクがあるため推奨されません。
参考として手順のみ記載します(root権限が必要です)。
#root権限で実行
echo /usr/local/lib64 > /etc/ld.so.conf.d/libedit.conf
ldconfig
#lddで置き換わっていることを確認
ldd /usr/bin/mysql |grep libedit
libedit.so.0 => /usr/local/lib64/libedit.so.0 (0x00007f8d1ad93000)
まとめと補足
- 原因: RHEL 7.9に付属する
libedit
ライブラリのバージョンが古く、UTF-8に完全対応していないため。 - 対策: UTF-8に対応した最新版の
libedit
をソースからビルドし、LD_LIBRARY_PATH
を用いてMySQLクライアント実行時のみに新しいライブラリを読み込ませる。
RHEL 7は2024年6月30日にメンテナンスサポートが終了しました。根本的な解決策としては、RHEL 8やRHEL 9といった新しいOSバージョンへ移行することを強く推奨します。
ちなみに、RHEL 8.7に付属するlibeditのバージョンは3.1-23.20170329(バージョン56)であり、本問題は発生しません。