MySQL 5.1.43リリース

出ました。今回は機能追加が1件、バグ修正が47件あります。バグ修正のうち1件はセキュリティに関するもの、それからパーティショニングに関するものが2件、レプリケーションに関するものが7件となっています。InnoDB PluginはMySQL 5.1.42に引き続きRC版の1.0.6となっています。
今回は注意すべき変更点がいくつかありますので、かいつまんで説明します。

パーティショニングに関する機能追加

パーティショニング機能に関して一つ機能追加があり、UNIX_TIMESTAMP()をパーティショニング表現として利用できるようになりました。先日のMySQL 5.5.0-m2の記事における例を書き直すと以下のようになります。

mysql> CREATE TABLE timeline (
    ->   id BIGINT(20) NOT NULL,
    ->   created_at DATETIME DEFAULT NULL,
    ->   screen_name VARCHAR(15) DEFAULT NULL,
    ->   text VARCHAR(140) DEFAULT NULL,
    ->   PRIMARY KEY (id, created_at)
    -> )
    -> ENGINE = InnoDB
    -> PARTITION BY RANGE (TO_DAYS(created_at)) (
    ->   PARTITION p2009 VALUES LESS THAN (UNIX_TIMESTAMP('2010-01-01')),
    ->   PARTITION p2010 VALUES LESS THAN (UNIX_TIMESTAMP('2011-01-01')),
    ->   PARTITION p2011 VALUES LESS THAN (UNIX_TIMESTAMP('2012-01-01')),
    ->   PARTITION plast VALUES LESS THAN MAXVALUE
    -> );
Query OK, 0 rows affected (0.06 sec)

mysql> SHOW CREATE TABLE timeline\G
*************************** 1. row ***************************
       Table: timeline
Create Table: CREATE TABLE `timeline` (
  `id` bigint(20) NOT NULL,
  `created_at` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  `screen_name` varchar(15) DEFAULT NULL,
  `text` varchar(140) DEFAULT NULL,
  PRIMARY KEY (`id`,`created_at`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
/*!50100 PARTITION BY RANGE (TO_DAYS(created_at))
(PARTITION p2009 VALUES LESS THAN (1262271600) ENGINE = InnoDB,
 PARTITION p2010 VALUES LESS THAN (1293807600) ENGINE = InnoDB,
 PARTITION p2011 VALUES LESS THAN (1325343600) ENGINE = InnoDB,
 PARTITION plast VALUES LESS THAN MAXVALUE ENGINE = InnoDB) */
1 row in set (0.00 sec)

MySQL 5.1.42までは以下のようなエラーが返されます。

ERROR 1564 (HY000): This partition function is not allowed

以前、MySQL 5.5ではRANGE COLUMNSパーティショニングによって1日よりも細かい単位でパーティションを作ったり、パーティションの区切りを0時0分以外にできると述べました。MySQL 5.1.43の機能追加によりその優位性は少し薄れてしまった形です。

セキュリティ修正

MySQL組み込みのSSL接続機能について脆弱性が報告されています。組み込みのSSL機能を有効にしている場合、ネットワーク経由の攻撃によってバッファオーバーフローが発生する恐れがあります。組み込みのSSL機能を有効にしているかどうかは、以下のコマンドで「have_ssl」の設定を見ることで確認できます。

mysql> show global variables like '%ssl%';
+---------------+----------+
| Variable_name | Value    |
+---------------+----------+
| have_openssl  | DISABLED |
| have_ssl      | DISABLED |
| ssl_ca        |          |
| ssl_capath    |          |
| ssl_cert      |          |
| ssl_cipher    |          |
| ssl_key       |          |
+---------------+----------+
7 rows in set (0.00 sec)

have_sslがDISABLEDになっている場合は、危険性はありません。

RAND()がステートメントベースレプリケーションにおいて安全でなくなった

ステートメントベースのレプリケーションにおいて、RAND()ファンクションが安全ではないと見なされるようになりました。
RAND()ファンクションを含むDMLレプリケーションする場合、MySQLは以下のように乱数のSEEDをスレーブに送ることでマスタ/スレーブ間の整合性を確保していました。

#100202 10:50:37 server id 1  end_log_pos 300   Rand
SET @@RAND_SEED1=579603802, @@RAND_SEED2=401006069/*!*/;
# at 300
#100202 10:50:37 server id 1  end_log_pos 407   Query   thread_id=1     exec_tim
e=0     error_code=0
SET TIMESTAMP=1265075437/*!*/;
INSERT INTO test (c1) VALUES (RAND() * 100)

従来はこれでうまく動くとされていたのですが、実はINSERT ... SELECTのような複数レコードを更新する処理ではレコードの更新順序が保証されません。そのため乱数の値が不一致を起こす場合があるということが分かりました。
今後レプリケーション環境でRAND()ファンクションを利用する場合は、行ベースレプリケーションを利用してください。またRAND()ファンクションに限らず、行ベースレプリケーションへの移行は今後検討すべき課題の一つと考えられます。InnoDBトランザクション分離レベルがREAD COMMITTEDの場合は、ネクストキーロックを軽減できるというメリットもあります。