Blogの最近のブログ記事

うちの Blog で利用している Movable Type は SQLite でデータ保存を行っていたのですが、どうもその SQLite データファイルが、利用しているホスティングであるさくらサーバの容量に対して到底無視できない割合(1/4)を利用しているということが判明。事実、容量の空きが非常に苦しいものとなってきていました。
その一方、さくらでは別途 MySQL も用意されており、ユーザは www 用サーバとは別に準備されたいくつかの MySQL サーバのうちの1つを選択し利用できるというサービス体系になっています。

そんな利用状況なさくらサービス、ひょっとすると使用可能なホスティングデータ量ってば、利用可能なサーバ容量の範囲とは別でないかという甘い考えが思いついたことはさておき、そもそも SQLite よりも MySQL サーバを利用するほうが保持するデータ容量は少なくなるであろうという考えの元、SQLite から MySQL へデータ移行することにしました。

その際、当方の SQLite におけるデータ構造や SQL 内容の理解がないので、1つ1つ確認しながら出来るよう、大よそを手動で事を進めていきました。今回のケースは Movable Type におけるお話ですが、他のものにもある程度流用できるのではないでしょうか。なおデータベース、および SQL についての若干ながらの知識が必要になるかもしれません。(SQL エラーが発生した場合に対応できるとか。)


0. 環境

参考までに、今回の環境は以下のとおり。
なお作業はオーソドックスにすべて CLI ベースのクライアントで進めました。

* MySQL 4.0.27
* SQLite 3.3.17
* Movable Type 4.0


1. Movable Typeのデータスキーマを MySQL 側に作成

まず MySQL 上に Movable Type のデータが格納できるよう、スキーマを作成します。
MT の設定ファイル(mt-config.cgi)内に記述されたデータベース接続設定を SQLite から MySQL のものへ変更し保存します。MT はかつて SQLite 環境で動いていたもので問題ありません。むしろこのまま MySQL へ移行しようとするので、へたに新しい MT の管理ページを作成する必要はありません。

続けて MT の管理ページへアクセスします。すると MT は MySQL 上に MT 用データが存在しないため、新規作成を行おうとしますので、これを進めていきます。MTユーザ登録などもあわせて行う流れとなりますが、内容を覚えておく必要はありません。

作成が完了した後、MySQL クライアントを使って、MT 用テーブルのデータを全て消去します。MT 用テーブルは、テーブル名の先頭すべてに「mt_」という接頭辞がついているものです。
テーブルの削除ではなく、データの削除であることに注意しましょう。データ削除コマンドは「truncate テーブル名」です。またその他のテーブルデータも消えぬことのないように…。

これで MySQL 側の受け口ができました。


2. SQLite のデータダンプ

続いて SQLite データをダンプします。

SQLite データは1つのファイルにまとめられている状態となっています。sqlite のコマンドツールはこのデータファイルを指定して実行する仕組みとなっています。またデータダンプは、sqlite の「.dump」コマンドで行います。たとえば SQLite データファイル example.db に対してのデータダンプは、CLI より以下のように実行します。

$ echo '.dump' | sqlite example.db > sqlite.dump.sql

SQLite データファイルの指定、および sqlite コマンドの違いに気をつけましょう。(さくらの場合、「sqlite3」コマンドでした。)

このコマンドの実行で、sqlite.dump.sql というテキストベースの SQL データが出来ました。



3. SQL データを MySQL 向けに編集

SQLite のダンプデータは、SQL 文によるデータベースの情報や操作が記載されています。
SQL は色々なデータベースで利用されているものですが、今回ダンプした直後の内容では一部 MySQL で利用できないものが含まれているので、これを編集します。

* 一行目の「BEGIN TRANSACTION;」を削除
* 最終行の「COMMIT;」を削除
* その直前の「CREATE INDEX~」行をすべて削除

まず以上のことを行うことで、データ内は「CREATE TABLE~」と「INSERT INTO~」のみのものとなります。

本来ならば、ここから「CREATE TABLE~」のSQLもすべて削除し「INSERT INTO~」のみにすることで MySQL への投入準備が整うのですが、私の場合はここから「INSERT INTO~」文を編集する必要がありました。このままデータを INSERT してしまうと、MySQL 上では目的のデータ構造とは異なるものになろうとしていたからです。

