きぬろぐ


cactiのバージョンアップができない件について

投稿者: kinusati, カテゴリー: freebsd

ノードごとのリソースグラフを管理するため、cactiを0.8.7b から 0.8.7eにバージョンアップしようとしたのですが、以下のエラーが出ます。

Invalid Cacti version 0.8.7b      , cannot upgrade to 0.8.7e

なんでだろうと調べてみたら、結論から言うと、my.cnfにdefault-character-set = binaryの設定を登録していたことが原因だった。では何故こうなるのか?を以下にまとめます。

原因詳細

上記エラーを出す部分のソースコードですが、cacti0.8.7eのバージョンアップ画面で利用されるinstall/index.phpの364-369行目が該当します。

    364         if (!is_int($old_version_index)) {
    365                 print " <p style='font-family: Verdana, Arial; font-size: 16px; font-weight: bold; color: red;'>
Error</p>
    366                         <p style='font-family: Verdana, Arial; font-size: 12px;'>Invalid Cacti version
    367                         <strong>$old_cacti_version</strong>, cannot upgrade to <strong>" . $config["cacti_versio
n"] . "
    368                         </strong></p>";
    369                 exit;
    370         }

364行目で$old_version_index変数の条件判定が失敗するため、エラーになることがわかります。

この$old_version_index変数の中身はmysqlのversionテーブルから取得したもので、mysqlからバージョンアップ前のバージョン情報を取得することで、バージョンアップ可能かどうかを判定しています。

データベースのcharacter-setがutf8の場合

データベースのcharacter-set=utf8だと正常にバージョンアップできます。試しにmysqlに対してversionテーブルが持つ値を検索してみたところ、以下応答となります。versionテーブルのcactiカラムはchar(20)であり、取得できるバージョンも”0.8.7b”となります。

mysql> desc version;
+-------+----------+------+-----+---------+-------+
| Field | Type     | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| cacti | char(20) | YES  |     | NULL    |       |
+-------+----------+------+-----+---------+-------+
1 row in set (0.00 sec)

mysql> select * from version;
+--------+
| cacti  |
+--------+
| 0.8.7b |
+--------+
1 row in set (0.00 sec)

データベースのcharacter-setがbinaryの場合

character-setがbinaryだと以下のようにversionテーブルのcactiカラムがbinary(20)!!!となり、応答結果は”0.8.7b______________”‘(表示都合上、NULL文字を”_”で表現)”となります。cactiの初期データ作成に用いるcacti.sqlではCHAR(20)を指定しているのに・・・binary型に変換されるようですね。

mysql> desc version;
+-------+------------+------+-----+---------+-------+
| Field | Type       | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| cacti | binary(20) | YES  |     | NULL    |       |
+-------+------------+------+-----+---------+-------+
1 row in set (0.00 sec)

mysql> select * from version;
+----------------------+
| cacti                |
+----------------------+
| 0.8.7b               |
+----------------------+
1 row in set (0.00 sec)

この場合、上述の$old_version_index変数にはバージョン情報 + NULL情報を含んだ値が返されるため、エラーになる・・ということがことの真相のようです。

データベースのキャラクタセットにbainaryを使う際は注意が必要ということか。

言い訳ですが、今回cactiに利用しているデータベースは昔MySQL 4.0系を利用していた物を流用しました。流用の中で、セキュリティ対策を考慮して4.0系から5.1系までバージョンアップさせた物を使っています。

有名な話ですが、4.0系から5.0系以上にバージョンアップすることは大変な苦労を伴います。理由はMySQLの4.1系で文字コード自動変換が実装された事が原因であり、そのままバージョンアップすると、文字化けすると既存データ破損が大量に発生するため、苦肉の策としてcharacter-setをbinaryにした上でバージョンアップ作業を行っていました。

でもまさかこんなところで落とし穴があるとは・・・・。

下手なことはやらないものですね。以後気をつけます。

コメント(1)

  1. 楽神

    ちょうどバージョンアップしようとググッてました。
    助かりました。
    参考にさせてもらいます♪(●´_ゝ`)y~~~~

コメントする

フリースペース

バナーやブログパーツなどを貼って、ご自由にお使いください。