Home » August 2004 » mt-sql2db.cgi: mt-db2sql.cgiの逆変換CGIスクリプト

mt-sql2db.cgi: mt-db2sql.cgiの逆変換CGIスクリプト

コネタが続きますが、このエントリでは、MySQLなどに保存しているMovable TypeのデータをBerkeleyDBにコピーするための自作CGIスクリプト(mt-sql2db.cgi)を紹介します。

mt-sql2db.cgi

0.01(2004.08.09): 公開。

レンタルサーバなどでMySQLなどを使っている場合、どうしてもデータをロストする危険を感じないわけにはいきません。実際廉価なレンタルサーバでのSQLサーバ利用は「at your own risk」と明記されている場合が非常に多く、サービスの継続性にも不安を感じます。

一方で、Movable TypeはBerkeleyDB形式で作ったデータをSQLに変換する機能は提供しますが、その逆の機能は提供しません。確かに一旦SQLに変換してしまえば、lolipopのMySQLデータベースを簡単バックアップするCGIスクリプトに書いたようにSQLデータをバックアップすること自体は簡単です(しかもreadableだし、portableだし、だし)。が、そうして取ったバックアップからリカバリーしたい場合、リカバリー側環境でSQLサーバが無事に使えれば問題はないですが、そうでなければMovable Typeを継続して使うことができないということになります。

こうした事情もあり、最近頓にトラブルの多いBerkeleyDBからMySQLに移行したいがBerkeleyDBに戻せないのは困るという理由で二の足を踏んでいる、という人は割に多いのではないでしょうか? そんな人の背中を押すのがこのスクリプトの目的です。

このスクリプトは、端的に言ってMovable Type 3.0に付属のmt-db2sql.cgiの逆変換機能を提供します。mt.cfgでDBI ObjectDriverを指定しているときに、データベースに格納してあるすべてのMT Objectを読み込んではDBM形式で保存していく、というただそれだけのスクリプトです。


使い方

基本的な使い方は以下の通りです。

  1. 上記リンクよりCGIスクリプトをダウンロードして、mt-sql2db.cgiという名前で保存します。
  2. mt.cgiなどが置かれているディレクトリにアップロードし、mt.cgiなどと同様に実行権限を与えます。
  3. mt.cfgでObjectDriver、Database、DBUser、DBHost、(BerkeleyDBが使用するディレクトリを指定する)DataSourceが適切に設定されていることを確認してください。また、DataSourceで指定したディレクトリを作るのも忘れずに。
  4. ブラウザからmt-sql2db.cgiにアクセスしてCGIを実行してください。SQLサーバのデータがDataSourceで指定したディレクトリにBerkeleyDB形式でダンプされるはずです。
  5. 無事に済んだら、mt.cfgのObjectDriverの行をコメントアウトしてBerkeleyDBでの動作確認をしてください。

このツールはもう少し応用的な使い道もできます。

megu's blogのmeguさんにコメント欄でご示唆いただいたように、異なるSQLサーバ間のデータ形式変換にも使えます。例えば、MySQLで作ったデータを一旦BerkeleyDB形式に変換(このエントリのmt-sql2db.cgi)し、次にBerkeleyDB形式のデータをPostgreSQL形式に変換(MT3.0付属のmt-db2sql.cgi)することで、MySQL→PostgreSQLの移行ができます(vice versa)。

もちろん両スキーマ間の変換をする方が確実かつ高速なのは言うまでもないですが、この方法ならSQLの知識なしに(あるいはそれ専用のツールを使うことなしに)変換できるというメリットがあります。

