風柳メモ

ソフトウェア・プログラミング関連の覚書が中心

mysqldumpではまる

レンタルサーバ上にあるMySQLのデータベースの自動バックアップの必要が出来たので、mysqldump が使える環境みたいだしと思ってこれでダンプしたものをcronで定期的にダウンロードすればいいか、と安易に考えていて、現在はまり中。

mysqldump --opt --default-character-set=binary --user=xxxxxxx --password=yyyyyyyy dbname > dbname.dmp
cat dbname.dmp | nkf -Ew -Lu > dbname-utf8.dmp

で見てみたら、INSERT 文とかの日本語はきちんと変換されているのだけれど、テーブル定義で

`fruit` set('林檎','蜜柑','苺') DEFAULT NULL,

みたいに日本語を含む SET 型を使って使っている箇所だけが化けてしまう。
これ、どうすればいいんだろう……。
当たり前だが、phpMyAdminを使ってダウンロードした方のSQLテキストはきちんとEUC-JP→UTF-8に変換できるし、SET型の定義箇所も正常。


追記

実際に試すとこんな感じに。

cat dbname.dmp | nkf -Ew -Lu | grep fruit

  `fruit` set('存辿','捉卒損','巽探') NOT NULL
INSERT INTO `test_table` (`fruit`) VALUES ('林檎'),('蜜柑,苺');

…助けて(哀)。
mysqldumpのバージョンは mysqldump Ver 10.13 Distrib 5.1.50, for redhat-linux-gnu (x86_64) らしい


追記2

結局、mysqldump そのものでは、どうオプション等をいじくってもなんともならないみたいだったので、

mysqldump.php



mysqldump.php is a PHP script that dumps a MySQL database into a mysqldump compatible SQL script. It can also dump a table into CSV format.

mysqldump.php – Freecode

あたりを試してみることにしよう……。


それにしても、この件ではまっている人、見かけないなぁ……。SET型はMySQL独自だし、さらにその項目に日本語とか使っている人自体が少ないってこと…?
一応、

この記事では、一般的に WordPress の MySQL データベーステーブルを、ある文字コード(キャラクタセット)から別の文字コードに変換する方法について説明します。
 :
(中略)
 :
説明を単純にするため、ここでは文字コードが latin1 のデータベースを utf8 に変換するものとします。

問題点
文字コードを変換するには、MySQL の ALTER TABLE コマンドを使用する必要があります。文字コードを変換すると、すべての TEXT 型フィールド(および類似フィールド)が UTF-8 に変換されますが、その際に格納されているテキストデータが壊れてしまいます。これは、MySQL 側では変換前のデータが latin1 文字コードで保存されていることを前提にしているのですが、WordPress は(UTF-8 で動いているため) unicode の文字をデータベースに保存していることがあり、変換後に文字化けしてしまうのです。

解決策
この問題を回避するため、まずすべての TEXT 型および類似フィールドを、対応するバイナリのデータ型に ALTER コマンドを使って変換します。文字コードを変換した後、データ型を元に戻します。

DB 文字コードセットの変換 - WordPress Codex 日本語版

このあたりを参考にすればなんとかなりそうだけれど、コマンドライン使えない環境でやるには手順が煩雑すぎるのでデバッグが大変そうだ……。


追記3

character_set_*の状態

ちなみに件のサーバの

SHOW VARIABLES LIKE 'character\_set\_%';

の結果は、

Variable_name Value
character_set_client latin1
character_set_connection latin1
character_set_database latin1
character_set_filesystem binary
character_set_results latin1
character_set_server latin1
character_set_system utf8

のような感じ。