LargeObjectが大量すぎでvacuumdb –full ができなかった時の対処法

5月 27th, 2011

こんにちは、なかわけです。

珍しくPostgresの話です。
管理しているとあるデータベースで、LargeObjectが大量に保存されてました。大量すぎて大変になってきたので、一部のLO管理を止めてファイル管理にするように移行しました。移行後に削除したLO分の容量を解放すべくフルバキュームを行ったのですが、強制終了やほかのプロセスにより中断されましたという謎のエラーでフルバキュームが完了しませんでした。
(さらに…)

Cactiを0.8.7gにアップデートしたのですが

2月 22nd, 2011

こんにちは、なかわけです。

仕事で使っているCactiを0.8.7fから0.8.7gにアップデートしました。
Tholdというメール通知のプラグインをインストールしようと思ったら0.8.7fのパッチとPlugin Architectureがなかったのでついでにアップデートもしてしまおうという流れで。インストール・アップデートの手順は以下のサイトを参考にしました。ありがとうございました。

ウノウラボ
Linux/CentOS5/cacti-0.8.7cから0.8.7dへ移行
サーバー監視システム構築(RRDtool+Cacti)

手順通りしたのですが、 (さらに…)

EC-CUBE 詳細サブ画像を増やす方法

12月 14th, 2010

こんにちは、なかわけです。

EC-CUBEの詳細ページ/管理ページの詳細サブ画像を増やす方法です。
サイズ違いの画像を追加したい時などに使います。
基本的に過去の記事「EC-CUBE商品の登録項目内容の追加」を参考に作業を行います。
ただ、追加している項目が違いますので作業が必要ないステップもあります。確認しながら必要に応じで行ってください。また詳細サブ画像は1~5まであるので、それに合わせてDBテーブルにカラムをsub_hoge_image1 ~ sub_hoge_image5 のように追加しなくてはいけません。
(さらに…)

EC-CUBE 商品詳細ページのテンプレートファイルの場所

12月 13th, 2010

こんにちは、なかわけです。

EC-CUBEの商品詳細ページのテンプレートファイルの保存先がわかりにくかったのでメモです。

(public_htmlとか人によって違う)/user_data/packages/TEMPLATE_NAME/detail.tpl

TEMPLATE_NAMEはdefaultだったり自分でテンプレートを作った場合のディレクトリ名です。
これ探すのにかなり時間かかりました・・・。

しかし、自分でテンプレート作っても管理ページのテンプレートは、
(public_htmlとか人によって違う)/user_data/Smarty/templates/default/admin/
に以下にあるのが解せないんだよな~。

EclipseのSVNでJava heap spaceを回避するヒント

11月 8th, 2010

こんにちは、なかわけです。
めちゃ久しぶりです。

今日Eclipseのプロジェクトがぶっ壊れました。
原因は分かりません。

アップデートもコミットもできなくなって、しょうがないので新規でプロジェクトを追加したところ、
いつものJava heap spaceでした;_;

チェックアウト中のプロジェクトにファイルが作られていく様を観察していたのですが、
どうやらディレクトリ単位にチェックアウトしているようです。
つまり、チェックアウト中のディレクトリに10ファイルあれば10ファイルメモリに入れてから
ローカルにファイルを生成する、という具合。

たとえば、ひとつのディレクトリに画像が100ファイルあったとすると、
100ファイルをメモリに入れてローカルにファイルを生成・・・できなくてjava heap space!
こんな感じです、たぶん。

試しに100ファイルあるディレクトリをSVNリポジトリ・エクスプローラで
直接接続してディレクトリを作って小分けにしてみました。
はい、できました;_;

要するにひとつのディレクトリにたくさんファイルを置かないということですね。
計画的にディレクトリを作りましょう!!
あ、もちろん、容量の重いファイルもJava heap spaceの原因になるので注意です。

Postgresで大量のラージオブジェクトデータをコピーする

8月 12th, 2010

こんにちは、なかわけです。

いまpostgresのlargeobjectを大量にコピーする作業をしています。
元のデータベースに3000万行くらいあってそれをまるっとそっくりコピーのデータベースに流し込みます。