例えば、ダンプデータ内の CREATE TABLE 文が

CREATE TABLE mt_placement (
    placement_id integer not null primary key,
    placement_blog_id integer not null,
    placement_category_id integer not null,
    placement_entry_id integer not null,
    placement_is_primary boolean not null
);

というものに対し、実際のこのテーブルへの INSERT 文は
INSERT INTO "mt_placement" VALUES (4,2,2,4,1);

となっていたとします。データベースに対して CREATE TABLE を行った後にこの INSERT を実行すると、以下のようなレコードができます。

mt_placement テーブル
---------------------
placement_id = 4
placement_blog_id = 2
placement_category_id = 2
placement_entry_id = 4
placement_is_primary = 1

一方、既に MySQL 上で準備されている mt_placement テーブルは、先ほどの CREATE TABLE のものと同じとは限りません。同じテーブル内容なものの、カラム順が異なるケースが実際にありました。(以下は一例)

CREATE TABLE mt_placement (
    placement_id int(11) not null auto_increment,
    placement_entry_id int(11) not null,
    placement_blog_id int(11) not null,
    placement_category_id int(11) not null,
    placement_is_primary tinyint(4) not null,
    PRIMARY KEY(id)
)
type = MYISAM;

この場合、同じ INSERT 文を行った mt_placement テーブルはこうなります。

mt_placement テーブル
---------------------
placement_id = 4
placement_entry_id = 2
placement_blog_id = 2
placement_category_id = 4
placement_is_primary = 1

カラム名を指定した INSERT 文ではないため、テーブル定義を行った順に INSERT が行われてしまい、結果違うレコードに仕上がってしまいます。

これを回避すべく、ダンプデータ内に記述されている CREATE TABLE 文のカラム順序どおりに、INSERT 文を編集していくのです。(説明長い!)


先ほどのこれは、

INSERT INTO "mt_placement" VALUES (4,2,2,4,1);

こうします。

INSERT INTO mt_placement
(placement_id, placement_blog_id, placement_category_id, placement_entry_id, placement_is_primary)
VALUES (4,2,2,4,1);

(ついでにテーブル名のダブルクオートも排除。なお複数行でなくても一行でOK。)

全ての INSERT 文において、対応するテーブルの CREATE TABLE 文で示されているカラム順に従った形で INSERT 文を書き換えていきます。

INSERT 文のすべてを書き換え終わった後に、CREATE TABLE 文をすべて削除します。
 


4. MySQL へデータを投入

編集後のファイルを MySQL へ投入します。
例えば MySQL のデータベース「my_database」に対して投入する状況において、3. のセクションで sqlite.dump.sql ファイルを編集後 mysql.import.sql として保存したのであれば、以下のようなコマンドを実行します。

$ mysql my_database < mysql.import.sql

必要に応じて -u, -p などのオプションをつけて、SQL が正しく実行できるようにしましょう。
またエラーが発生した場合は原因を良く確かめて import ファイルを編集し、truncate でもう一度リセットした上で再投入しましょう。


5. Movable Type 管理へアクセス

投入後再び Web で MT 管理ページへアクセスします。SQLite 環境で稼動していたものと同じものが参照、利用できるはずです。

Movable Type を4系にえいやっと更新してみました。

メジャーなバージョンアップなので以前からのサイトデザインも捨てる勢いでテンプレート関連情報も一斉初期化してみました。なんだかカスタムテンプレート扱いでなかなか初期化できずに困りましたが。
テンプレート情報を全て消去して「システムメニュー」の「ブログ一覧」から「テンプレートの初期化」で何とかデフォルトテンプレートが適応されたものの、エントリ毎のアーカイブファイルなどの出力設定が空っぽの状態だったので、その部分だけは最終的に手動設定にて対応。過去のエントリのアーカイブへリンクを貼っている方なども多数おられるので、その部分は同じファイル名となるように。

ともかくテンプレートまわりが偉い変わっててビックリ。「モジュールテンプレート」として細かいパーツがひたすら外出しされているのが標準的に利用されてます。
まだ全部読んでないですが、MTSetVar / MTGetVar をトップ(レイアウト部に該当するテンプレート)で利用して変数値設定、その内容に応じてモジュールテンプレートの利用可否を決定しているといった感じで、より玄人向けな内容になってます。プログラムをやってる人ならばすぐ理解できますし面白い機構なのですが、なかなか大変だなあ。

