MariaDBサーバにmysql-connector-pythonを利用して接続を試みた時に「’utf8mb4_0900_ai_ci’なんて知らないよ。」というエラーが発生したので、collationを設定して修正した話。

By | 2023年12月11日

はじめに

Fedora39へのアップグレード終了後に本Webサイトで使用しているWordPressが使用しているMariaDBのサーバに接続してみたところ、

“Unknown collation: ‘utf8mb4_0900_ai_ci'”

というエラーが発生したので、原因を探ることにしました。

スポンサーリンク

発生した現象の詳細

Python 3.12で記述したプログラムを使ってMariaDB(10.5.22)に接続を試みたところ、以下のエラーが発生し接続できませんでした。

Traceback (most recent call last):
File “/home/panda/pandanotekit/sidestory/./dump_articles_list.py”, line 32, in
conn = mysql.connector.connect(user=dbconfig[“user”],password=dbconfig[“password”],host=dbconfig[“host”],database=dbconfig[“dbname”],charset=”utf8mb4″)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/usr/lib/python3.12/site-packages/mysql/connector/__init__.py”, line 265, in connect
return MySQLConnection(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/usr/lib/python3.12/site-packages/mysql/connector/connection.py”, line 104, in __init__
self.connect(**kwargs)
File “/usr/lib/python3.12/site-packages/mysql/connector/abstracts.py”, line 970, in connect
self._post_connection()
File “/usr/lib/python3.12/site-packages/mysql/connector/abstracts.py”, line 942, in _post_connection
self.set_charset_collation(self._charset_id)
File “/usr/lib/python3.12/site-packages/mysql/connector/abstracts.py”, line 900, in set_charset_collation
self._execute_query(“SET NAMES ‘{0}’ COLLATE ‘{1}'”.format(
File “/usr/lib/python3.12/site-packages/mysql/connector/connection.py”, line 979, in _execute_query
self.cmd_query(query)
File “/usr/lib/python3.12/site-packages/mysql/connector/connection.py”, line 599, in cmd_query
result = self._handle_result(self._send_cmd(ServerCmd.QUERY, query))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/usr/lib/python3.12/site-packages/mysql/connector/connection.py”, line 487, in _handle_result
raise errors.get_exception(packet)
mysql.connector.errors.DatabaseError: 1273 (HY000): Unknown collation: ‘utf8mb4_0900_ai_ci’

 

解決策

mysql.connector.connect関数の実行時の引数にcollation="utf8mb4_general_ci"を追加しました。

mysql.connector.connect関数の引数を以下の通りに書き換えています。

mysql.connector.connect(user=dbconfig[“user”],password=dbconfig[“password”],host=dbconfig[“host”],database=dbconfig[“dbname”],charset=”utf8mb4″,collation=”utf8mb4_general_ci”)

 

原因

ここまではGoogle先生にお伺いを立てながら解決策の検討を優先し、いったんは解決することができました。

解決したところで、根本的な原因を探ることにしました。

サーバ側の確認

まず、サーバ側の状況を確認します。

MariaDBサーバでサポートしているCollationを調べてみます。

結果は以下の通りです。エラー発生時に指定していた”utf8mb4_0900_ai_ci”はサーバ側ではサポートしていないことがわかります。

MariaDB [pandanote]> show collation where charset like ‘%utf8mb4%’;
+——————————+———+——+———+———-+———+
| Collation | Charset | Id | Default | Compiled | Sortlen |
+——————————+———+——+———+———-+———+
| utf8mb4_general_ci | utf8mb4 | 45 | Yes | Yes | 1 |
| utf8mb4_bin | utf8mb4 | 46 | | Yes | 1 |
| utf8mb4_unicode_ci | utf8mb4 | 224 | | Yes | 8 |
| utf8mb4_icelandic_ci | utf8mb4 | 225 | | Yes | 8 |
| utf8mb4_latvian_ci | utf8mb4 | 226 | | Yes | 8 |
| utf8mb4_romanian_ci | utf8mb4 | 227 | | Yes | 8 |
| utf8mb4_slovenian_ci | utf8mb4 | 228 | | Yes | 8 |
| utf8mb4_polish_ci | utf8mb4 | 229 | | Yes | 8 |
| utf8mb4_estonian_ci | utf8mb4 | 230 | | Yes | 8 |
| utf8mb4_spanish_ci | utf8mb4 | 231 | | Yes | 8 |
| utf8mb4_swedish_ci | utf8mb4 | 232 | | Yes | 8 |
| utf8mb4_turkish_ci | utf8mb4 | 233 | | Yes | 8 |
| utf8mb4_czech_ci | utf8mb4 | 234 | | Yes | 8 |
| utf8mb4_danish_ci | utf8mb4 | 235 | | Yes | 8 |
| utf8mb4_lithuanian_ci | utf8mb4 | 236 | | Yes | 8 |
| utf8mb4_slovak_ci | utf8mb4 | 237 | | Yes | 8 |
| utf8mb4_spanish2_ci | utf8mb4 | 238 | | Yes | 8 |
| utf8mb4_roman_ci | utf8mb4 | 239 | | Yes | 8 |
| utf8mb4_persian_ci | utf8mb4 | 240 | | Yes | 8 |
| utf8mb4_esperanto_ci | utf8mb4 | 241 | | Yes | 8 |
| utf8mb4_hungarian_ci | utf8mb4 | 242 | | Yes | 8 |
| utf8mb4_sinhala_ci | utf8mb4 | 243 | | Yes | 8 |
| utf8mb4_german2_ci | utf8mb4 | 244 | | Yes | 8 |
| utf8mb4_croatian_mysql561_ci | utf8mb4 | 245 | | Yes | 8 |
| utf8mb4_unicode_520_ci | utf8mb4 | 246 | | Yes | 8 |
| utf8mb4_vietnamese_ci | utf8mb4 | 247 | | Yes | 8 |
| utf8mb4_croatian_ci | utf8mb4 | 608 | | Yes | 8 |
| utf8mb4_myanmar_ci | utf8mb4 | 609 | | Yes | 8 |
| utf8mb4_thai_520_w2 | utf8mb4 | 610 | | Yes | 4 |
| utf8mb4_general_nopad_ci | utf8mb4 | 1069 | | Yes | 1 |
| utf8mb4_nopad_bin | utf8mb4 | 1070 | | Yes | 1 |
| utf8mb4_unicode_nopad_ci | utf8mb4 | 1248 | | Yes | 8 |
| utf8mb4_unicode_520_nopad_ci | utf8mb4 | 1270 | | Yes | 8 |
+——————————+———+——+———+———-+———+
33 rows in set (0.001 sec)

スポンサーリンク

 

サーバ上は特に問題と考えられる点はなさそうです。

クライアント側

次にクライアント側(mysql-connector-python)を調べます。

Fedora39へのアップグレード時には記録をしなかったので、再度確認です。

すると…

panda@fedora:~$ python
Python 3.12.0 (main, Oct 2 2023, 00:00:00) [GCC 13.2.1 20230918 (Red Hat 13.2.1-3)] on linux
Type “help”, “copyright”, “credits” or “license” for more information.
>>> import mysql.connector
>>> print(mysql.connector.__version__)
8.0.21

バージョンは8.0.21であることがわかります。

ここでmysql-connector-pythonパッケージはMySQL謹製のものであって、MariaDBが提供しているものではないことを思い出しました。

そこで、mysql-connector-pythonパッケージのdefaultのcollationを調べます。

panda@fedora:~$ python
Python 3.12.0 (main, Oct 2 2023, 00:00:00) [GCC 13.2.1 20230918 (Red Hat 13.2.1-3)] on linux
Type “help”, “copyright”, “credits” or “license” for more information.
>>> import mysql.connector
>>> from mysql.connector import CharacterSet
>>> CharacterSet.get_default_collation(‘utf8mb4’)
(‘utf8mb4_0900_ai_ci’, ‘utf8mb4’, 255)

 

どうやら、上記のクライアントの設定が原因だったようです。

まとめ

MariaDBを使い続けていると、以下の構成になっていることを忘れがちですね。

  • サーバ: MariaDB
  • クライアント(コネクタ): MySQL用(MariaDB用ではない)
  • クライアント(コマンドラインツール): MariaDB謹製

クライアントがMySQL謹製のものとそうでないものの2種類あるので、コマンドラインツールのクライアントの状況を調べただけでは原因にたどり着くことができないところが曲者感を感じるところです。

この記事は以上です。