注意点

  • エントリーの数が増えると非常に時間がかかるようになります。所要時間はおおよそエントリー数の2乗に比例すると考えてください。辛抱が肝心です。
  • レンタルサーバなどではスクリプトの実行時間が長くかかり過ぎると途中終了する場合があります。その場合にはこのツールは使えません。ちなみにLolipopではこのブログはバックアップできませんでした
  • BerkeleyDBへのバックアップは、mt.cfgのDataSourceで指定しているディレクトリに行います。すでにこのディレクトリにバックアップが存在する場合上書きされます
  • Known bugですが、Link this template to a file(このテンプレートにリンクするファイル)を指定しているテンプレートがあるとスクリプトが失敗することがあります。これはBerkeleyDBにsaveしようとする際に対象ファイルへのアクセスが発生するためです。原因は分かっていますが、面倒なので対処しません。
  • MySQLとPostgreSQLとSQLiteで動作することを確認しています。
  • MT2.6X~MT3.1Xでしか動作確認しておりません。
  • ご利用は計画的におながいいたします。念には念を入れてバックアップしてください。

このエントリーのトラックバックURL: http://as-is.net/mt/mt-tb.cgi/168

Links referred to this entry

Comments (23)

  1. こんにちは。
    私の環境でやってみました。
    ところが、下記のようなエラーになってしまうのです。
    なにか足りないのでしょうか?

    MT-SQL2DB: Copying data from your SQL database to BerkeleyDB

    Dumping MT::Author
    **** WARNING: DBI::db=HASH(0x8abc900)->disconnect invalidates 1 active statement handle (either destroy statement handles or call finish on them before disconnecting) at /home/blog/public_html/lib/MT/ObjectDriver/DBI.pm line 315.


    An error occurred while loading data: No ObjectDriver defined at /home/blog/public_html/lib/MT/Object.pm line 105.

    環境は
    MT3.01D-ja
    MySQL version: 3.23.58
    perl  v5.8.1 です。

    気にかかるのが、MySQLでの文字コードです。
    MySQLの設定ではujis(EUC-JP)にしてありますが、実際にはUTF-8のコンテンツが入っています。

    バックアップのことを考えると、ディレクトリごとtarで固められるので、BerkeleyDBのほうが便利だなぁと思い始めていたところなのです。

  2. エラーの件ですが、dbディレクトリを作っていないか、すでに作られているBerkeleyDBが壊れているのではないかと思います。

    MySQLのcharsetに関しては気にしなくてもいいというのが私の考えです。EUC-JPとUTF-8は同じ8bit領域のコードの列で文字を表すので。MySQL 4.XはUTF-8をサポートしていて、サーバにUTF-8で格納しておき、クライアント側でShift_JISで読み出すとかできるらしいです。

  3. ogawaさん、毎度すみません。
    確かに私、DB用のディレクトリを作成していませんでした。
    無意識に「ないものは作成してくれる」と勘違いしていました。
    そういえばcgiでしたものね....。ごめんなさい。
    いま、実行してみたら無事できました。
    MySQL、データベース上に格納される文字コードと、取り出すときの文字コードの変換をしてくれるようになるのなら、中身はEUCで、コンテンツはUTF-8というのが可能になりますね。
    4.0へのアップグレード、チャレンジしてみたいと思います!!

  4. SQLサーバー=EUC、クライアント(MovableType)=UTF-8ということですか、それは…できるのかな?

    念のため、SQLサーバー・クライアント間でコード変換が可能だとしても、Perl moduleにそのAPIが用意されているかどうかは分かりませんよー。

  5. こんばんは!
    あれからPostgreSQLが都合が良いことがわかりました。
    データベース内をUTF-8で、psqlで表示する際に自分が好きな文字コードにencodeできるようなので、試しにやってみたらバッチりでだったので、PostgreSQLでいってみようかなと思いなおしています。
    #もしかしたら、mysqlコマンドでも同様のことが出来るのかも?

    ただ、MySQL→PostgreSQL間でスキーマ-の変換が必要なようです。
    うまくいかなかったら、ogawaさんのツールをいったん介して行うかもです。
    PostgreSQLへの変換がうまくいったら、このcgiをもういちど試してみます。
    どうもありがとうございます!

  6. なるほど。SQLサーバ間のデータ変換にも使える(かも)というのは気が付いていませんでした。

    MySQLでUTF-8/UCS2が真っ当にサポートされたのは、4.1.1以降かららしいです。4.1系列はまだβ版でした…。

  7. こんにちは!
    できあがったPostgreSQLの環境で、mt-sql2db.cgiを利用してみました。
    問題なく変換できました。
    PostgreSQL 7.4.3です。

  8. ご確認ありがとうございました。

    あとはバージョン間の互換性をもう少し高めたいところです。
    MT3.1b1では3.0に比べてテーブルの数が一つ増えていたりします。

  9. mt-sql2db.cgiをご紹介いただきまして、ありがとうございました。
    lolipopさんのサーバー DBHost: mysql04.lolipop.jpで動作確認しました。
    【MySQL から Berkeley DB へコンバート】

    Movable Type 3.01D bug fix release [07.09.2004]
    Movable Type 2.661
    ともに、問題ありませんでした。
    Movable Type 2.661については、
    http://infohitomi.lolipop.jp/SQLtoBerkeley/
    をご覧下さい。
    なお、lolipopさんとの契約期限を数日過ぎていますので、ページは削除されているかもしれません。ご了承下さい。

  10. ご報告ありがとうございました。2.6系では動作しそうですね。

    MT3.0のCallback APIを使えば、SQLサーバを使いながら常時BerkeleyDBにミラーリングし続けるPluginが簡単に書ける気がします。気が向いたらやってみるつもりです。

  11. すでに報告済み?のようですが、Xrea.comさんのサーバーのSQLデーターベース PostgreSQL 7.4.X、MySQL 4.0.X (詳細なバージョン、サーバー環境は公開を控えさせていただきます)でも、問題なくコンバートできました。こちらは、Movable Type 3.01D-ja(日本語版)を使用しました。

  12. 重ね重ねありがとうございます。

  13. 明けましておめでとうございます
    MySQL 4.1.7 では、mt.cfg 設定: PublishCharset UTF-8 を選択すると、mt-load.cgi 実行時エラーとなります。(PublishCharset) EUC-JP では問題ありません(Shift_JIS は未確認です)。2005/1/5, TrackBackさせていただきました。
    MT 新規インストールであれば、ちょっと注意するだけでよいのですが、MT 本家のサポートフォーラムでもほとんど問題となっていないことが不思議です。Xrea.com さんのサーバだけの問題なのでしょうか。
    本年もよろしくお願いいたします。

  14. 明けましておめでとうございます。

    MySQL 4.1.7は4.1系列初の安定バージョンですから、まだあまり使われていません。
    Xreaにインストールされているのはちょっと意外でしたが、しかし「入出力charsetをEUC-JPにしなければならない」という制約はXreaのMySQLの設定によるものでXrea自身がユーザに注意を喚起すべきでしょうね。Movable Type側で対応することではないようにも思います。Tipsとしては有用ですよね。

    予想ですが、多分、MySQL 4.1.7の入出力charsetと内部charsetとの変換は、auto-conversionやno-conversionにも設定できるのではないかと思います。

  15. ご指摘のとおり、
    http://pcweb.mycom.co.jp/cgi-bin/print?id=25624
    では、「--with-charset=binary」ビルドオプションでインストールし、my.cnf に必要なキャラクタセットを設定すると、文字コードの自動変換機能に伴う多くの問題が解決するように、記載されています。実際の動作、特に mt-load.cgi の実行については確認しておりませんが、MySQL 4.1系へのアップグレードを予定されている Movable Type 管理者の方は、注意が必要のようです。Xrea.comさんでは、MySQL 4.1系の 文字コード EUC-JP 以外はサポート外とのことですので、MT管理者は、s101, s102サーバを利用しない方がお得のようです。なお、サーバ機 s101, s102のみ MySQL 4.1系、その後の新サーバ機(10台余り)では、MySQL 4.0.23 がインストール (downgrade or version down)されています。

  16. こんには、はじめまして。

    僕のMovableTypeはVersion 3.151-jaなのですが、
    駄目モトでツールを使わせていただきました。

    Dumping MT::Author~Dumping MT::Logまで
    mt-sql2db.cgiは順調に動きました。

    しかしながらmt-cfgを変更して、ログインしたところ
    それぞれのブログがみれなくなってしまいました。
    (ログイン自体はできるのですが、それぞれのブログが見えない)
    おそらく、権限のインポートが美味く入ってないのだと思います。
    何かうまくいく方法等ございましたら、ご教授ください。

    ちなみに、サブカテゴリは対応していなかったので、すべて
    トップカテゴリに戻してcgiを実行しています。
    また、初期ID-PassのMelody-Nelson ではログイン不可でしが。
    また、パスワード再送しましたが、ブログが見えない状況です。

  17. 3.151-jaでも問題ないと思います。

    MT::Author, MT::Permissionのところで何かエラーなどは表示されていないでしょうか。

    サブカテゴリーの対応はうまくいく場合とそうでない場合があります。これはmt-db2sql.cgiでも同様です。ですのですべてのカテゴリーを一旦トップカテゴリーに変更する必要があります。これはおこなっていらっしゃるようですね。

  18. さっそくのお返事ありがとうございました。

    結論を申し上げますとうまく移行完了することが出来ました。
    原因はmt-sql2db.cgiが最後まで動く前にタイムアウトしてた
    みたいです。何度か試したら最後に

    Done copying data from your SQL database to BerkeleyDB.

    のメッセージがでて、きちんと移行完了しました。
    ありがとうございました。

  19. これを使ってデータベースの移行をしました!
    トラックバックを一括変更したいときなんか、
    BerkeleyDB使ったことないんで、
    SQLにした方が高速!

    まじでおすすめです。

    ありがとーございました。

  20. ogawaさん、はじめまして。
    MySQLに移行すれば軽くなると思ってやってみたんですが
    逆に重くなってしまいました(汗
    それでこちらにたどりついて安堵し
    mt-sql2db.cgiを実行しましたら

    Dumping MT::Category
    ..**** WARNING: DBI::db=HASH(0x844b0b0)->disconnect invalidates 1 active statement handle (either destroy statement handles or call finish on them before disconnecting) at lib/MT/ObjectDriver/DBI.pm line 327.


    An error occurred while loading data:

    こんなエラーが出てしまいました。
    何かワタシのやり方が間違ってるんでしょうか?教えてください。

  21. mt-sql2db.cgi? mt-db-convert.cgiではなく?

    確かにこのエントリーでmt-sql2db.cgiは公開していますが、なにぶんメンテナンスをしていないこともあり、すでにobsoleteです。サブカテゴリーを作っている場合やMT 3.2などではうまく動かない可能性があります。

    mt-db-convert.cgiでもMySQL→BerkeleyDBの変換はできますよ。mt-db-convert.cgiに関しては以下のエントリーを参照してください。

    http://as-is.net/blog/archives/001023.html

  22. ogawaさん、おはようございます!
    早々とお返事ありがとうございました。
    mt-db-convert.cgiでは全部に対応してるんですね。
    名前は、さえらさんのところで見ていたんですが。。。
    恥ずかしいです。ごめんなさい。

    早速、使ってみました!
    最初、途中で止まってしまったんですが
    ログを消去してから更新してみたところうまくいきました。
    とっても嬉しいです。ありがとうございました。

    でもちょっとお聞きしたいんですが
    エントリーのところで

    ......**** WARNING: Character in 'C' format wrapped in pack at extlib/Jcode.pm line 733.

    と出ました。
    前にも再構築すると出たんです。
    これはどういう意味なんでしょうか?
    ここでは関係ないことを聞いてスミマセン。

  23. Jcode.pmで文字コード認識がちゃんとできていないのでしょうね。ブログ名に一文字だけ漢字を使ったりするのを止めたらいかがでしょう。

    MT 3.2では、Perl 5.8以降ならばEncode.pmが使われるようになっているのでこのメッセージは表示されないはずです。可能ならPerl 5.8を使った方がよいでしょう。

Post a comment

Remember me?