INSERT INTO pg_largeobject
       SELECT *
         FROM dblink('dbname=元データベース', SELECT * FROM pg_largeobject')
           AS t1 (loid oid, pageno integer, data bytea);

最初一回でコピーしようとしたらメモリエラーで失敗しました。そりゃそうですよねw

それで3000万行を10万行ずつに分割して書いたクエリのテキストファイルを読み込ませて
データを流し込むことにしました。たとえば、以下はその中のひとつのクエリ。

INSERT INTO pg_largeobject
       SELECT *
         FROM dblink(
                  'dbname=元データベース',
                  'SELECT * FROM pg_largeobject ORDER BY loid, pageno LIMIT 100000 OFFSET 200000')
           AS t1(loid oid,pageno integer,data bytea);

始めの方は10万行を挿入するのに1、2分程度で処理されていましたが、だんだん処理が遅くなり、
1000万行を挿入し終わったあたりでは10万行挿入するのに15分程度かかるようになってしまいました。

時間がかかってしょうがないです。どうしたものか。

ところが、とあるところからいい方法を教えてもらいました。

INSERT INTO pg_largeobject
           SELECT *
           FROM dblink(
                   'dbname=元データベース',
                   'SELECT * FROM pg_largeobject WHERE loid BETWEEN n AND m')
           AS t1(loid oid,pageno integer,data bytea);

ORDERしてLIMIT、OFFSETするのではなく、BETWEENを使うんですね!
確かにこっちの方が処理が少ない分早そうだし、実際めちゃ早かったです。
あーよかったよかった!

Linux、Postgresで最近学んだこと

8月 8th, 2010

こんにちは、なかわけです。

ここ1週間エンジニアリグな作業ばかりしていましたが、
LinuxとPostgresで学んだことを箇条書き。誰得記事です。

  1. CPUの使用率が90%を超えるとパフォーマンスが極端に落ちる
  2. メモリの使用率が90%を超えるとパフォーマンスが落ちる
  3. データ容量が90%を超えるとパフォーマンスが落ちる
  4. わからないコトはいろんな記事を比較して調べる
  5. 必ずバックアップを取ってからファイルを削除する
  6. ラージオブジェクトを使う場合はそのときのリスクを考える
  7. pg_dumpは不正データもdumpする可能性がある
  8. ラージオブジェクトを含むdumpデータはrestoreに時間がかかる

この1週間かなり勉強になったがもう二度とやりたくない。

mkdir()したときのPermission deniedを回避

6月 8th, 2010

こんにちは、なかわけです。

自分的な作業メモです。
対象のディレクトリのパーミッションは合っているのに
mkdir()したときのPermission deniedのエラーが出ました。
いろいろいろいろ調べてやっと解決しましたが、何が原因だったのかわかりません。
ひょっとしたら私の認識が間違っているかもしれません(ただの勘違い?)。
詳しい人コメントください。

もともとのコードは以下のようなものでした
はじめにimagesディレクトリは存在していて、mkdir()でchocolateディレクトリを作るという設定です。
まず、Hogeクラスにmkdir()の処理が書いてあります。

class Hoge{
    public function __construct(){
        //コンストラクト的な処理
    }
    public function makeDir(){
        mkdir('images/chocolate', 0755, true);
    }
}

それで、Permission deniedのエラーが発生したときのコードFugaクラス

require_once 'Hoge.php'
class Fuga {
    public function __construct(){
        //コンストラクト的な処理
    }
    public function piyo(){
        $hoge = new Hoge();
        $hoge->makeDir();
    }
}

これだとPermission deniedのエラーがでてしまいましたが、
上記のFugaクラスを以下のように変更したら、エラーが無くなりました

require_once 'Hoge.php'
class Fuga {
    protected $hoge;
    public function __construct(){
        //コンストラクト的な処理
        $hoge = new Hoge();
    }
    public function piyo(){
        $this->hoge->makeDir();
    }
}

もともとimagesディレクトリの所有者はApacheだったんだけど、
メソッド内でHogeをnewするとmkdir()したときのディレクトリの所有者がApacheじゃなくなるのかなぁ
とか思ったんですが、じつは書き直す前のコードでもちゃんと動いている時期があって
phpのバージョンが上がったからなのかなんなのか・・・。
今度同じような問題にぶつかったときに詳しく調べようと思います。
ちょっと今日はもう時間がないので解決したというメモだけで・・・。

jQueryの.load()がブラウザによって挙動がまちまち

5月 28th, 2010

こんにちは、なかわけです。

jQueryの.load()の挙動がブラウザによってまちまちです。
実際、どんな感じか。

index.html

<html>
<body>
<div>
    <a href="hoge.html">hoge</a>
    <a href="fuga.html">fuga</a>
    <a href="piyo.html">piyo</a>
</div>
</body>
</html>

deploy.html

<html>
<hed>
<script src="jquery.js"></script>
<script>
$(function(){
    $('div').load('index.html div a', function(){
        alert('ヾ(*´∀`*)ノロードできた~');
    });
});
</script>
</head>
<body>
<div></div>
</body>
</html>

で、主なブラウザ挙動は以下のような感じ。
Firefox
hoge、fuga、piyoのリンクが出力されて、アラートが2回

Chrome
なにも出力されずに、アラートが1回

Safari
hoge、fuga、piyoのリンクが出力されて、アラートが1回

この結果からみるとSafariの挙動が正しいっぽいけど、
なんでこうもまちまちなのかね~。
jQueryには珍しくブラウザ間の差が吸収されていないのでしょうか。
詳しい方、コメントくださいな!(いつもすいません・・・。)

ロード直後にラジオボタンを選択するjs(jQuery)

5月 27th, 2010

こんにちは、なかわけです。

タイトルのことをしようとすると以下のようなコードになると思います。

HTML

<input type="radio" name="sweets" value="1"/> チョコレート
<input type="radio" name="sweets" value="2"/> チョコラーテ
<input type="radio" name="sweets" value="3"/> ショコラ

Java Script

$(function(){
    //ラジオボタンにchangeイベントを結びつける
    $('input').change(function(){
        console.log('Buono!');
    });
    //ラジオボタンのひとつ目をクリック    
    $('input:first').click();
});

このままでもラジオボタンのひとつ目は選択されますが、
Buono!は出力されません。

これを以下のように変更するとBuono!も出力されてラジオボタンのひとつ目も選択されます。

Java Script

$(function(){
    //ラジオボタンにchangeイベントを結びつける
    $('input').change(function(){
        console.log('Buono!');
    });
    //ラジオボタンのひとつ目をクリック :ここを変更!   
    $('input').get(0).click();
});

はい、これで期待した挙動にはなりましたが、なぜでしょう?
なぜなぜ?
:firstとget(0)の挙動の違いなんでしょうけど、私にはわかりません・・・。
理由がわかる方コメントいただけると助かります。