MySQL 5.1.50リリース

すでにMySQL 5.1.51がリリースされていますが、最近のバージョンについて順番に確認していきたいと思います。
MySQL 5.1.50では24件のバグ修正が行われており、そのうちレプリケーションに関するものが1件、パーティショニングに関するものが2件となっています。InnoDB Pluginは順調にバージョンが上がって、1.0.11になりました。
今回はバイナリログまわりでImportant Changeが出ているので、内容をおさえておきましょう。

  • LOAD DATA INFILE文は、ステートメントベースのバイナリログにおいて安全でないと見なされるようになりました。ステートメントベースのバイナリログを使用している際にLOAD DATA INFILE文を実行すると、今後は警告が出力されるようになります。ミックスフォーマットを使用している場合は、LOAD DATA INFILE文を実行すると行ベースのバイナリログが生成されるようになりました。(Bug#34283)

レプリケーション環境でLOAD DATA INFILE文を使ってはいけないなんて知らなかった…と考えるのは早計で、レプリケーション環境でLOAD DATA INFILE文を使うことには問題ありません。今回問題とされたのは、mysqlbinlogコマンドによるデータベースのリカバリ処理です。
LOAD DATA INFILE文を含むバイナリログをmysqlbinlogにかけると、以下のようなSQLが復元されます。

# at 1110
#100928  0:23:51 server id 1  end_log_pos 1828
#Begin_load_query: file_id: 1  block_len: 695
# at 1828
#100928  0:23:51 server id 1  end_log_pos 2118  Execute_load_query      thread_id=5     exec_time=0     error_code=0
SET TIMESTAMP=1285601031/*!*/;
LOAD DATA LOCAL INFILE '/tmp/SQL_LOAD_MB-1-0' INTO TABLE `emp` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`empno`, `ename`, `job`, `mgr`, `hiredate`, `sal`, `comm`, `deptno`)
/*!*/;
# file_id: 1

LOAD DATA INFILE文がLOAD DATA LOCAL INFILE文として復元される点も興味深いですが、ポイントは読み込むファイルが /tmp/SQL_LOAD_MB-1-0 と具体的に指定されているところです。実はこのファイルは、mysqlbinlogによってたった今作られたものなのです。
mysqlbinlogはバイナリログにLOAD DATA INFILE文を見つけると、

  1. その場で一時ファイルを作成し、
  2. 一時ファイルをロードするLOAD DATA LOCAL INFILE文を出力

します。そして今回問題とされたのは、この一時ファイルを自動で消す手段がないというところです。そのためこれらの一時ファイルが、知らず知らずの間にディスクの空き容量を圧迫している恐れがあります。
一時ファイルを自動で消すように修正するのはなかなか難しいです。まずmysqlbinlogによって出力されたSQLスクリプトはすぐに実行されるとは限りませんから、mysqlbinlogプロセスがファイルを削除するチャンスはありません。一方、出力されたSQLスクリプトに「system rm /tmp/SQL_LOAD_MB-1-0」といったファイル削除コマンドを埋め込むと、そのSQLスクリプトは一度しか実行できなくなってしまいます。この問題が最初に報告されたのは2003年なのですが(Bug#1073)、これまで長い間修正されることはありませんでした。
MySQL 5.1からは、binlog_format = rowを利用することでこの問題を回避できるようになりました。行ベースのバイナリログを用いると、LOAD DATA INFILE文による更新データは以下のように直接SQLスクリプト内に埋め込まれる形となり、一時ファイルは作成されなくなります。そしてMySQL 5.1.50からはbinlog_format = mixedのときも行ベースのバイナリログが生成されるようになり、binlog_format = statementのときは警告が出力されるようになりました。

# at 417
#100928  1:48:47 server id 1  end_log_pos 417   Table_map: `scott`.`emp` mapped to number 17
#100928  1:48:47 server id 1  end_log_pos 836   Write_rows: table id 17 flags: STMT_END_F

BINLOG '
78qgTBMBAAAAQAAAAKEBAAAAABEAAAAAAAEABXNjb3R0AANlbXAACPYPD/YK9vb2DgQAHgAbAAQA
BwIHAgIA/g==
78qgTBcBAAAAowEAAEQDAAAAABEAAAAAAAEACP9AnMkFc21pdGgFY2xlcmue3pF5D4ADIACUAJ1L
BWFsbGVuCHNhbGVzbWFunhJUeg+ABkAAgAEsAJ4AnWEEd2FyZAhzYWxlc21hbp4SVnoPgATiAIAB
9ACeQJ2OBWpvbmVzB21hbmFnZXKen4J6D4ALnwCUAJ3mBm1hcnRpbghzYWxlc21hbp4SPHsPgATi
AIAFeACeQJ4SBWJsYWtlB21hbmFnZXKen6F6D4ALIgCeQJ5mBWNsYXJrB21hbmFnZXKen8l6D4AJ
kgCKQJ5sBXNjb3R0B2FuYWx5c3SdjpOGD4ALuACUSJ6fBGtpbmcJcHJlc2lkZW50cXsPgBOIAIoA
nqQGdHVybmVyCHNhbGVzbWFunhIoew+ABdwAgAAAAJ5AnsQFYWRhbXMFY2xlcmuebLeGD4AETACU
QJ7cBWphbWVzBWNsZXJrnhKDew+AA7YAnkCe3gRmb3JkB2FuYWx5c3SdjoN7D4ALuACUQJ7+Bm1p
bGxlcgVjbGVya55mN3wPgAUUAIo=
'/*!*/;

心当たりのある方は、 /tmp などに一時ファイルが残っていないか確認してみてください。