ひとまず StyleCatcher で見た目の変更ということで、躊躇なく三沢のタイツでいくことにしました。

Comment Spam も Trackback Ping Spam も。
今でこそ制限をかけているので表に出ることがほとんどなくなったものの、MT のログをみるとえらいことになってる。特に Ping Spam がひどい。

しかし、ここまで凄まじい勢いで吐き出していつつもほとんどの blog で filtering されていて、果たして効果の出ている広告媒体なのだろうか。そっちのほうも気になる。

以前から小生ブログへ律儀へコメントを残して行かれていた online poker さんが今度はトラックバックで spam フィーバー!WOW!

ということで時間が勿体無いのでさくっと導入できる mt-spamstop-tb でちょこっと対策を取ってみたのでしばし様子を見てみよう。

【重要】 Movable Typeの脆弱性と対策について

各地で凄い数の同エントリが上がっていることと思いますが。今までリリースされていた Movable Type に脆弱性が発見された模様です。上記リンクにて現行バージョンに適応できるプラグインパッチ、また対策を行ったバージョン 3.122 がリリースされています。メールによるコメント通知機能を有効にしていた場合に踏み台にされるようですが、念のため塞いでおきましょう。

以下余談。今回のパッチ適応個所が自分でカスタマイズしている個所と見事に合致してしまっていたのでさらに書き換えて適応したのですが、直接本体該当個所のソースをいじらずにこういう方法でパッチ適応できたのですね。思いがけぬ収穫。今後の Ver.UP のときにこの手法を使うことにしよう。

んで出来た。まともに動作させようとしたら思ったより太ったコードになってしまいましたね。動作は至ってサクサクですが。

ステップは前回のエントリで上げたとおり、
 1. iTunes 情報取得
 2. Amazon アフィリエイトリンク作成
 3. java script ファイルへ出力
 4. FTP で java script を Upload
です。active perl で実装。

さて実際に自分で目的の機能を果たそうと試していたところ1つの事実が発覚したのであります。Amazon ってば、中途半端に日本盤のアルバムタイトルをカタカナ表記にしちゃってるのね…そりゃ一部アルバム引っかからないわけだわ。
まあリンク精度よりもジャケット写真のほうが個人的には重きに置きたいところなので、リンク生成する際国内の amazon.co.jp の商品に向けて生成するものの、もしその CD のジャケット写真がなかった場合は amazon.com の方も検索をかけて画像リンクのみ引っ張ってくるという流れを作ってみました。洋盤ならではの作戦なり。

以下ソース。

このブログのサイドバーに iTunes で演奏中のトラックを音ログ.jp を用いて表示させていますが、聴いている HM/HR に対してのリンク精度がお世辞にも良いとは言えません。Amazon アフィリエイトも海外盤へのリンクになるし、amazon.co.jp の海外盤ジャケットイメージがブランクとなっているため嬉しさが半減なんですね。
Music でもやっぱりマイナー分野に該当する以上仕方がない話です。ちゅーことでこりゃもう自前でやるしかないなと思ったわけです。そのついでに自分のアフィリエイトにしてアサマシもやっちゃいましょう。

perl にて iTunes の情報を COM を利用し取得、その情報を元に Net::Amazon を使ってアフィリエイトリンクを作成。これを java script ファイルを作成した後、Net::FTP を使って Upload。よしこれだ。現在のトラック以外に過去5件分くらいのアルバムもリストすることにしよう。

んで cygwin perl でやろうとしたら perl はおろか cygwin の version が古くて Ver.UP。これがどうにも終わらなくって、先にエントリーが先行してしまったというオチです。

さらに、cygwin で Win32 パッケージが見事導入失敗に終わったので、おとなしく Active Perl でやることにしよう…うわー何となくこうなることは分かってたけど凄いションボリだ。寝る前にガリガリ検証しようと思ったけどもういいや。

このアーカイブについて

このページには、過去に書かれたブログ記事のうちBlogカテゴリに属しているものが含まれています。

前のカテゴリはAudio/Videoです。

次のカテゴリはBookです。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

Powered by Movable Type 4.01