-->

2013-10-15

memo: audit

$ sudo emerge --oneshot -avt sys-process/audit

$ sudo auditctl -l
Error - audit support not in kernel
Cannot open netlink audit socket

$ diff /etc/kernels/kernel-config-x86_64-3.4.6{3,6}-gentoo
3c3
< # Linux/x86 3.4.63-gentoo Kernel Configuration
---
> # Linux/x86 3.4.66-gentoo Kernel Configuration
95c95,99
< # CONFIG_AUDIT is not set
---
> CONFIG_AUDIT=y
> CONFIG_AUDITSYSCALL=y
> CONFIG_AUDIT_WATCH=y
> CONFIG_AUDIT_TREE=y
> CONFIG_AUDIT_LOGINUID_IMMUTABLE=y

$ sudo auditctl -l
No rules

$ sudo auditctl -w /mnt/hgfs/share/

$ cd /mnt/hgfs/share/

$ sudo tail -n0 -f /var/log/audit/audit.log

$ ll 1.txt

$ sudo tail -n0 -f /var/log/audit/audit.log
type=SYSCALL msg=audit(1381841035.653:30): arch=c000003e syscall=191 success=no exit=-95 a0=7fffff313e35 a1=7f585a90627f a2=0 a3=0 items=1 ppid=10513 pid=10662 auid=1000 uid=1000 gid=1000 euid=1000 suid=1000 fsuid=1000 egid=1000 sgid=1000 fsgid=1000 tty=pts0 ses=5 comm="ls" exe="/bin/ls" key=(null)
type=CWD msg=audit(1381841035.653:30):  cwd="/mnt/hgfs/share"
type=PATH msg=audit(1381841035.653:30): item=0 name="1.txt" inode=30962247438286374 dev=00:15 mode=0100777 ouid=1000 ogid=1000 rdev=00:00

2013-09-19

memo: K760E, LBT-UAN04C2BK

K760E, LBT-UAN04C2BK

windows7でも使用可能らしいので買った。

コントロール パネル\すべてのコントロール パネル項目\デバイスとプリンター
ではペアリングできなかった。

コンピューター\マイBluetoothデバイス
でできた。(Bluetooth USBアダプタのCD付属)

「F10」が「fn-F10」で反応がある。
「ctl-alt-delete」が「fn-ctl-alt-delete」で反応がある。(印字はdeleteで機能はbackspaceでdeleteにする場合が「fn+delete」)
google画像検索、検索ツール、大きいサイズでも見た目は見れる。


http://masaru.org/diary/20110412.html

http://qa.green-house.co.jp/faq_detail.html?id=1117

LBT-UAN04C2BKのCDのソフトウェアを入れた。
csr harmony wireless software stack

ディスカバリーモード : ディスカバリーOFF
SCMT-T               : 有効
デバイスの種類       : PC/デスクトップPC

キーボードが109っぽいが印字と違うのでusにしたいが「地域と言語」から設定するUSだと日本語変換ができない。
参考サイトを元に値を変更した。
HKEY_LOCALMACHINE\SYSTEM\CurrentControlSet\Enum\HID
↓
HID\CSRHIDDevice????????&?????
↓
xxx&0xxx
    KeyboardTypeOverride
xxx&1xxx
    KeyboardTypeOverride
xxx&2xxx
    KeyboardTypeOverride
複数ある場合は番号が多い方のようです。

何回も再インストールしたら増えたので復元で戻したら戻った。
ちょうどいいタイミングのログがあったので。2日前の。
その間に入れたソフトウェアはおかしくなったので入れなおした。

無事「shift-2」で「@」が出たので成功した。

http://www.logicool.co.jp/ja-jp/product/wireless-solar-keyboard-k760-for-mac
仕様
型番 K760E
キーレイアウト : 78キー英語レイアウト

コントロール パネル\すべてのコントロール パネル項目
に表示方法:小さいアイコンで
Bluetooth Devices
Bluetooth 設定
という表示が出て「Bluetooth 設定」のほうは押しても反応がない。
なにか間違ったかと思って再インストールして消えたかと思ったが再起動後に出るので、そのままにした。
「表示方法:カテゴリ」の場合はそうでもない。

F1~F12を多用する場合はやめたほうが良さそう。
しかし太陽電池は良さそう。壊れなければ。

2013-09-16

memo: VMware Player, Microsoft Loopback Adapter

http://www.anseilen.org/puki/index.php?%CC%B5%C0%FELAN%A1%DCVPN%B4%C4%B6%AD%A4%C7%A1%A2%B2%BE%C1%DBPC%A4%F2%BB%C8%A4%A6

http://blogs.yahoo.co.jp/akio_myau/39554285.html

http://d.hatena.ne.jp/uesama99/20070211/1171159451

https://twitter.com/yyamasak/statuses/289623414795296768

http://d.hatena.ne.jp/kakenman/20110314/1300084623

http://trendy.nikkeibp.co.jp/article/tec/bb/20020826/101625/


これはNAT接続がうまくいかないがブリッジ接続でIPアドレスを割り当てたくない場合に試すかもしれないので確認した作業の例です。

スタート、コンピューター、右クリック、管理、
コンピューターの管理、デバイスマネージャ、ネットワークアダプタ、
操作(A)、レガシーハードウェアの追加(L)、
...

コントロール パネル\すべてのコントロール パネル項目\ネットワーク接続

ローカルエリア接続2
認識されていないネットワーク
Microsoft Loopback Adapter

右クリック、プロパティ、インターネットプロトコルバージョン4(TCP/IPv4)、
プロパティ、次のIPアドレスを使う、

IPアドレス(I):       192.168.137.1
サブネットマスク(U): 255.255.255.0

OK、ローカルエリア接続、右クリック、プロパティ、共有、

インターネット接続の共有
[v]ネットワークのほかのユーザーに、このコンピュータのインターネット接続を通しての接続を許可する(N)
ホームネットワーク接続(H):
[ローカルエリア接続2]
[ ]ネットワークのほかのユーザーに、共有インターネット接続の制御や無効化を許可する(O)

OK、

VmwarePlayer
仮想マシン設定の編集(D)
ネットワークアダプタ ブリッジ(自動)
(●)ブリッジ: 物理ネットワークに直接接続(B)
    [ ]物理ネットワーク接続の状態を複製(P)
                           アダプタの設定(F)

ブリッジの自動設定
自動的にブリッジするホストネットワークアダプタを選択してください:
[v] Microsot Loopback Adapter
[ ] Realtek RTL8168D/8111D...

$ cat /etc/sysconfig/network-scripts/ifcfg-eth0 | grep -v ^# | grep -v ^$
DEVICE="eth0"
BOOTPROTO="static"
NM_CONTROLLED="no"
ONBOOT="yes"
TYPE="Ethernet"
IPADDR="192.168.137.220"
GATEWAY=192.168.137.1
NETMASK="255.255.255.0"
DNS1="192.168.0.1"

元々動いていた他のvmwareplayerのブリッジ接続のSSH接続が切れた。
アダプタの設定(F)
で、Microsot Loopback Adapterを外せばOK.
共存させる意味はないが。物理的な環境によって使い分け的な何かがあるかもしれない。
今度はMicrosot Loopback Adapterのほうが接続切れたので共存できないようだ。
ローカルエリア接続2を使うほうのVmwareの設定が変わっていた。
[ ] Microsot Loopback Adapter
[v] Realtek RTL8168D/8111D...
何か設定が衝突したので片方を衝突しないようにした的な何かがあったかもしれない。
ローカルエリア接続 → ローカルエリア接続2
ローカルエリア接続 → VMware Virtual Ethernet Adapter for VMnet1
が両方は無理なのかもしれない。

他も192.168.137.xxxにすれば普通に共存はできる。
普通のブリッジのように192.168.137.xxxに192.168.0.xxx(ホストOS以外)からはアクセスできない。
192.168.137.xxx → ssh 192.168.0.xxx(ホストOS以外) → ssh 192.168.137.xxx できないのでOK.

NAT接続で大丈夫か、普通のブリッジ接続でIPアドレスを複数使ってよいなどであれば必要ない。
多分、
[ ]物理ネットワーク接続の状態を複製(P)
を、ONにしてゲストをDHCPにすれば、IPアドレスも被らない、といいな、と思う。
これはVPNのCLIENTで接続するとVmwarePlayerのNAT接続にアクセスできない場合などで試してみる場合の参考です。
そもそも本当に問題が解決するかどうかは不明です。

ローカルエリア接続2を使う場合。両方ONだとvmwareplayerが2個以上で両方にブリッジ接続すると何かがまずい。
普通はしないので1個だけにする。"Vmware Bridge Protocol"ONを。別に物理的に複数ある場合は関係ない。
ローカルエリア接続2 → [v] Vmware Bridge Protocol
ローカルエリア接続  → [ ] Vmware Bridge Protocol

ローカルエリア接続、プロパティ、共有、設定にIPフォワーディングの設定のようなものがあるが、この例では変更していない。

2013-09-14

memo: arglist-cont-nonempty

他に影響がある。
;; spl_autoload_register(call_user_func(function() { の次の行を4。他で影響あれば無し。
;; ((arglist-cont-nonempty 1 22) (arglist-cont-nonempty 1 37) (statement-block-intro 1)) で statement-block-intro で4.
(c-set-offset 'arglist-cont-nonempty' 0)

2013-09-08

spl_autoload_registerの例

https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md
http://qiita.com/Hiraku/items/72251c709503e554c280

クラス名 => ファイルパスで1:1で対応していないと非常にわかりにくいので下記の例は非推薦な例です。








spl_autoload_register(function($className)
{
    static $includePathList;
    if (!is_array($includePathList)) {
        $includePathList = explode(PATH_SEPARATOR, get_include_path());
    }
    $includedFileList = get_included_files();
    $successFlag = false;
    do {
        $classNameList = array();
        $errorFlag = false;
        preg_replace_callback(
            "/(" .
            "(?:[A-Z])" .
            "(?:" .
            "(?:[0-9]{0,15})" .
            "(?:[a-z])" .
            "(?:[0-9]{0,15})" .
            "){1,15}" .
            ")|(.)/", function($matches) use(&$classNameList, &$errorFlag) {
                if (!$errorFlag) {
                    switch (true) {
                    case (is_string($matches[1]) && $matches[1] !== ""):
                        $classNameList[] = $matches[1];
                        break;
                    case (is_string($matches[2])):
                        switch (true) {
                        case (in_array($matches[2], array("\\", "_"), true)):
                            break;
                        default:
                            $errorFlag = true;
                        }
                        break;
                    default:
                        trigger_error("\$className parse error.", E_USER_ERROR);
                    }
                }
            }, $className);
        if ($errorFlag) {
            break;
        }
        foreach ($includePathList as $includeDir) {
            $currentDir1 = $includeDir;
            $classNameListTmp = $classNameList;
            foreach ($classNameList as $val1) {
                if (count($classNameListTmp) <= 1) {
                    break;
                }
                $currentDir1 .= DIRECTORY_SEPARATOR . $val1;
                if (!is_dir($currentDir1)) {
                    break;
                }
                array_shift($classNameListTmp);
                $currentDir2 = "";
                foreach ($classNameListTmp as $val2) {
                    $file = $currentDir1 . DIRECTORY_SEPARATOR . $currentDir2 . $val2 . ".php";
                    if (!in_array($file, $includedFileList, true) && is_file($file)) {
                        require($file);
                        if (class_exists($className)) {
                            $successFlag = true;
                            break 3;
                        }
                    }
                    $currentDir2 .= $val2;
                }
            }
        }
    } while (false);
});

問題点。

後でset_include_path(...)が行われても考慮しない。

全部同じディレクトリやファイルの走査になる。
$class = new Foo_Bar_Baz;
$class = new FooBarBaz;
$class = new \Foo\Bar\Baz;

大文字の英字{1} + 小文字の英字{1,15}(半角数字が間にあるのはOK)で"\"と"_"は区切り。
foo_bar_baz は無理。
F111_B222_B333 は無理。
Foo1_Bar2_Baz3 はOK.

"$class = new FooBar;" => "./Foo/Bar.php" のように、"ディレクトリ/ファイル名.php"で最低2つ。

$class = new FooBarBaz;
./Foo/Bar/Baz.phpで定義されている場合、定義されていないが候補に上がるファイルを全部requireする。

./Foo/Bar.php <= 読む。無い。
./Foo/BarBaz.php <= 読む。無い。
./Foo/Bar/Baz.php <= 読む。あった。終わり。

include_path = "1:2:3:4:5:6:7:8:9:." の場合で
./1/Foo/Bar.php などが全部ある場合、30ファイル目をrequireしたところで終了する。
その無駄な29ファイルはrequireしただけでは何も実行部分が無い定義だけのファイルであること、を期待している。

$class = new \Foo\Bar_Baz; のように1つ目がnamespaceであることを期待しているような気もするが強制していない。
多分\Foo\であれば"use xxx as xxx"できっと名前の競合をきっと防げる、のではないか?と思うので。

多分スラッシュとバックスラッシュが見分けにくいフォントがお気に入りの場合、つらい。
ドット、カンマ、コロン、セミコロンが見分けにくいフォントがあるのと、あんまり変わらない問題のようにも感じる。
さすがにスラッシュとバックスラッシュは無いか?見分けにくいフォントを使うのは?色んな場面でかなり不便のはずだし。

(1 + (15 + 1 + 15) * 15) = 466 <= こんな長いクラス名の一部があるかどうかは別にしてマッチする可能性はある。
こういう部分で正規表現を使うのはマナー違反的な何かがある。でかい文字に正規表現処理したらセグメンテーション違反とかね。



探す順番を制御できないがinclude_onceのほうがシンプル。
<?php
spl_autoload_register(function($className)
{
    $successFlag = false;
    do {
        $classNameList = array();
        $errorFlag = false;
        preg_replace_callback(
            "/([A-Z][a-z0-9]{0,9}[a-z][a-z0-9]{0,9})|(.)/",
            function($matches) use(&$classNameList, &$errorFlag) {
                if (!$errorFlag) {
                    switch (true) {
                    case (is_string($matches[1]) && $matches[1] !== ""):
                        $classNameList[] = $matches[1];
                        break;
                    case (is_string($matches[2])):
                        switch (true) {
                        case (in_array($matches[2], array("\\", "_"), true)):
                            break;
                        default:
                            $errorFlag = true;
                        }
                        break;
                    default:
                        trigger_error("\$className parse error.", E_USER_ERROR);
                    }
                }
            }, $className);
        if ($errorFlag) {
            break;
        }
        $currentDir1 = "";
        $classNameListTmp = $classNameList;
        foreach ($classNameList as $val1) {
            $currentDir2 = "";
            foreach ($classNameListTmp as $val2) {
                $file = $currentDir1 . $currentDir2 . $val2 . ".php";
                @include_once($file);
                if (class_exists($className)) {
                    $successFlag = true;
                    break 2;
                }
                $currentDir2 .= $val2;
            }
            $currentDir1 .= $val1 .DIRECTORY_SEPARATOR;
            array_shift($classNameListTmp);
        }
    } while (false);
});

/*
set_include_path("001:002:003");
$class = new \Foo\Bar\Baz;

001/Foo/Bar/Baz.php
001/Foo/BarBaz.php
001/Foo/Bar.php
001/FooBarBaz.php
001/FooBar.php
001/Foo.php
002/Foo/Bar/Baz.php
002/Foo/BarBaz.php
002/Foo/Bar.php
002/FooBarBaz.php
002/FooBar.php
002/Foo.php
003/Foo/Bar/Baz.php
003/Foo/BarBaz.php
003/Foo/Bar.php
003/FooBarBaz.php
003/FooBar.php
003/Foo.php
*/
spl_autoload_register(function($className)
{
    static $includePathList;
    if (!is_array($includePathList)) {
        $includePathList = explode(PATH_SEPARATOR, get_include_path());
        foreach ($includePathList as $key => $dir) {
            if (!is_dir($dir) || !is_readable($dir)) {
                unset($includePathList[$key]);
            }
        }
        $includePathList = array_reverse($includePathList);
    }
    do {
        $classNameList = array();
        $errorFlag = false;
        preg_replace_callback(
            "/([A-Z][a-z0-9]{0,9}[a-z][a-z0-9]{0,9})|(.)/",
            function($matches) use(&$classNameList, &$errorFlag) {
                if (!$errorFlag) {
                    switch (true) {
                    case (is_string($matches[1]) && $matches[1] !== ""):
                        $classNameList[] = $matches[1];
                        break;
                    case (is_string($matches[2])):
                        switch (true) {
                        case (in_array($matches[2], array("\\", "_"), true)):
                            break;
                        default:
                            $errorFlag = true;
                        }
                        break;
                    default:
                        trigger_error("\$className parse error.", E_USER_ERROR);
                    }
                }
            }, $className);
        if ($errorFlag) {
            break;
        }
        $fileList = array();
        foreach ($includePathList as $includeDir) {
            $currentDir1 = $includeDir . DIRECTORY_SEPARATOR;
            $classNameListTmp = $classNameList;
            foreach ($classNameList as $val1) {
                $currentDir2 = "";
                foreach ($classNameListTmp as $val2) {
                    $file = $currentDir1 . $currentDir2 . $val2 . ".php";
                    if (is_file($file)) {
                        $fileList[] = $file;
                    }
                    $currentDir2 .= $val2;
                }
                if (count($classNameListTmp) <= 1) {
                    break;
                }
                $currentDir1 .= $val1 . DIRECTORY_SEPARATOR;
                if (!is_dir($currentDir1)) {
                    break;
                }
                array_shift($classNameListTmp);
            }
        }
        for ($i = count($fileList) - 1; $i >= 0; --$i) {
            @include_once($fileList[$i]);
            if (class_exists($className)) {
                break;
            }
        }
    } while (false);
});

2013-09-03

memo: vmware player, VirtualBox

VMnet8が192.168.129.1の場合でNATの場合 gateway 192.168.129.2, ipaddress 192.168.129.3-127 かもしれない。
仮想ネットワークエディタの使用はポートフォワーディングが必要な場合などのみ、かもしれない。
VirtualBoxを入れると休止状態から復帰した場合にvmware-playerのブリッジ接続ができなくなる場合がある。

以下は詳細です。

参考URL.
http://thatsdone-j.blogspot.jp/2013/01/vmware-player.html
http://blog.kondoyoshiyuki.com/2012/08/18/fix-ip-address-on-vmware-player/
http://prog.hateblo.jp/entry/2012/04/03/105927
http://qiita.com/nojima/items/4ee930105f947fc2e818
http://www.kuron-zero.com/port/windows7a.php

http://qiita.com/nojima/items/4ee930105f947fc2e818
管理者権限でコマンドプロンプトを開く。
    cd "C:\Program Files (x86)\VMware\VMware Player"
    rundll32 vmnetui.dll,VMNetUI_ShowStandalone

仮想ネットワークエディタ
↓
VMnet8  NAT  NAT  接続済み  有効  129.168.129.0  (最初からこうだった)
↓
選択してNAT設定
↓
ネットワーク     : vmnet8
...
ゲートウェイIP(G): 192.168.129.2 (最初からこうだった?触っていないはずだが微妙な値が入っている気持ちになる。)
...
ポート転送(F)
22  TCP  192.168.129.20:22 (これ追加のみ。これは入れた。)
...
OK押して適用が押せる状態になっているはずなので押す。

仮想ネットワークエディタのDHCPの設定の範囲外(192.168.129.128~254以外。255と1と2以外。)にした。
$ rcsdiff /etc/config-archive/etc/sysconfig/network-scripts/ifcfg-eth0,v /etc/sysconfig/network-scripts/ifcfg-eth0
===================================================================
RCS file: /etc/config-archive/etc/sysconfig/network-scripts/ifcfg-eth0,v
retrieving revision 1.1
diff -r1.1 /etc/sysconfig/network-scripts/ifcfg-eth0
8c8
< IPADDR="192.168.0.220"
---
> IPADDR="192.168.129.20"
10a11,13
> GATEWAY=192.168.129.2
> NETMASK=255.255.255.0
> BROADCAST=192.168.129.255

他のブリッジ接続のほうからは無理だった。
(windows,putty => ブリッジ接続のlinux => ssh 192.168.129.20 x)
windowsから直接sshしたところ、つながった。
(windows,putty => ssh 192.168.129.20 o)

いじっていないはず。過去にいじったかどうかは不明。
ネットワーク接続
VMware Network Adapter VMnet8のプロパティ
インターネットプロトコルバージョン4(tcp/ipv4)のプロパティは無変更
IPアドレス      : 192.168.129.1
サブネットマスク: 255.255.255.0
他は記入なし。

見た感じ GATEWAY=192.168.129.1 じゃダメなのか?のテスト。
仮想ネットワークエディタのNATの設定
ゲートウェイIP(G): 192.168.129.1 に変更。

centosのほうの設定変更
$ route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
192.168.129.0   0.0.0.0         255.255.255.0   U     1      0        0 eth0
0.0.0.0         192.168.129.1   0.0.0.0         UG    0      0        0 eth0

$ ifconfig |grep 192.168.129
          inet addr:192.168.129.20  Bcast:192.168.129.255  Mask:255.255.255.0

ダメだった。多分最初からNAT設定のGATEWAYは末尾2だった。

DNSは下記。これは実際のgateway=dnsの状態で。
$ cat /etc/resolv.conf 
# Generated by NetworkManager
search localnet
nameserver 192.168.0.1

ping test.
NATのOS => GATEWAY, DNS, 外, 多分OK
NATのOS => windows, ブリッジの他のos => 無理

$ ping -c1 192.168.0.1
PING 192.168.0.1 (192.168.0.1) 56(84) bytes of data.
64 bytes from 192.168.0.1: icmp_seq=1 ttl=128 time=1.11 ms

--- 192.168.0.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 1ms
rtt min/avg/max/mdev = 1.111/1.111/1.111/0.000 ms

$ ping -c1 www.google.co.jp
PING www.google.co.jp (173.194.72.94) 56(84) bytes of data.
64 bytes from tf-in-f94.1e100.net (173.194.72.94): icmp_seq=1 ttl=128 time=35.4 ms

--- www.google.co.jp ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 43ms
rtt min/avg/max/mdev = 35.498/35.498/35.498/0.000 ms

$ ping -c1 129.168.0.80
PING 129.168.0.80 (129.168.0.80) 56(84) bytes of data.

--- 129.168.0.80 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 10000ms

$ ping -c1 129.168.0.110
PING 129.168.0.110 (129.168.0.110) 56(84) bytes of data.

--- 129.168.0.110 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 10000ms

ブリッジのOS => NATのOS 無理。
ブリッジのOS => 192.168.129.1 x
ブリッジのOS => 192.168.129.2 x
ブリッジのOS => 192.168.129.20 x

windows7 => 192.168.129.1 o
windows7 => 192.168.129.2 x
windows7 => 192.168.129.20 o

ssh test.
windows7 => 192.168.129.20 o

natのosが外を見れる。
windowsからsshできる。
よくわからないが目的を達成したので成功。



同じネットワークであればpingは通るっぽい。
$ rcsdiff /etc/config-archive/etc/conf.d/net,v /etc/conf.d/net
===================================================================
RCS file: /etc/config-archive/etc/conf.d/net,v
retrieving revision 1.1
diff -r1.1 /etc/conf.d/net
9,10c9,10
< config_eth0="192.168.0.110 netmask 255.255.255.0 brd 192.168.0.255"
< routes_eth0="default via 192.168.0.1"
---
> config_eth0="192.168.129.21 netmask 255.255.255.0 brd 192.168.129.255"
> routes_eth0="default via 192.168.129.2"
12a13
> txqueuelen_eth0="65535"

$ ping -c3 192.168.129.20
PING 192.168.129.20 (192.168.129.20) 56(84) bytes of data.
64 bytes from 192.168.129.20: icmp_seq=1 ttl=64 time=0.680 ms
64 bytes from 192.168.129.20: icmp_seq=2 ttl=64 time=0.451 ms
64 bytes from 192.168.129.20: icmp_seq=3 ttl=64 time=0.431 ms

--- 192.168.129.20 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2000ms
rtt min/avg/max/mdev = 0.431/0.520/0.680/0.115 ms

自分のPCでlinux上のemacsなどのエディタが使いたいだけであれば、ポートフォワーディングはいらない。

ポート転送(F), 22  TCP  192.168.129.20:22
実際のwindowsのループバックの22。
ssh 127.0.0.1:22
他の実際のOSから見たwindowsのIPアドレスのport22で。
ssh 192.168.0.80:22

ポート転送(F), 22  TCP  192.168.129.21:10022
実際のwindowsのループバックの10022。
ssh 127.0.0.1:10022
他の実際のOSから見たwindowsのIPアドレスのport10022で。
ssh 192.168.0.80:10022

他の実際のパソコンから見るためにはファイアウォールに設定する。
http://www.kuron-zero.com/port/windows7a.php
tcp 22, 10022 開ける。

vmware立ち上げたところのwindowsからだけであればいらない。
ssh 192.168.129.20:22
ssh 192.168.129.21:22

vmware playerが無理だったらssh接続であればVirtualBoxもあり。
仮想マシン
設定
ネットワーク
割り当てNAT
ポートフォワーディング
Rule1  TCP  127.0.0.1  22  10.0.2.15  22

windowsから 127.0.0.1:22 でOK.
# /etc/sysconfig/network-scripts/ifcfg-eth0 変更していないが ifconfig, route 変化あり。
# 10.0.2.15 を固定できるか知らないが多分出来る気がする。

確認。
ポートフォワーディング
Rule1  TCP  127.0.0.1  22  10.0.2.115  22
に変更。

ifcfg-eth1を作成

$ cat /etc/sysconfig/network-scripts/ifcfg-eth1
DEVICE="eth1"
BOOTPROTO="static"
NM_CONTROLLED="yes"
ONBOOT="yes"
TYPE="Ethernet"
IPADDR="10.0.2.115"
NETMASK="255.255.255.0"
DNS1="192.168.0.1"
GATEWAY=10.0.2.2
NETMASK=255.255.255.0
BROADCAST=10.0.2.255

2013-08-30

PORTDIR_OVERLAYの追加 part4

参考URL.
https://devmanual.gentoo.org/general-concepts/dependencies/index.html

http://www.gentoo.org/doc/ja/policy.xml

http://www.atzm.org/gentoo/ebuilds2.html

http://insnvlovn.blogspot.jp/2013/08/memo-hhvm.html

hhvmの依存パッケージをemerge --depcleanで消したくない。
# /var/lib/portage/world(emerge --oneshot => emerge --noreplace)登録では
# 後で何でインストールした?となることがある。
# 全部libevent-1.4.14b-stableみたいにソースから入れれば良かったのでは?
$ /usr/local/hhvm/2013-08-11/hiphop-php/hphp/hhvm/hhvm --version
HipHop VM v2.1.0-dev (rel)
Compiler: heads/master-0-g67ec381c907f1cb0c20fd7ae39bac594cce5260f
Repo schema: c1d8348ed4576c1d8bea8d67f007c715860f7c6d

そんな時はvirtualパッケージを登録する。
# もっと楽にできたような気がする。コマンド的な何かで一発登録。
$ grep /usr/local/portage/test /etc/portage/make.conf
PORTDIR_OVERLAY="${PORTDIR_OVERLAY} /usr/local/portage/test"

mkdir -p /usr/local/portage/test/virtual/hhvm
cd /usr/local/portage/test/virtual/hhvm
cp -i /usr/portage/virtual/acl/acl-0-r1.ebuild hhvm-2.1.0.ebuild

RDEPENDだけ修正する。
# ={$packagename}-{$version} でバージョン固定で依存("="のかわりに"~"で-r1とかOK.)
# {$packagename}[useflag1,useflag2] で依存パッケージにuseflagを要求。
# もっと細かく指定可能なのでマニュアルを閲覧する。
# 個人の用途であれば説明とか修正しなくても動く。
# たまたま元から入っていた依存パッケージもあるので、それも書かないと後で動作しなくなる。
# バージョン書いてないのにもバージョン指定があったような気がした。インストール時のエラーメッセージで。
$ cat hhvm-2.1.0.ebuild
# Copyright 1999-2013 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header: /var/cvsroot/gentoo-x86/virtual/acl/acl-0-r1.ebuild,v 1.3 2013/03/22 16:03:21 jer Exp $

EAPI="3"

DESCRIPTION="Virtual for acl support (sys/acl.h)"
HOMEPAGE=""
SRC_URI=""

LICENSE=""
SLOT="0"
KEYWORDS="alpha amd64 arm hppa ia64 m68k ~mips ppc ppc64 s390 sh sparc x86 ~amd64-fbsd ~x86-fbsd ~amd64-linux ~ia64-linux ~x86-linux"
IUSE=""

DEPEND=""
RDEPEND="
dev-libs/boost
dev-cpp/glog[unwind]
=dev-libs/libmemcached-0.39
media-libs/gd[jpeg,png]
dev-cpp/tbb
net-nds/openldap
=dev-libs/libdwarf-20120410
net-libs/c-client
"

インストールする。
ebuild hhvm-2.1.0.ebuild manifest
sudo emerge -avt hhvm

確認する。
$ grep hhvm /var/lib/portage/world
virtual/hhvm

チェックする。
逆にuseflagがあってはいけない、と変更する。
...
dev-cpp/glog[-unwind]
...

インストールはしないが、どうなるか確認する。
$ ebuild hhvm-2.1.0.ebuild manifest
$ sudo emerge -avtp hhvm

The following USE changes are necessary to proceed:
 (see "package.use" in the portage(5) man page for more details)
# required by virtual/hhvm-2.1.0::x-test
# required by hhvm (argument)
>=dev-cpp/glog-0.3.3 -unwind

These are the packages that would be merged, in reverse order:

Calculating dependencies  ... done!
[ebuild   R    ] virtual/hhvm-2.1.0::x-test  0 kB
[ebuild   R    ]  dev-cpp/glog-0.3.3  USE="-gflags -static-libs {-test} -unwind*" 0 kB

Total: 2 packages (2 reinstalls), Size of downloads: 0 kB

戻す。
$ grep unwind hhvm-2.1.0.ebuild
dev-cpp/glog[unwind]
$ ebuild hhvm-2.1.0.ebuild manifest

$ sudo emerge -avtp hhvm

These are the packages that would be merged, in reverse order:

Calculating dependencies  .... done!
[ebuild   R    ] virtual/hhvm-2.1.0::x-test  0 kB

Total: 1 package (1 reinstall), Size of downloads: 0 kB

2013-08-29

memo

http://news.mynavi.jp/articles/2009/01/27/perftools/003.html

http://goog-perftools.sourceforge.net/doc/tcmalloc.html

http://www.ibm.com/developerworks/jp/opensource/library/os-php-v521/

http://www.checksite.jp/jmxterm-command-line-tool/

$ rcsdiff -r1.1 /etc/config-archive/etc/tomcat-7-7.0.42-main/server.xml,v /etc/tomcat-7-7.0.42-main/server.xml
===================================================================
RCS file: /etc/config-archive/etc/tomcat-7-7.0.42-main/server.xml,v
retrieving revision 1.1
diff -r1.1 /etc/tomcat-7-7.0.42-main/server.xml
27c27
<   <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
---
>   <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="off" />
71a72,74
>                acceptCount="65536"
>                maxConnections="-1"
>                maxThreads="2000"
91c94
<     <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
---
>     <!-- <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> -->

2013-08-28

memo: DBCP

http://people.apache.org/~fhanik/jdbc-pool/jdbc-pool.html

http://tomcat.apache.org/tomcat-7.0-doc/jndi-datasource-examples-howto.html#Database_Connection_Pool_%28DBCP%29_Configurations

http://tomcat.apache.org/tomcat-5.5-doc/jndi-datasource-examples-howto.html#Database_Connection_Pool_%28DBCP%29_Configurations

http://www.atmarkit.co.jp/ait/articles/1111/07/news212.html

警告: Failed to register in JMX: javax.naming.NamingException: Could not create resource factory instance [Root exception is java.lang.ClassNotFoundException: org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory]

$ tar xvzf /usr/portage/distfiles/commons-dbcp-1.4-src.tar.gz
$ cd commons-dbcp-1.4-src/
$ grep -nri BasicDataSourceFactory .
...
$ grep -nriP "org\..*\.BasicDataSourceFactory" .
./xdocs/release-notes-1.2.1.xml:42:     at org.apache.commons.dbcp.BasicDataSourceFactory.createDataSource(BasicDataSourceFactory.java:162)
./xdocs/release-notes-1.2.1.xml:43:     at org.apache.commons.dbcp.BasicDataSourceFactory.getObjectInstance(BasicDataSourceFactory.java:144)
./xdocs/guide/jndi-howto.xml:57:    "org.apache.commons.dbcp.BasicDataSourceFactory", null);

$ grep -A24 "jdbc/TestDB" ./conf/Catalina/localhost/test001.xml > tmp1.txt
$ grep -A24 "jdbc/DbcpTestDB" ./conf/Catalina/localhost/test001.xml > tmp2.txt
$ diff tmp{1,2}.txt
1c1
<   <Resource name="jdbc/TestDB"
---
>   <Resource name="jdbc/DbcpTestDB"
4c4
<             factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
---
>             factory="org.apache.commons.dbcp.BasicDataSourceFactory"

$ rcsdiff /etc/config-archive/etc/conf.d/tomcat-7-7.0.42-main,v /etc/conf.d/tomcat-7-7.0.42-main
===================================================================
RCS file: /etc/config-archive/etc/conf.d/tomcat-7-7.0.42-main,v
retrieving revision 1.2
diff -r1.2 /etc/conf.d/tomcat-7-7.0.42-main
19c19
< TOMCAT_EXTRA_JARS="jdbc-mysql"
---
> TOMCAT_EXTRA_JARS="jdbc-mysql,commons-pool,commons-collections,commons-dbcp"

2013-08-26

ab と gnuplot の例

ファイルサイズ。(サンプル結果含む)
466M    gnuplot.2013-08-25_230027/
13M     gnuplot.2013-08-25_230027.tar.bz2

使用法。レスポンスのbodyが同じURLを用意します。
$ grep -A6 -n "\$urlList =" make.php
111:    $urlList = array(
112-        "apache-worker_mod-php" => "http://192.168.0.110/test/gnuplot/test001.php",
113-        "pecl-event_php-cli" => "http://192.168.0.110:8010/",
114-        "tomcat" => "http://192.168.0.110:8080/test001/hello",
115-        "nodejs" => "http://192.168.0.110:8124/",
116-        "pecl-libevent_php-cli" => "http://192.168.0.110:2000/",
117-        );

phpコマンドを用意します。
$ php -v
PHP 5.4.17-pl0-gentoo (cli) (built: Aug 16 2013 22:08:43)
Copyright (c) 1997-2013 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2013 Zend Technologies

必要があればフォントを用意します。もしくは変更かコメントアウトします。
$ grep -n "putenv" make.php
10:putenv("PATH=/usr/bin:/bin:/usr/sbin");
300:        putenv("GDFONTPATH=/usr/share/fonts/mplus-outline-fonts/");
301:        putenv("GNUPLOT_DEFAULT_GDFONT=M+2P+IPAG");

実行します。
N=10000 && for C in 5 15 45; do php make.php $N $C; done &

サンプルの結果ではpecl-eventが有利です。
しかしwebサーバとabとブラウザなどの色々な動作が一緒に動いているサーバの状態なので参考です。
なおEventHttp::setCallbackはメモリリークするようです。setDefaultCallbackで代用可能ですが。

gnuplotの設定はデータからグラフ表示だけする場合は複雑ではないです。
日本語も試したら使えました。
データは TIMESTAMP, data1, [data2 ...] のように2種類以上のデータであればグラフっぽくできます。

例えばsiegeがurllistとlogfileがあるようなので、複数のurlを指定する場合ab以外のほうが良いです。

ソースはhttp://www.php.net/manual/en/event.examples.phpのExample #8 Simple HTTP server です。

pecl-libeventのほうはstream_socket_serverのbacklogが128固定なのが関係が深いかもしれません。
ソースはhttps://gist.github.com/joseph-montanez/1122992です。
http://php.net/manual/en/libevent.examples.phpのServer example:です。

nodejsはhttp://nodejs.org/api/synopsis.htmlです。
apache(mod_php)とtomcatはprintを実行するだけのソースです。

https://docs.google.com/file/d/0BwK7sPpG0c5Zbjh6ZjhXenhxanM/edit?usp=sharing



参考URL.
http://blog.tojiru.net/category/10170146-4.html

http://blog.tojiru.net/article/225226976.html#more

http://tech.camobile.com/httpd/centos6-2-%E3%81%AB-g-wan-%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%97%E3%81%A6%E3%81%BF%E3%81%9F%E3%82%88/2036

http://stackoverflow.com/questions/5929104/apache-bench-gnuplot-output-what-are-the-column-definitions

http://stackoverflow.com/questions/937627/how-to-redirect-stdout-to-a-file-in-php

http://folk.uio.no/hpl/scripting/doc/gnuplot/Kawano/plot2.html

http://dsl4.eee.u-ryukyu.ac.jp/DOCS/gnuplot/node162.html

http://www.kusastro.kyoto-u.ac.jp/~moritani/etc/memo/gnuplot_memo.html

http://www.obihiro.ac.jp/~suzukim/masuda/utils/gnuplot.html

http://satococoa.github.io/blog/2012/10/25/performance-test-with-httperf/

http://memo.yomukaku.net/entries/394J1JB

http://higelog.brassworks.jp/?p=562

http://www5a.biglobe.ne.jp/~nkgwtty/nn_gnuplot.html

http://www.ss.scphys.kyoto-u.ac.jp/person/yonezawa/contents/program/gnuplot/label.html

http://squeeze.jp/blog/web-design/heading-design-css-only/

http://www.gnuplot-cmd.com/chart/label.html

http://d.hatena.ne.jp/ks88/20100110/1263127086

http://d.hatena.ne.jp/UDONCHAN/20101116/1289891757

http://www.netplan.co.jp/archives/1559

http://dsl4.eee.u-ryukyu.ac.jp/DOCS/gnuplot/node82.html

http://www.deqnotes.net/gnuplot/labels

http://d.hatena.ne.jp/sobasobasoba/20091212/1260613135

http://nemf.info/2011/07/how-to-make-a-graph-from-vmstat-by-gnuplot/

2013-08-25

memo: sort

id    uptm   data
...   ...    ...

-k2,2r -k1,1        => ORDER BY uptm DESC, id ASC
-k2,2r -k1          => ORDER BY uptm DESC, id ASC, data ASC
-k3,3r -k2,2r -k1,1 => ORDER BY data DESC, uptm DESC, id ASC

-k1                 => ORDER BY id ASC, uptm ASC, data ASC
-k1 -k3r            => ORDER BY id ASC, uptm ASC, data ASC
-k1,1 -k3,3r        => ORDER BY id ASC, data DESC
"-k1,1" "-k1,1r" のようにXX個目のカラムだけを正順、逆順、という風に書かないと、逆に難しい。



以下は詳細です。

定期的にsortがおかしい、なぜだ?と考えるのでメモを取る。
その都度納得しているような気がするが、なぜ納得したのか覚えていない。

元データ。
$ (echo "A z 0" && echo "B x 1" && echo "A y 1" && echo "B z 0")
A z 0
B x 1
A y 1
B z 0

1カラム目~3カラム目までソートしてから、3カラム目でソートしている。
# 3カラム目のソートは2カラム目でソート済みなので無意味?
# 3カラム目はソート済み、という情報が記録されて何回も同じカラムでソートできない?
$ (echo "A z 0" && echo "B x 1" && echo "A y 1" && echo "B z 0") | sort -k1 -k3
A y 1
A z 0
B x 1
B z 0

1カラム目でソートしてから、3カラム目でソートしている。
$ (echo "A z 0" && echo "B x 1" && echo "A y 1" && echo "B z 0") | sort -k1,1 -k3,3
A z 0
A y 1
B z 0
B x 1

レコードを1つ増やす。
$ (echo "B z 1" && echo "A z 0" && echo "B x 1" && echo "A y 1" && echo "B z 0")
B z 1
A z 0
B x 1
A y 1
B z 0

1カラム目~3カラム目でソートしてから、3カラム目でソートする。(成功?)
$ (echo "B z 1" && echo "A z 0" && echo "B x 1" && echo "A y 1" && echo "B z 0") | sort -k1 -k3
A y 1
A z 0
B x 1
B z 0
B z 1

1カラム目~3カラム目でソートしてから、3カラム目で逆順ソートする。(失敗)
# 最後の2行が入れ替わることを期待した。
$ (echo "B z 1" && echo "A z 0" && echo "B x 1" && echo "A y 1" && echo "B z 0") | sort -k1 -k3r
A y 1
A z 0
B x 1
B z 0
B z 1

1カラム目~2カラム目でソートしてから、3カラム目で逆順ソートする。(成功)
$ (echo "B z 1" && echo "A z 0" && echo "B x 1" && echo "A y 1" && echo "B z 0") | sort -k1,2 -k3r
A y 1
A z 0
B x 1
B z 1
B z 0

1カラム目で逆順にソートする。(成功)
# 元の順序は保証されず、指定した1カラム目だけで見た場合は成功。
$ (echo "B z 1" && echo "A z 0" && echo "B x 1" && echo "A y 1" && echo "B z 0") | sort -k1,1r
B x 1
B z 0
B z 1
A y 1
A z 0

1カラム目で逆順にソートしたが、やっぱり正順にしよう。(失敗)
$ (echo "B z 1" && echo "A z 0" && echo "B x 1" && echo "A y 1" && echo "B z 0") | sort -k1,1r -k1,1
B x 1
B z 0
B z 1
A y 1
A z 0

2カラム目~3カラム目でソートしてから、1カラム目~3カラム目でソート(多分1カラム目のみ有効)する。
# ODER BY 2カラム目 ASC、3カラム目 ASC、1カラム目 ASC、なイメージ。
$ (echo "B z 1" && echo "A z 0" && echo "B x 1" && echo "A y 1" && echo "B z 0") | sort -k2 -k1
B x 1
A y 1
A z 0
B z 0
B z 1

2カラム目~3カラム目でソートしてから、1カラム目~3カラム目で逆順ソート(多分1カラム目のみ有効)する。
# 1カラム目の最後3つ, B,A,B は、3カラム目の最後3つ, 0,0,1 のほうが優先なので、おかしくない。
# ODER BY 2カラム目 ASC、3カラム目 ASC、1カラム目 DESC、なイメージ。
$ (echo "B z 1" && echo "A z 0" && echo "B x 1" && echo "A y 1" && echo "B z 0") | sort -k2 -k1r
B x 1
A y 1
B z 0
A z 0
B z 1

2カラム目でソートしてから、1カラム目~3カラム目で逆順にソート(1カラム目、3カラム目の順にソート)する。
# ODER BY 2カラム目 ASC、1カラム目 DESC、3カラム目 DESC、なイメージ。
$ (echo "B z 1" && echo "A z 0" && echo "B x 1" && echo "A y 1" && echo "B z 0") | sort -k2,2 -k1r
B x 1
A y 1
B z 1
B z 0
A z 0

2カラム目でソートしてから、1カラム目で逆順にソートする。
# ODER BY 2カラム目 ASC、1カラム目 DESC、なイメージ。
# B z 0
# B z 1 <= ここら辺の順番は確定ではない。
$ (echo "B z 1" && echo "A z 0" && echo "B x 1" && echo "A y 1" && echo "B z 0") | sort -k2,2 -k1,1r
B x 1
A y 1
B z 0
B z 1
A z 0

2カラム目でソートしてから、1カラム目で逆順にソートしてから、3カラム目で逆順にソートする。
# ODER BY 2カラム目 ASC、1カラム目 DESC、3カラム目 DESC、なイメージ。
# B z 1
# B z 0 <= ここら辺の順番を"B z 0","B z 1"にする場合は -k3,3r => -k3,3
$ (echo "B z 1" && echo "A z 0" && echo "B x 1" && echo "A y 1" && echo "B z 0") | sort -k2,2 -k1,1r -k3,3r
B x 1
A y 1
B z 1
B z 0
A z 0

バイト単位でソートの場合。
# 多分utf-8の場合は大丈夫。
LC_ALL=C sort

2013-08-23

memo: tomcat

http://www.mulesoft.com/using-tomcat-reload-features-speed-development
http://tomcat.apache.org/tomcat-7.0-doc/api/org/apache/catalina/core/ContainerBase.html
http://wiki.gentoo.org/wiki/Apache_Tomcat
http://www.searchman.info/java_eclipse/1040.html

$ cat /var/lib/tomcat-7-main/conf/Catalina/localhost/test001.xml
<?xml version="1.0" encoding="UTF-8"?>
<Context
    reloadable="true"
    backgroundProcessorDelay="1"
    >
  <WatchedResource>WEB-INF/web.xml</WatchedResource>
</Context>

再起動が遅い。
reloadable="true"でも読み込みが遅い。10秒。
javac xxx.java => xxx.class で出力途中のファイルが読み込まれるとおかしくなる。メモリリーク。

意味は無いかもしれない。
javac -d ./tmp/ -classpath "/usr/share/tomcat-servlet-api-3.0/lib/servlet-api.jar" HelloWorld.java && mv -f ./tmp/HelloWorld.class .

jspは関係ないかもしれない。
eclipseを使うのが正解かもしれない。

$ grep -nriP "backgroundProcessorDelay\s*=" apache-tomcat-7.0.32-src/
apache-tomcat-7.0.32-src/java/org/apache/catalina/core/StandardEngine.java:76:        backgroundProcessorDelay = 10;
apache-tomcat-7.0.32-src/java/org/apache/catalina/core/ContainerBase.java:176:    protected int backgroundProcessorDelay = -1;
apache-tomcat-7.0.32-src/java/org/apache/catalina/core/ContainerBase.java:370:        backgroundProcessorDelay = delay;

backgroundProcessorDelayはreloadable限定の設定ではないのでテスト以外で変な値にするとダメかもしれない。

$ grep -iP "java|tomcat" /var/lib/portage/world | while read pkgname; do eix -I $pkgname | grep -P "(^\[I\]\s)|(^\s*Installed versions:)"; done
[I] dev-java/jdbc-mysql
     Installed versions:  5.1.18^t(08:14:30 08/22/13)(-c3p0 -log4j -source ELIBC="-FreeBSD")
[I] dev-java/struts
     Installed versions:  1.2.9-r3(1.2)(05:50:48 04/06/13)(doc examples source ELIBC="-FreeBSD")
[I] www-servers/tomcat
     Installed versions:  7.0.32(7)^t(06:25:34 04/06/13)(doc extra-webapps source -test ELIBC="-FreeBSD")

#$ sudo /usr/share/tomcat-7/gentoo/tomcat-instance-manager.bash --create
#$ sudo /usr/share/tomcat-7/gentoo/tomcat-instance-manager.bash --remove
$ sudo /usr/share/tomcat-7/gentoo/tomcat-instance-manager.bash --create --suffix main

$ cat /var/lib/tomcat-7-main/webapps/test001/WEB-INF/web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app
    version="3.0"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">

  <servlet>
    <servlet-name>hello</servlet-name>
    <servlet-class>HelloWorld</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>
      hello
    </servlet-name>
    <url-pattern>
      /hello
    </url-pattern>
  </servlet-mapping>

</web-app>

$ cat /var/lib/tomcat-7-main/webapps/test001/WEB-INF/classes/HelloWorld.java
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class HelloWorld extends HttpServlet {
    public void doGet(HttpServletRequest request,
                      HttpServletResponse response)
        throws IOException, ServletException
    {

        PrintWriter out = response.getWriter();
        out.println("HelloWorld.");
        out.close();
    }
}

javac -d ./tmp/ -classpath "/usr/share/tomcat-servlet-api-3.0/lib/servlet-api.jar" HelloWorld.java && mv -f ./tmp/HelloWorld.class .

$ tail -n0 -f /var/log/tomcat-7-main/catalina.2013-08-23.log
Aug 23, 2013 8:23:02 AM org.apache.catalina.core.StandardContext reload
INFO: Reloading Context with name [/test001] has started
Aug 23, 2013 8:23:02 AM org.apache.catalina.core.StandardContext reload
INFO: Reloading Context with name [/test001] is completed

/var/lib/tomcat-7-main/conf/Catalina/localhost/test001.xml
/var/lib/tomcat-7-main/webapps/test001/WEB-INF/classes/HelloWorld.java
/var/lib/tomcat-7-main/webapps/test001/WEB-INF/web.xml

$ curl http://localhost:8080/test001/hello
HelloWorld.1

2013-08-19

memo: MF-HTU332GBK

https://downloadcenter.intel.com/SearchResult.aspx?lang=jpn&ProductFamily=%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%E8%A3%BD%E5%93%81&ProductLine=%E3%83%81%E3%83%83%E3%83%97%E3%82%BB%E3%83%83%E3%83%88%E3%83%BB%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2&ProductProduct=%E3%82%A4%E3%83%B3%E3%83%86%E3%83%AB%C2%AE+%E3%83%81%E3%83%83%E3%83%97%E3%82%BB%E3%83%83%E3%83%88%E3%83%BB%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%E3%83%BB%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%83%BB%E3%83%A6%E3%83%BC%E3%83%86%E3%82%A3%E3%83%AA%E3%83%86%E3%82%A3%E3%83%BC

Windows 7 (64-bit)*
ドライバ

https://downloadcenter.intel.com/Detail_Desc.aspx?agr=Y&DwnldID=20775&ProdId=816&lang=jpn&OSVersion=Windows%207%20%2864-bit%29*&DownloadType=%E3%83%89%E3%83%A9%E3%82%A4%E3%83%90

Intel® Chipset Device Software (INF Update Utility)

ファイル名:infinst_autol.exe
バージョン:9.4.0.1022

多分これを入れればOK.








FRGS515T/Dというパソコンを使っているがUSB3のメモリが認識しないことがわかった。

http://www.cpuid.com/softwares/cpu-z.html

cpu-z_1.66-setup-en.exe

IPMSB-DA-B75-8111D-ODM という名前だった。

https://downloadcenter.intel.com/confirm.aspx?httpDown=http://downloadmirror.intel.com/21129/eng/Intel%28R%29_USB_3.0_eXtensible_Host_Controller_Driver.zip&lang=jpn&Dwnldid=21129

Intel(R)_USB_3.0_eXtensible_Host_Controller_Driver.zip
Setup.exe

インストールの要件を満たしていないと言われた。

http://devid.info/model/64712

381415.devid.info.exe

実行してみたが別に有効にならなかった。

Setup.exe

今度は普通に実行できた。

再起動後USB3で認識した。

-----------------------------------------------------------------------
CrystalDiskMark 3.0.2 x64 (C) 2007-2012 hiyohiyo
                           Crystal Dew World : http://crystalmark.info/
-----------------------------------------------------------------------
* MB/s = 1,000,000 byte/s [SATA/300 = 300,000,000 byte/s]

           Sequential Read :    98.028 MB/s
          Sequential Write :    18.916 MB/s
         Random Read 512KB :    92.102 MB/s
        Random Write 512KB :    14.686 MB/s
    Random Read 4KB (QD=1) :     7.474 MB/s [  1824.8 IOPS]
   Random Write 4KB (QD=1) :     1.287 MB/s [   314.3 IOPS]
   Random Read 4KB (QD=32) :     9.690 MB/s [  2365.7 IOPS]
  Random Write 4KB (QD=32) :     1.552 MB/s [   378.9 IOPS]

  Test : 50 MB [I: 0.0% (0.0/28.9 GB)] (x5)
  Date : 2013/08/19 22:40:37
    OS : Windows 7 Professional SP1 [6.1 Build 7601] (x64)
  

MF-HTU332GBK です。

-----------------------------------------------------------------------
CrystalDiskMark 3.0.2 x64 (C) 2007-2012 hiyohiyo
                           Crystal Dew World : http://crystalmark.info/
-----------------------------------------------------------------------
* MB/s = 1,000,000 byte/s [SATA/300 = 300,000,000 byte/s]

           Sequential Read :   132.104 MB/s
          Sequential Write :    21.324 MB/s
         Random Read 512KB :   102.089 MB/s
        Random Write 512KB :    15.955 MB/s
    Random Read 4KB (QD=1) :     7.524 MB/s [  1836.9 IOPS]
   Random Write 4KB (QD=1) :     1.285 MB/s [   313.7 IOPS]
   Random Read 4KB (QD=32) :     9.869 MB/s [  2409.5 IOPS]
  Random Write 4KB (QD=32) :     1.560 MB/s [   381.0 IOPS]

  Test : 50 MB [I: 0.3% (0.1/28.8 GB)] (x5)
  Date : 2013/08/20 0:15:43
    OS : Windows 7 Professional SP1 [6.1 Build 7601] (x64)
  
exFAT
32768 キロバイト
取り外しポリシー
高パフォーマンス

2013-08-18

memo: postgresql, mysql

/etc/mysql/my.cnf /etc/postgresql-9.2/postgresql.conf 変更無し。

$ eix -C dev-db "^(mysql|postgresql-server)$"|grep "Installed versions:"
     Installed versions:  5.1.70(11時28分41秒 2013年08月18日)(community perl ssl -big-tables -cluster -debug -embedded -extraengine -latin1 -max-idx-128 -minimal -pbxt -profiling -selinux -static -test -xtradb)
     Installed versions:  9.2.4(9.2)(12時40分02秒 2013年08月18日)(nls pam perl -doc -kerberos -pg_legacytimestamp -python -selinux -tcl -test -uuid -xml KERNEL="linux" LINGUAS="-af -cs -de -en -es -fa -fr -hr -hu -it -ko -nb -pl -pt_BR -ro -ru -sk -sl -sv -tr -zh_CN -zh_TW" PYTHON_SINGLE_TARGET="python2_7 -python2_5 -python2_6 -python3_1 -python3_2 -python3_3" PYTHON_TARGETS="python2_7 python3_2 -python2_5 -python2_6 -python3_1 -python3_3")

$ sudo su - -c "echo 3 > /proc/sys/vm/drop_caches"
$ sudo /etc/init.d/mysql restart

mysql> create table test004 (id serial, data text) ENGINE=innodb;
Query OK, 0 rows affected (0.04 sec)

mysql> show create table test004\G
*************************** 1. row ***************************
       Table: test004
Create Table: CREATE TABLE `test004` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `data` text,
  UNIQUE KEY `id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

$ for cnt in $(seq 1 10); do ab -n2000 -c200 http://192.168.0.110:2000/ 2>&1 | grep -iP "^((Non-2xx responses)|(Failed requests)|(   \\(Connect)|(Complete requests)|(Requests per second)):"; done | sort | uniq -c | sort -k1nr,5n
     10 Complete requests:      2000
     10 Failed requests:        0
      1 Requests per second:    206.60 [#/sec] (mean)
      1 Requests per second:    213.36 [#/sec] (mean)
      1 Requests per second:    221.74 [#/sec] (mean)
      1 Requests per second:    221.75 [#/sec] (mean)
      1 Requests per second:    224.32 [#/sec] (mean)
      1 Requests per second:    226.38 [#/sec] (mean)
      1 Requests per second:    239.60 [#/sec] (mean)
      1 Requests per second:    242.41 [#/sec] (mean)
      1 Requests per second:    242.47 [#/sec] (mean)
      1 Requests per second:    265.60 [#/sec] (mean)

mysql> select * from test004 order by id desc limit 1;
+-------+----------------------------+
| id    | data                       |
+-------+----------------------------+
| 20011 | 2013-08-18 11:59:06.715882 |
+-------+----------------------------+
1 row in set (0.03 sec)

$ sudo su - -c "echo 3 > /proc/sys/vm/drop_caches"
$ sudo /etc/init.d/mysql restart

mysql> drop table test004;
Query OK, 0 rows affected (0.00 sec)

mysql> create table test004 (id serial, data text) ENGINE=myisam;
Query OK, 0 rows affected (0.03 sec)

mysql> show create table test004\G
*************************** 1. row ***************************
       Table: test004
Create Table: CREATE TABLE `test004` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `data` text,
  UNIQUE KEY `id` (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

$ for cnt in $(seq 1 10); do ab -n2000 -c200 http://192.168.0.110:2000/ 2>&1 | grep -iP "^((Non-2xx responses)|(Failed requests)|(   \\(Connect)|(Complete requests)|(Requests per second)):"; done | sort | uniq -c | sort -k1nr,5n
     10 Complete requests:      2000
     10 Failed requests:        0
      1 Requests per second:    2402.95 [#/sec] (mean)
      1 Requests per second:    2435.10 [#/sec] (mean)
      1 Requests per second:    2438.26 [#/sec] (mean)
      1 Requests per second:    2471.78 [#/sec] (mean)
      1 Requests per second:    3124.24 [#/sec] (mean)
      1 Requests per second:    3176.14 [#/sec] (mean)
      1 Requests per second:    3179.68 [#/sec] (mean)
      1 Requests per second:    3180.62 [#/sec] (mean)
      1 Requests per second:    3232.88 [#/sec] (mean)
      1 Requests per second:    3235.57 [#/sec] (mean)

mysql> select * from test004 order by id desc limit 1;
+-------+----------------------------+
| id    | data                       |
+-------+----------------------------+
| 20000 | 2013-08-18 12:01:47.475692 |
+-------+----------------------------+
1 row in set (0.03 sec)

$ sudo su - -c "echo 3 > /proc/sys/vm/drop_caches"
$ sudo /etc/init.d/postgresql-9.2 restart

dbname=# drop table test004;
ERROR:  テーブル"test004"は存在しません
dbname=# create table test004 (id serial, data text);
NOTICE:  CREATE TABLEはシリアル列"test004.id"用に暗黙的なシーケンス"test004_id_seq"を作成します。
CREATE TABLE

$ for cnt in $(seq 1 10); do ab -n2000 -c200 http://192.168.0.110:2000/ 2>&1 | grep -iP "^((Non-2xx responses)|(Failed requests)|(   \\(Connect)|(Complete requests)|(Requests per second)):"; done | sort | uniq -c | sort -k1nr,5n
     10 Complete requests:      2000
     10 Failed requests:        0
      1 Requests per second:    1117.53 [#/sec] (mean)
      1 Requests per second:    1136.16 [#/sec] (mean)
      1 Requests per second:    1144.23 [#/sec] (mean)
      1 Requests per second:    1147.27 [#/sec] (mean)
      1 Requests per second:    1155.13 [#/sec] (mean)
      1 Requests per second:    1155.26 [#/sec] (mean)
      1 Requests per second:    1163.53 [#/sec] (mean)
      1 Requests per second:    1163.71 [#/sec] (mean)
      1 Requests per second:    1164.36 [#/sec] (mean)
      1 Requests per second:    974.07 [#/sec] (mean)

dbname=# select * from test004 order by id desc limit 1;
  id   |            data
-------+----------------------------
 20000 | 2013-08-18 13:05:01.021865
(1 行)

http://www.php.net/manual/ja/libevent.examples.php
https://gist.github.com/joseph-montanez/1122992
http://www.php.net/manual/ja/book.http.php

この結果はチューニングをしてなく内容も単純なので参考でしかありませんが
この中ではトランザクションとSQLが使いたいのであればpostgresqlが良く
SQLが使いたいのであればmysql-myisamが良いです。
またpeclのlibeventはphpからnodejsに変えるか検討している場合には
nodejs以外の選択肢の一つになると思います。

vmware playerのディスク拡張の例

vmware playerのディスク拡張の例です。
LVMは使っていません。
パーテーションが1つだけか、サイズを増やしたいパーテーションがディスクの最後にある場合の例です。

失敗に備えてコピーします。
C:\Users\username\Documents\Virtual Machines\GentooLinux-x86_64
C:\Users\username\Documents\Virtual Machines\GentooLinux-x86_64 - コピー

BIOSの画面でキーが押せない場合に追加します。
c:/Users/username/Documents/Virtual Machines/GentooLinux-x86_64/GentooLinux-x86_64.vmx

bios.bootDelay = "5000"

linuxの入ったイメージファイルをダウンロードします。
http://ftp.jaist.ac.jp/pub/Linux/Gentoo/releases/amd64/current-iso/

install-amd64-minimal-20130816.iso

CDを入れます。
仮想マシン設定の編集
  CD/DVD(IDE)
    デバイスのステータス
      起動時に接続、にチェック
    ISOイメージファイルを使用する
      C:\Users\username\Downloads\ユーティリティ\iso\install-amd64-minimal-20130816.iso

ハードディスクを拡張します。
ハードディスク(SCSI)  30GB
  ユーティリティ
    拡張
      ディスク最大サイズ(GB) 30.0 => 32.0
ハードディスク(SCSI)  32GB

CDで起動します。
仮想マシンの再生
  画面をクリック
    Escキーを押す。(F2でBIOSメニュー)
      Boot Menu
        CD-ROM Drive

linuxを起動します。
boot:
  Enterキーを押す

...

livecd ~ #

キー配列を設定し、
パスワードを設定し、
IPアドレスを確認し、
sshサーバを起動します。
loadkeys jp106
passwd
ifconfig
/etc/init.d/sshd start

sshで接続します。
ディスクを確認します。その際 head, tail は必要無いです。
ssh 192.168.0.2

livecd ~ # cd /tmp/

livecd tmp # fdisk -l /dev/sda | head -n2 | tail -n1
Disk /dev/sda: 34.4 GB, 34359738368 bytes, 67108864 sectors

livecd tmp # fdisk -l /dev/sda1 | head -n2 | tail -n1
Disk /dev/sda1: 32.2 GB, 32211206144 bytes, 62912512 sectors

fdiskを起動します。
2048 62914559 などの表示をコピペなどしときます。
fdisk /dev/sda

Command (m for help): w [Enter] しないと保存しないのでhelpを見ながら操作する。

Command (m for help): q [Enter] でセーブせずに戻る。

Command (m for help): p
...
/dev/sda1            2048    62914559    31456256   83  Linux

削除して新しいパーテーションを作成します。
2048 が同じで、
62914559 が増えています。
Command (m for help): d
Selected partition 1
Partition 1 is deleted

Command (m for help): n
Partition type:
   p   primary (0 primary, 0 extended, 4 free)
   e   extended
Select (default p):
Using default response p
Partition number (1-4, default 1):
Using default value 1
First sector (2048-67108863, default 2048):
Using default value 2048
Last sector, +sectors or +size{K,M,G} (2048-67108863, default 67108863):
Using default value 67108863
Partition 1 of type Linux and of size 32 GiB is set

Command (m for help): p

Disk /dev/sda: 34.4 GB, 34359738368 bytes, 67108864 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x70c133cf

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1            2048    67108863    33553408   83  Linux

書き込みます。
Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.
livecd tmp #

リサイズします。
resize2fs の -p は作業完了分のパーセントを表すバーを表示します。
livecd tmp # resize2fs /dev/sda1
resize2fs 1.42.7 (21-Jan-2013)
Please run 'e2fsck -f /dev/sda1' first.

livecd tmp # e2fsck -f /dev/sda1
e2fsck 1.42.7 (21-Jan-2013)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/: 682914/1966080 files (0.2% non-contiguous), 3760376/7864064 blocks

livecd tmp # resize2fs -p /dev/sda1
resize2fs 1.42.7 (21-Jan-2013)
Resizing the filesystem on /dev/sda1 to 8388352 (4k) blocks.
The filesystem on /dev/sda1 is now 8388352 blocks long.

確認します。
livecd tmp # fdisk -l /dev/sda | head -n2 | tail -n1
Disk /dev/sda: 34.4 GB, 34359738368 bytes, 67108864 sectors

livecd tmp # fdisk -l /dev/sda1 | head -n2 | tail -n1
Disk /dev/sda1: 34.4 GB, 34358689792 bytes, 67106816 sectors

リードオンリーでマウントして確認します。
大丈夫そうであればシャットダウンします。
livecd tmp # mkdir sda1

livecd tmp # mount -r /dev/sda1 sda1/

livecd tmp # df|grep sda1
/dev/sda1       32895856 14420948  16797244  47% /tmp/sda1

livecd tmp # df -h|grep sda1
/dev/sda1        32G   14G   17G  47% /tmp/sda1

livecd tmp # mount | grep sda1
/dev/sda1 on /tmp/sda1 type ext4 (ro)

livecd tmp # umount sda1/

livecd tmp # shutdown -h now

CDでの起動を無効化します。
仮想マシン設定の編集
  CD/DVD(IDE)
    デバイスのステータス
      起動時に接続、のチェックを外す

起動すれば成功です。

2013-08-16

memo: bash-completion

http://forums.gentoo.org/viewtopic-t-898628-start-0.html
http://d.hatena.ne.jp/pcmaster/20101021/p1

sudo emerge --oneshot -avt app-shells/bash-completion

sudo eselect bashcomp enable --global gentoo
sudo eselect bashcomp enable --global ssh
#sudo eselect bashcomp enable --global base

$ ssh bash: _known_hosts_real: コマンドが見つかりません
bash: _known_hosts_real: コマンドが見つかりません

sudo eselect bashcomp enable --global base

$ ll /etc/bash_completion.d/
合計 0
lrwxrwxrwx 1 root root 36 2013-08-16 23:34:38 base -> ../../usr/share/bash-completion/base
lrwxrwxrwx 1 root root 38 2013-08-16 23:24:29 gentoo -> ../../usr/share/bash-completion/gentoo
lrwxrwxrwx 1 root root 35 2013-08-16 23:33:00 ssh -> ../../usr/share/bash-completion/ssh

$ grep -iP "^\s*have\s+\w+\s+\&\&" /etc/bash_completion.d/* | perl -pe 's/^.*:have (\w+).*$/$1/' | while read cmd; do which $cmd 2>/dev/null; if [ $? -ne 0 ]; then echo "### "$cmd; fi; done
/usr/bin/emerge
/usr/bin/ebuild
/sbin/rc
/usr/bin/equery
/usr/bin/epkginfo
### ekeyword
/usr/bin/portageq
### splat
/usr/bin/euse
### epm
### metagen
/usr/bin/ssh

memo: postgresql

http://www.postgresql.jp/document/9.2/html/indexes.html
http://dqn.sakusakutto.jp/2011/11/postgresql.html
http://d.hatena.ne.jp/y-kawaz/20090226/1235623336
http://lets.postgresql.jp/documents/technical/bulkload/
http://www.techscore.com/blog/2013/03/12/%E9%9B%86%E5%90%88%E3%82%92%E8%BF%94%E3%81%99generate_series%E9%96%A2%E6%95%B0%E3%81%A7%E5%A4%A7%E9%87%8F%E3%83%87%E3%83%BC%E3%82%BF%E3%82%92%E7%94%9F%E6%88%90%E3%81%97%E3%81%A6%E9%9B%86%E8%A8%88/
http://longkey1.net/blog/2013/05/09/clear-postgresql-caches/
http://www.glamenv-septzen.net/view/725
http://d.hatena.ne.jp/hhelibex/20110609/1307620714
http://www.ksknet.net/postgresql/primary_key.html
http://www.postgresql.jp/document/9.2/html/sql-commands.html
http://dba.stackexchange.com/questions/2070/postgresql-count-uses-a-sequential-scan-not-index
http://stackoverflow.com/questions/2204058/show-which-columns-an-index-is-on-in-postgresql
http://stackoverflow.com/questions/3524859/how-to-display-full-stored-procedure-code
http://serverfault.com/questions/34741/postgres-equivalent-to-mysqls-g
http://www.pgadmin.org/
http://stansantiago.wordpress.com/2011/10/30/install-and-configure-pl-php-for-postgres-9-1/
http://www.atmarkit.co.jp/ait/articles/0810/01/news134_3.html
http://lets.postgresql.jp/documents/tutorial/gihyo_rensai/5/
http://lets.postgresql.jp/documents/technical/text-processing/3
http://aoi-f.blog.so-net.ne.jp/2011-05-15

目的は、
postgresqlはどうだろう?使ったことある、
pgadminは便利だったような気がする、
phpをトリガーの言語で使えたような気がするが今は無い、
などです。

テスト環境です。
$ uname -a
Linux vmware-gentoo1 3.8.13-gentoo #1 SMP Thu May 16 19:10:40 JST 2013 x86_64 Intel(R) Core(TM) i5-3470 CPU @ 3.20GHz GenuineIntel GNU/Linux

$ emerge --info|grep -P "^(CFLAGS|CXXFLAGS|CHOST)="
CFLAGS="-march=native -O2"
CHOST="x86_64-pc-linux-gnu"
CXXFLAGS="-march=native -O2"

$ LC_ALL=C lscpu
Architecture:          x86_64
CPU op-mode(s):        32-bit, 64-bit
Byte Order:            Little Endian
CPU(s):                3
On-line CPU(s) list:   0-2
Thread(s) per core:    1
Core(s) per socket:    3
Socket(s):             1
Vendor ID:             GenuineIntel
CPU family:            6
Model:                 58
Stepping:              9
CPU MHz:               3192.820
BogoMIPS:              6385.64
Hypervisor vendor:     VMware
Virtualization type:   full
L1d cache:             32K
L1i cache:             32K
L2 cache:              256K
L3 cache:              6144K

$ free
             total       used       free     shared    buffers     cached
Mem:       8170124    1313924    6856200          0     159176     610836
-/+ buffers/cache:     543912    7626212
Swap:       131068          0     131068

インストールします。
$ grep postgresql /etc/portage/package.use/x86_64-pc-linux-gnu
dev-db/postgresql-server       perl
$ sudo emerge --oneshot -avt dev-db/postgresql-server
$ sudo emerge --config dev-db/postgresql-server:9.2

ユーザーを作成します。
# 多分"-a"は非推奨。"-s"が正解。
$ sudo createuser -a -E -P -U postgres dbuser

設定を変更します。
$ /usr/bin/sudo /usr/bin/rcsdiff /etc/config-archive/etc/postgresql-9.2/postgresql.conf,v /etc/postgresql-9.2/postgresql.conf
===================================================================
RCS file: /etc/config-archive/etc/postgresql-9.2/postgresql.conf,v
retrieving revision 1.1
diff -r1.1 /etc/postgresql-9.2/postgresql.conf
59c59
< #listen_addresses = 'localhost'          # what IP address(es) to listen on;
---
> listen_addresses = '192.168.0.110'       # what IP address(es) to listen on;
64c64
< max_connections = 100                      # (change requires restart)
---
> max_connections = 1000                     # (change requires restart)
113c113
< shared_buffers = 32MB                      # min 128kB
---
> shared_buffers = 2048MB                    # min 128kB

設定を変更します。
$ /usr/bin/sudo /usr/bin/rcsdiff /etc/config-archive/etc/postgresql-9.2/pg_hba.conf,v /etc/postgresql-9.2/pg_hba.conf
===================================================================
RCS file: /etc/config-archive/etc/postgresql-9.2/pg_hba.conf,v
retrieving revision 1.1
diff -r1.1 /etc/postgresql-9.2/pg_hba.conf
86a87
> host    all             dbuser            192.168.0.110/24        md5

とりあえずOFFにします。ONの場合安全に再起動。
$ rcsdiff -u -U4 /etc/config-archive/etc/conf.d/postgresql-9.2,v /etc/conf.d/postgresql-9.2
===================================================================
RCS file: /etc/config-archive/etc/conf.d/postgresql-9.2,v
retrieving revision 1.1
diff -u -U4 -r1.1 /etc/conf.d/postgresql-9.2
--- /etc/conf.d/postgresql-9.2  2013/08/15 08:13:01     1.1
+++ /etc/conf.d/postgresql-9.2  2013/08/16 04:21:27
@@ -12,9 +12,9 @@
 # Forecfully disconnect clients from server and shut down. This is performed
 # after NICE_QUIT. Terminated client connections have their open transactions
 # rolled back.
 # Set RUDE_QUIT to "NO" to disable. RUDE_TIMEOUT in seconds.
-RUDE_QUIT="YES"
+RUDE_QUIT="NO"
 RUDE_TIMEOUT=30

 # If the server still fails to shutdown, you can force it to quit by setting
 # this to YES and a recover-run will execute on the next startup.

plperlを入れます。
$ createlang -h 192.168.0.110 -U dbuser plperl dbname

再起動します。
$ sudo /etc/init.d/postgresql-9.2 restart

psqlで接続します。
# pgadmin3を入れて起動しておくと便利です。
$ psql -h 192.168.0.110 -U dbuser dbname

時間を計ります。
dbname=# \timing
タイミングは on です。

ランダムな文字を作成する関数を作成します。
dbname=# \x
Expanded display is on.
dbname=# SELECT prosrc FROM pg_proc WHERE proname = 'randstr';
-[ RECORD 1 ]----------------------------------------------
prosrc | # http://aoi-f.blog.so-net.ne.jp/2011-05-15
       |
       | use strict;
       |
       | my $ret = "";
       |
       | my $length = $_[0];
       |
       | my @char_tmp=();
       |
       | push @char_tmp, ('a'..'z');
       | push @char_tmp, ('A'..'Z');
       | push @char_tmp, (0..9);
       |
       | my $rand_str_tmp = '';
       | my $cnt = $#char_tmp;
       |
       | for (my $i=1; $i<=$length; $i++) {
       |     $rand_str_tmp .= $char_tmp[int(rand($cnt+1))];
       | }
       |
       | return $rand_str_tmp;
       |

Time: 2.506 ms
dbname=# \x
Expanded display is off.

テストテーブルを作成します。
dbname=# DROP TABLE test003;
DROP TABLE
時間: 5.686 ms
dbname=# CREATE TABLE test003 (id SERIAL, data VARCHAR(255));
NOTICE:  CREATE TABLEはシリアル列"test003.id"用に暗黙的なシーケンス"test003_id_seq"を作成します。
CREATE TABLE
時間: 3.490 ms
dbname=# \d test003
                              テーブル "public.test003"
  列  |           型           |                        修飾語
------+------------------------+------------------------------------------------------
 id   | integer                | not null default nextval('test003_id_seq'::regclass)
 data | character varying(255) |

テストテーブルの serial を後回しにします。
dbname=# DROP TABLE test003;
DROP TABLE
時間: 3.348 ms
dbname=# CREATE TABLE test003 (id INTEGER, data VARCHAR(255));
CREATE TABLE
時間: 2.262 ms
dbname=# CREATE SEQUENCE test003_id_seq
  INCREMENT 1
  MINVALUE 1
  MAXVALUE 9223372036854775807
  START 1
  CACHE 1;
CREATE SEQUENCE
時間: 2.420 ms
dbname=# ALTER TABLE test003_id_seq
  OWNER TO dbuser;
ALTER TABLE
時間: 0.688 ms
dbname=# ALTER SEQUENCE test003_id_seq OWNED BY test003.id;
ALTER SEQUENCE
時間: 1.429 ms
dbname=# ALTER TABLE test003 ALTER COLUMN id SET NOT NULL;
ALTER TABLE
時間: 1.396 ms
dbname=# ALTER TABLE test003 ALTER COLUMN id SET DEFAULT nextval('test003_id_seq'::regclass);
ALTER TABLE
時間: 1.994 ms
dbname=# \d test003
                              テーブル "public.test003"
  列  |           型           |                        修飾語
------+------------------------+------------------------------------------------------
 id   | integer                | not null default nextval('test003_id_seq'::regclass)
 data | character varying(255) |

10件INSERTします。
dbname=# DROP TABLE test003;
DROP TABLE
時間: 2.531 ms
dbname=# CREATE TABLE test003 (id INTEGER, data VARCHAR(255));
CREATE TABLE
時間: 2.185 ms
dbname=# INSERT INTO test003 (data) SELECT randstr((FLOOR(RANDOM()*250)+1)::INT) AS data FROM GENERATE_SERIES(1, 10);
INSERT 0 10
時間: 3.071 ms
dbname=# SELECT COUNT(data) FROM test003;
 count
-------
    10
(1 行)

時間: 0.826 ms
dbname=# SELECT LENGTH(data) AS len, COUNT(data) AS cnt FROM test003 GROUP BY len ORDER BY len ASC;
 len | cnt
-----+-----
   5 |   1
  20 |   1
  53 |   1
  54 |   1
  58 |   1
  64 |   1
  68 |   1
  82 |   1
 119 |   1
 243 |   1
(10 行)

時間: 1.192 ms

ある程度INSERTします。
dbname=# INSERT INTO test003 (data) SELECT randstr((FLOOR(RANDOM()*250)+1)::INT) AS data FROM GENERATE_SERIES(1, 100);
INSERT 0 100
時間: 11.091 ms
dbname=# INSERT INTO test003 (data) SELECT randstr((FLOOR(RANDOM()*250)+1)::INT) AS data FROM GENERATE_SERIES(1, 1000);
INSERT 0 1000
時間: 65.906 ms
dbname=# INSERT INTO test003 (data) SELECT randstr((FLOOR(RANDOM()*250)+1)::INT) AS data FROM GENERATE_SERIES(1, 10000);
INSERT 0 10000
時間: 424.606 ms
dbname=# INSERT INTO test003 (data) SELECT randstr((FLOOR(RANDOM()*250)+1)::INT) AS data FROM GENERATE_SERIES(1, 100000);
INSERT 0 100000
時間: 4210.131 ms
dbname=# INSERT INTO test003 (data) SELECT randstr((FLOOR(RANDOM()*250)+1)::INT) AS data FROM GENERATE_SERIES(1, 1000000);
INSERT 0 1000000
時間: 41347.289 ms
dbname=# SELECT COUNT(data) FROM test003;
  count
---------
 1111110
(1 行)

時間: 153.315 ms
dbname=# SELECT LENGTH(data) AS len, COUNT(data) AS cnt FROM test003 GROUP BY len ORDER BY len ASC;
 len | cnt
-----+------
   1 | 4572
   2 | 4354
   3 | 4488

... snip ...

 248 | 4435
 249 | 4477
 250 | 4445
(250 行)

時間: 2228.025 ms
dbname=# SELECT LENGTH(data) AS len, COUNT(data) AS cnt FROM test003 GROUP BY len ORDER BY len ASC LIMIT 1;
 len | cnt
-----+------
   1 | 4572
(1 行)

時間: 1860.114 ms
dbname=# SELECT LENGTH(data) AS len, COUNT(data) AS cnt FROM test003 GROUP BY len ORDER BY len DESC LIMIT 1;
 len | cnt
-----+------
 250 | 4445
(1 行)

時間: 1874.450 ms

約1000万レコードでテストに移ります。
dbname=# INSERT INTO test003 (data) SELECT randstr((FLOOR(RANDOM()*250)+1)::INT) AS data FROM GENERATE_SERIES(1, 10000000);
INSERT 0 10000000
時間: 410982.963 ms
dbname=# SELECT COUNT(data) FROM test003;
  count
----------
 11111110
(1 行)

時間: 1408.626 ms
dbname=# SELECT LENGTH(data) AS len, COUNT(data) AS cnt FROM test003 GROUP BY len ORDER BY len ASC LIMIT 1;
 len |  cnt
-----+-------
   1 | 44672
(1 行)

時間: 85998.609 ms
dbname=# SELECT LENGTH(data) AS len, COUNT(data) AS cnt FROM test003 GROUP BY len ORDER BY len DESC LIMIT 1;
 len |  cnt
-----+-------
 250 | 44174
(1 行)

時間: 87158.518 ms
dbname=#

# 非常に怪しいランダムの偏りです。 RANDOM() の使用法に誤りがあります。

serial を戻します。
dbname=# CREATE SEQUENCE test003_id_seq
  INCREMENT 1
  MINVALUE 1
  MAXVALUE 9223372036854775807
  START 1
  CACHE 1;
CREATE SEQUENCE
時間: 27.763 ms
dbname=# ALTER TABLE test003_id_seq
  OWNER TO dbuser;
ALTER TABLE
時間: 0.705 ms
dbname=# ALTER SEQUENCE test003_id_seq OWNED BY test003.id;
ALTER SEQUENCE
時間: 1.378 ms
dbname=# ALTER TABLE test003 ALTER COLUMN id SET NOT NULL;
ERROR:  列"id"にはNULL値があります
時間: 36.759 ms
dbname=# ALTER TABLE test003 ALTER COLUMN id SET DEFAULT nextval('test003_id_seq'::regclass);
ALTER TABLE
時間: 2.010 ms
dbname=# UPDATE test003 SET id=nextval('test003_id_seq'::regclass);
UPDATE 11111110
時間: 125298.068 ms
dbname=# ALTER TABLE test003 ALTER COLUMN id SET NOT NULL;
ALTER TABLE
時間: 3793.104 ms
dbname=# \d test003
                              テーブル "public.test003"
  列  |           型           |                        修飾語
------+------------------------+------------------------------------------------------
 id   | integer                | not null default nextval('test003_id_seq'::regclass)
 data | character varying(255) |

dbname=#

serial が正常か確認します。
dbname=# \d test003_id_seq
      シーケンス "public.test003_id_seq"
      列       |   型    |         値
---------------+---------+---------------------
 sequence_name | name    | test003_id_seq
 last_value    | bigint  | 11111110
 start_value   | bigint  | 1
 increment_by  | bigint  | 1
 max_value     | bigint  | 9223372036854775807
 min_value     | bigint  | 1
 cache_value   | bigint  | 1
 log_cnt       | bigint  | 13
 is_cycled     | boolean | f
 is_called     | boolean | t
所有者: public.test003.id

dbname=# SELECT id, LENGTH(data) FROM test003 ORDER BY id DESC LIMIT 2;
    id    | length
----------+--------
 11111110 |    103
 11111109 |    214
(2 行)

時間: 6080.592 ms
dbname=# INSERT INTO test003 (data) SELECT randstr((FLOOR(RANDOM()*250)+1)::INT) AS data FROM GENERATE_SERIES(1, 1);
INSERT 0 1
時間: 16.984 ms
dbname=# SELECT id, LENGTH(data) FROM test003 ORDER BY id DESC LIMIT 2;
    id    | length
----------+--------
 11111111 |     47
 11111110 |    103
(2 行)

時間: 6044.897 ms

インデックス優先にします。
dbname=# SET ENABLE_SEQSCAN = FALSE;
SET
時間: 0.382 ms

primary key を追加します。
dbname=# ALTER TABLE test003 ADD PRIMARY KEY(id);
NOTICE:  ALTER TABLE / ADD PRIMARY KEYはテーブル"test003"に暗黙的なインデックス"test003_pkey"を作成します
ALTER TABLE
時間: 13328.882 ms

dbname=# SELECT id, LENGTH(data) FROM test003 ORDER BY id DESC LIMIT 2;
    id    | length
----------+--------
 11111111 |     47
 11111110 |    103
(2 行)

時間: 1.277 ms
dbname=# SELECT id, LENGTH(data) FROM test003 ORDER BY id ASC LIMIT 2;
 id | length
----+--------
  1 |     68
  2 |    119
(2 行)

時間: 0.886 ms
dbname=# EXPLAIN SELECT id, LENGTH(data) FROM test003 ORDER BY id ASC LIMIT 2;
                                            QUERY PLAN
--------------------------------------------------------------------------------------------------
 Limit  (cost=0.00..7.78 rows=2 width=131)
   ->  Index Scan using test003_pkey on test003  (cost=0.00..43216749.91 rows=11111111 width=131)
(2 行)

時間: 0.807 ms

集約関数にindexは貼れないことを確認します。
dbname=# SELECT COUNT(data) FROM test003;
  count
----------
 11111111
(1 行)

時間: 1494.485 ms
dbname=# EXPLAIN SELECT COUNT(data) FROM test003;
                                        QUERY PLAN
------------------------------------------------------------------------------------------
 Aggregate  (cost=10000579709.89..10000579709.90 rows=1 width=127)
   ->  Seq Scan on test003  (cost=10000000000.00..10000551932.11 rows=11111111 width=127)
(2 行)

時間: 0.569 ms
dbname=# CREATE INDEX ON test003 (COUNT(data));
ERROR:  式インデックスには集約関数を使用できません
時間: 1001.837 ms
dbname=# SELECT reltuples FROM pg_class WHERE oid = 'test003'::regclass;
  reltuples
-------------
 1.11111e+07
(1 行)

時間: 1.378 ms

COUNT の書き方を試しています。
dbname=# SELECT COUNT(id) FROM test003;
  count
----------
 11111111
(1 行)

時間: 2903.467 ms
dbname=# EXPLAIN SELECT COUNT(id) FROM test003;
                                         QUERY PLAN
---------------------------------------------------------------------------------------------
 Aggregate  (cost=759916.69..759916.70 rows=1 width=4)
   ->  Bitmap Heap Scan on test003  (cost=180206.80..732138.91 rows=11111111 width=4)
         ->  Bitmap Index Scan on test003_pkey  (cost=0.00..177429.02 rows=11111111 width=0)
(3 行)

時間: 0.670 ms
dbname=# SELECT *, COUNT(*) OVER() AS cntall FROM test003 ORDER BY id DESC LIMIT 1;
    id    |                      data                       |  cntall
----------+-------------------------------------------------+----------
 11111111 | vonjFJ3RCln0ohF65zQQ5isLbe1O1AoI0QnJT4iyOGAm42t | 11111111
(1 行)

時間: 97596.188 ms
dbname=# SELECT reltuples::bigint FROM pg_class WHERE oid = 'test003'::regclass;
 reltuples
-----------
  11250615
(1 行)

時間: 9.842 ms
dbname=# explain SELECT *, COUNT(id) OVER() AS cntall FROM test003 ORDER BY id DESC LIMIT 1;
                                                   QUERY PLAN
----------------------------------------------------------------------------------------------------------------
 Limit  (cost=0.00..0.21 rows=1 width=131)
   ->  WindowAgg  (cost=0.00..2396190.51 rows=11244966 width=131)
         ->  Index Scan Backward using test003_pkey on test003  (cost=0.00..2255628.43 rows=11244966 width=131)
(3 行)

時間: 2.019 ms
dbname=# SELECT *, COUNT(id) OVER() AS cntall FROM test003 ORDER BY id DESC LIMIT 1;
    id    |                      data                       |  cntall
----------+-------------------------------------------------+----------
 11111111 | vonjFJ3RCln0ohF65zQQ5isLbe1O1AoI0QnJT4iyOGAm42t | 11111111
(1 行)

時間: 14490.027 ms

explain が変化しました。多分統計情報が集まってきたためです。
dbname=# SELECT COUNT(id) FROM test003;
  count
----------
 11111111
(1 行)

時間: 1078.204 ms
dbname=# explain SELECT COUNT(id) FROM test003;
                                            QUERY PLAN
---------------------------------------------------------------------------------------------------
 Aggregate  (cost=318660.37..318660.38 rows=1 width=4)
   ->  Index Only Scan using test003_pkey on test003  (cost=0.00..290547.96 rows=11244966 width=4)
(2 行)

時間: 0.727 ms

work_mem を確認します。
$ sudo grep work_mem /etc/postgresql-9.2/*
/etc/postgresql-9.2/postgresql.conf:#work_mem = 1MB                             # min 64kB
/etc/postgresql-9.2/postgresql.conf:#maintenance_work_mem = 16MB                # min 1MB

LENGTH(data) にインデックスを貼ります。
dbname=# SELECT LENGTH(data) AS len, COUNT(data) AS cnt FROM test003 GROUP BY len ORDER BY len DESC LIMIT 1;
 len |  cnt
-----+-------
 250 | 44174
(1 行)

時間: 125475.003 ms
dbname=# explain SELECT LENGTH(data) AS len, COUNT(data) AS cnt FROM test003 GROUP BY len ORDER BY len DESC LIMIT 1;
                                              QUERY PLAN
------------------------------------------------------------------------------------------------------
 Limit  (cost=10004819382.67..10004819382.70 rows=1 width=127)
   ->  GroupAggregate  (cost=10004819382.67..10004964150.97 rows=4834484 width=127)
         ->  Sort  (cost=10004819382.67..10004847495.09 rows=11244966 width=127)
               Sort Key: (length((data)::text))
               ->  Seq Scan on test003  (cost=10000000000.00..10000581383.08 rows=11244966 width=127)
(5 行)

時間: 0.963 ms
dbname=#

dbname=# CREATE INDEX ON test003 (LENGTH(data));
CREATE INDEX
時間: 37074.003 ms

dbname=# explain SELECT LENGTH(data) AS len, COUNT(data) AS cnt FROM test003 GROUP BY len ORDER BY len DESC LIMIT 1;
                                                      QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------
 Limit  (cost=0.00..9.07 rows=1 width=127)
   ->  GroupAggregate  (cost=0.00..43332017.17 rows=4776936 width=127)
         ->  Index Scan Backward using test003_length_idx on test003  (cost=0.00..43216749.91 rows=11111111 width=127)
(3 行)

時間: 1.398 ms

dbname=# SELECT LENGTH(data) AS len, COUNT(data) AS cnt FROM test003 GROUP BY len ORDER BY len DESC LIMIT 1;
 len |  cnt
-----+-------
 250 | 44174
(1 行)

時間: 111.031 ms
dbname=#

LIKE に似た絞込みにインデックスを貼ります。
dbname=# SELECT COUNT(data) AS cnt FROM test003 WHERE data LIKE 'a%';
  cnt
--------
 179465
(1 行)

時間: 1934.644 ms
dbname=# explain SELECT COUNT(data) AS cnt FROM test003 WHERE data LIKE 'a%';
                                       QUERY PLAN
----------------------------------------------------------------------------------------
 Aggregate  (cost=10000579991.33..10000579991.34 rows=1 width=127)
   ->  Seq Scan on test003  (cost=10000000000.00..10000579709.89 rows=112578 width=127)
         Filter: ((data)::text ~~ 'a%'::text)
(3 行)

時間: 1.167 ms
dbname=#

LIKE に似た絞込みにインデックスを貼ります。
dbname=# CREATE INDEX ON test003 (substr(data, 1, 1));
CREATE INDEX
時間: 62754.251 ms
dbname=# SELECT COUNT(data) AS cnt FROM test003 WHERE substr(data, 1, 1) = 'a';
  cnt
--------
 179465
(1 行)

時間: 3131.558 ms
dbname=# explain SELECT COUNT(data) AS cnt FROM test003 WHERE substr(data, 1, 1) = 'a';
                                          QUERY PLAN
----------------------------------------------------------------------------------------------
 Aggregate  (cost=157082.20..157082.21 rows=1 width=127)
   ->  Bitmap Heap Scan on test003  (cost=1044.03..156943.31 rows=55556 width=127)
         Recheck Cond: (substr((data)::text, 1, 1) = 'a'::text)
         ->  Bitmap Index Scan on test003_substr_idx  (cost=0.00..1030.14 rows=55556 width=0)
               Index Cond: (substr((data)::text, 1, 1) = 'a'::text)
(5 行)

時間: 1.048 ms
dbname=#

LIKE に似た絞込みにインデックスを貼ります。
dbname=# CREATE INDEX ON test003 (substr(data::text, 1, 1));
CREATE INDEX
時間: 62361.070 ms
dbname=# explain SELECT COUNT(data) AS cnt FROM test003 WHERE substr(data::text, 1, 1) = 'a';
                                          QUERY PLAN
-----------------------------------------------------------------------------------------------
 Aggregate  (cost=157082.20..157082.21 rows=1 width=127)
   ->  Bitmap Heap Scan on test003  (cost=1044.03..156943.31 rows=55556 width=127)
         Recheck Cond: (substr((data)::text, 1, 1) = 'a'::text)
         ->  Bitmap Index Scan on test003_substr_idx1  (cost=0.00..1030.14 rows=55556 width=0)
               Index Cond: (substr((data)::text, 1, 1) = 'a'::text)
(5 行)

時間: 1.409 ms
dbname=# SELECT COUNT(data) AS cnt FROM test003 WHERE substr(data::text, 1, 1) = 'a';
  cnt
--------
 179465
(1 行)

時間: 3078.055 ms
dbname=#

LIKE に似た絞込みにインデックスを貼ります。
dbname=# CREATE INDEX ON test003 (substr(data::text, 1, 2));
CREATE INDEX
時間: 65614.633 ms
dbname=# explain SELECT COUNT(data) AS cnt FROM test003 WHERE substr(data::text, 1, 2) = 'ab';
                                          QUERY PLAN
-----------------------------------------------------------------------------------------------
 Aggregate  (cost=157082.20..157082.21 rows=1 width=127)
   ->  Bitmap Heap Scan on test003  (cost=1044.03..156943.31 rows=55556 width=127)
         Recheck Cond: (substr((data)::text, 1, 2) = 'ab'::text)
         ->  Bitmap Index Scan on test003_substr_idx2  (cost=0.00..1030.14 rows=55556 width=0)
               Index Cond: (substr((data)::text, 1, 2) = 'ab'::text)
(5 行)

時間: 0.904 ms
dbname=# SELECT COUNT(data) AS cnt FROM test003 WHERE substr(data::text, 1, 2) = 'ab';
 cnt
------
 2873
(1 行)

時間: 8.811 ms
dbname=#

dbname=# SELECT COUNT(data) AS cnt FROM test003 WHERE data LIKE 'ab%';
 cnt
------
 2873
(1 行)

時間: 1856.263 ms
dbname=#

LIKE に似た絞込みにインデックスを貼ります。
dbname=# SELECT COUNT(data) AS cnt FROM test003 WHERE data LIKE 'abc%';
 cnt
-----
  48
(1 行)

時間: 1887.597 ms
dbname=# CREATE INDEX ON test003 (substr(data::text, 1, 3));
CREATE INDEX
時間: 69296.781 ms
dbname=# SELECT COUNT(data) AS cnt FROM test003 WHERE substr(data::text, 1, 3) = 'abc';
 cnt
-----
  48
(1 行)

時間: 0.988 ms
dbname=# explain SELECT COUNT(data) AS cnt FROM test003 WHERE substr(data::text, 1, 3) = 'abc';
                                          QUERY PLAN
-----------------------------------------------------------------------------------------------
 Aggregate  (cost=157082.20..157082.21 rows=1 width=127)
   ->  Bitmap Heap Scan on test003  (cost=1044.03..156943.31 rows=55556 width=127)
         Recheck Cond: (substr((data)::text, 1, 3) = 'abc'::text)
         ->  Bitmap Index Scan on test003_substr_idx3  (cost=0.00..1030.14 rows=55556 width=0)
               Index Cond: (substr((data)::text, 1, 3) = 'abc'::text)
(5 行)

時間: 1.042 ms
dbname=#

カウント数がざっくりで良い場合は使えます。
更新しなければ時間が経つと正確なカウント数が取れるかもしれません。
dbname=# SELECT reltuples::bigint FROM pg_class WHERE oid = 'test003'::regclass;
 reltuples
-----------
  11111111
(1 行)

時間: 1.109 ms

統計情報を見ます。
dbname=# select * from report_tablesize where relname like 'test003%';
       relname       | relkind |     rows     |      bytes
---------------------+---------+--------------+------------------
 test003             | r       |   11,111,111 |    3,611,205,632
 test003_id_seq      | S       |            1 |            8,192
 test003_length_idx  | i       |   11,111,111 |      249,593,856
 test003_pkey        | i       |   11,111,111 |      249,593,856
 test003_substr_idx  | i       |   11,111,111 |      249,593,856
 test003_substr_idx1 | i       |   11,111,111 |      249,593,856
 test003_substr_idx2 | i       |   11,111,111 |      249,593,856
 test003_substr_idx3 | i       |   11,111,111 |      249,593,856
(8 行)

時間: 1.175 ms

統計情報を見ます。
drop view report_tablesize;
CREATE VIEW report_tablesize AS

SELECT
  relname,
  relkind,
  to_char(reltuples, '999,999,999') as rows,
  to_char(pg_relation_size(relname::regclass), '999,999,999,999') as bytes
FROM pg_class
WHERE relnamespace = (SELECT oid FROM pg_namespace WHERE nspname='public');

COMMENT ON VIEW report_tablesize IS '現在のテーブルサイズ';

統計情報を見ます。
dbname=# select * from report_tablesize where relname like 'test003%' and relkind='i';
       relname       | relkind |     rows     |      bytes
---------------------+---------+--------------+------------------
 test003_length_idx  | i       |   11,111,111 |      249,593,856
 test003_pkey        | i       |   11,111,111 |      249,593,856
 test003_substr_idx3 | i       |   11,111,111 |      249,593,856
(3 行)

時間: 1.506 ms

COUNT をキャッシュします。
dbname=# CREATE TABLE mytablerowcount (id SERIAL, name VARCHAR(63) NOT NULL, cnt BIGINT NOT NULL);
NOTICE:  CREATE TABLEはシリアル列"mytablerowcount.id"用に暗黙的なシーケンス"mytablerowcount_id_seq"を作成します。
CREATE TABLE
時間: 46.575 ms

dbname=# ALTER TABLE mytablerowcount ADD UNIQUE (name);
NOTICE:  ALTER TABLE / ADD UNIQUEはテーブル"mytablerowcount"に暗黙的なインデックス"mytablerowcount_name_key"を作成します
ALTER TABLE
時間: 26.638 ms

COUNT をキャッシュします。
dbname=# select * from mytablerowcount;
 id |  name   | cnt
----+---------+------
 16 | test004 | 2280
(1 row)

dbname=# select get_mytablerowcount('test003');
 get_mytablerowcount
---------------------
            11111111
(1 row)

dbname=# select * from mytablerowcount;
 id |  name   |   cnt
----+---------+----------
 17 | test003 | 11111111
 16 | test004 |     2280
(2 rows)

dbname=# \timing
Timing is on.
dbname=# select get_mytablerowcount('test003');
 get_mytablerowcount
---------------------
            11111111
(1 row)

Time: 1.892 ms
dbname=# INSERT INTO test003 (data) SELECT randstr((FLOOR(RANDOM()*250)+1)::INT) AS data FROM GENERATE_SERIES(1, 10);
INSERT 0 10
Time: 403.743 ms
dbname=# select get_mytablerowcount('test003');
 get_mytablerowcount
---------------------
            11111121
(1 row)

Time: 1.805 ms

COUNT をキャッシュします。
dbname=# select * from mytablerowcount where name='test003'; select count(id) from test003; select get_mytablerowcount('test003'); SELECT reltuples::bigint FROM pg_class WHERE oid = 'test003'::regclass;
 id |  name   |   cnt
----+---------+----------
 17 | test003 | 11111121
(1 row)

Time: 0.714 ms
  count
----------
 11111121
(1 row)

Time: 1036.212 ms
 get_mytablerowcount
---------------------
            11111121
(1 row)

Time: 0.852 ms
 reltuples
-----------
  11111111
(1 row)

Time: 0.603 ms
dbname=#

COUNT をキャッシュします。
-- Function: set_mytablerowcount()

-- DROP FUNCTION set_mytablerowcount();

CREATE OR REPLACE FUNCTION set_mytablerowcount()
  RETURNS trigger AS
$BODY$

use strict;

my $res;

=pod
unless (($_TD->{event} eq "INSERT" || $_TD->{event} eq "UPDATE") &&
        ($_TD->{when} eq "BEFORE") &&
        ($_TD->{level} eq "ROW"))
{
    elog(ERROR, "CRITICAL: this call timing is invalid. (event = $_TD->{event}, when = $_TD->{when}, level = $_TD->{level})");
}
=cut

if (! defined $_SHARED{stmt_mytablerowcount}->{$_TD->{table_name}})
{
    spi_exec_query("SELECT init_mytablerowcount('" . quote_ident($_TD->{table_name}) . "')");
}

$res = spi_exec_prepared($_SHARED{stmt_mytablerowcount}->{$_TD->{table_name}}->{insert}, {limit => 1}, $_TD->{table_name});

if ($res->{processed} != 1)
{
    elog(ERROR, "affected rows != 1.");
}

return;

$BODY$
  LANGUAGE plperl VOLATILE
  COST 100;
ALTER FUNCTION set_mytablerowcount()
  OWNER TO dbuser;

COUNT をキャッシュします。
-- Function: init_mytablerowcount(text)

-- DROP FUNCTION init_mytablerowcount(text);

CREATE OR REPLACE FUNCTION init_mytablerowcount(table_name text)
  RETURNS void AS
$BODY$

use strict;

my $table_name = $_[0];

my $sql;
my $cnt;

$sql = 'SELECT cnt FROM mytablerowcount WHERE name = $1';
$_SHARED{stmt_mytablerowcount}->{$table_name}->{select} = spi_prepare($sql, 'TEXT');

$sql = 'UPDATE mytablerowcount SET cnt=cnt+1 WHERE name = $1';
$_SHARED{stmt_mytablerowcount}->{$table_name}->{insert} = spi_prepare($sql, 'TEXT');

$sql = 'UPDATE mytablerowcount SET cnt=cnt-1 WHERE name = $1';
$_SHARED{stmt_mytablerowcount}->{$table_name}->{delete} = spi_prepare($sql, 'TEXT');

$sql = 'INSERT INTO mytablerowcount (name, cnt) VALUES ($1, (SELECT COUNT(id) FROM ' . quote_ident($table_name) . '))';
$_SHARED{stmt_mytablerowcount}->{$table_name}->{init} = spi_prepare($sql, 'TEXT');

$cnt = spi_exec_prepared($_SHARED{stmt_mytablerowcount}->{$table_name}->{select},
    {limit => 1}, $table_name)->{rows}[0]->{cnt};

if (defined $cnt)
{
}
else
{
    my $res = spi_exec_prepared($_SHARED{stmt_mytablerowcount}->{$table_name}->{init}, {limit => 1}, $table_name);
}

$BODY$
  LANGUAGE plperl VOLATILE
  COST 100;
ALTER FUNCTION init_mytablerowcount(text)
  OWNER TO dbuser;

COUNT をキャッシュします。
-- Function: get_mytablerowcount(text)

-- DROP FUNCTION get_mytablerowcount(text);

CREATE OR REPLACE FUNCTION get_mytablerowcount(table_name text)
  RETURNS bigint AS
$BODY$

use strict;

my $table_name = $_[0];
my $ret = 0;
my $cnt;

if (! defined $_SHARED{stmt_mytablerowcount}->{$_TD->{table_name}})
{
    spi_exec_query("SELECT init_mytablerowcount('" . quote_ident($table_name) . "')");
}

$cnt = spi_exec_prepared($_SHARED{stmt_mytablerowcount}->{$table_name}->{select},
    {limit => 1}, $table_name)->{rows}[0]->{cnt};

if (defined $cnt)
{
    $ret = $cnt;
}

return $cnt;

$BODY$
  LANGUAGE plperl VOLATILE
  COST 100;
ALTER FUNCTION get_mytablerowcount(text)
  OWNER TO dbuser;

randstr です。
-- Function: randstr(integer)

-- DROP FUNCTION randstr(integer);

CREATE OR REPLACE FUNCTION randstr(len integer)
  RETURNS text AS
$BODY$# http://aoi-f.blog.so-net.ne.jp/2011-05-15

use strict;

my $ret = "";

my $length = $_[0];

my @char_tmp=();

push @char_tmp, ('a'..'z');
push @char_tmp, ('A'..'Z');
push @char_tmp, (0..9);

my $rand_str_tmp = '';
my $cnt = $#char_tmp;

for (my $i=1; $i<=$length; $i++) {
    $rand_str_tmp .= $char_tmp[int(rand($cnt+1))];
}
    
return $rand_str_tmp;
$BODY$
  LANGUAGE plperl VOLATILE
  COST 100;
ALTER FUNCTION randstr(integer)
  OWNER TO dbuser;

画面が一つの場合 "Ctrl + Z => fg" で戻れます。
$ psql -h 192.168.0.110 -U dbuser dbname
ユーザ dbuser のパスワード:
psql (9.2.4)
"help" でヘルプを表示します.

dbname=# ^Z
[1]+  停止                  psql -h 192.168.0.110 -U dbuser dbname
$ sudo su - -c "echo 3 > /proc/sys/vm/drop_caches"
$ fg
psql -h 192.168.0.110 -U dbuser dbname

dbname=#

random()は0.5足して四捨五入が正解かもしれません。
可能であれば更新時に数えとけば集約関数の遅さもOKです。上記の例ではdeleteしてもカウント数が減りません。余計なことをする分、更新スピードは下がります。
pgadmin3は便利です。しかし画面左側のオブジェクトブラウザのツリーが、何かの作成時などに閉じてしまうことがあるのがうざいです。
検索サイト経由でpostgresqlのマニュアルを探すとバージョンがバラバラなのでローカルに検索できる環境を用意したほうが良いです。
pgadmin3に接続しているサーバのバージョンにマッチしたマニュアルの該当項目にジャンプするような右クリックのメニューがあるといいなと思います。
昔substr(data::text, 1, 3)でインデックスを作ってdata like 'abc%'とやるとインデックスを使ったような気がしましたが気のせいです。もしくは設定です。
pl/phpは9でも使えるようですが試していません。

2013-08-13

memo: httpd.conf

ServerRoot "/usr/local/apache_mod-php"
Listen 8084
LoadModule authz_core_module modules/mod_authz_core.so
LoadModule unixd_module modules/mod_unixd.so
LoadModule php5_module        modules/libphp5.so
LoadModule xsendfile_module   modules/mod_xsendfile.so
LoadModule alias_module modules/mod_alias.so
LoadModule log_config_module modules/mod_log_config.so
LoadModule logio_module modules/mod_logio.so
User daemon
Group daemon
ServerAdmin you@example.com
ServerName vmware-gentoo1
<Directory />
    AllowOverride None
    Options None
    Require all denied
</Directory>
DocumentRoot "/usr/local/apache_mod-php/htdocs/"
ForceType application/x-httpd-php
EnableSendfile On
XSendFile on
XSendFilePath /usr/local/apache_mod-php/files/download/
<Directory "/usr/local/apache_mod-php/files/download/">
    AllowOverride None
    Options None
    Require all granted
</Directory>
Alias / /usr/local/apache_mod-php/scripts/php/index.php/
<Directory "/usr/local/apache_mod-php/scripts/php/">
    AllowOverride None
    Options None
    Require all granted
</Directory>
ErrorDocument 400 "400 Bad Request"
ErrorDocument 401 "401 Unauthorized"
ErrorDocument 402 "402 Payment Required"
ErrorDocument 403 "403 Forbidden"
ErrorDocument 404 "404 Not Found"
ErrorDocument 405 "405 Method Not Allowed"
ErrorDocument 406 "406 Not Acceptable"
ErrorDocument 407 "407 Proxy Authentication Required"
ErrorDocument 408 "408 Request Timeout"
ErrorDocument 409 "409 Conflict"
ErrorDocument 410 "410 Gone"
ErrorDocument 411 "411 Length Required"
ErrorDocument 412 "412 Precondition Failed"
ErrorDocument 413 "413 Request Entity Too Large"
ErrorDocument 414 "414 Request-URI Too Long"
ErrorDocument 415 "415 Unsupported Media Type"
ErrorDocument 416 "416 Requested Range Not Satisfiable"
ErrorDocument 417 "417 Expectation Failed"
ErrorDocument 500 "500 Internal Server Error"
ErrorDocument 501 "501 Not Implemented"
ErrorDocument 502 "502 Bad Gateway"
ErrorDocument 503 "503 Service Unavailable"
ErrorDocument 504 "504 Gateway Timeout"
ErrorDocument 505 "505 HTTP Version Not Supported"
ErrorLog "logs/error_log"
LogLevel warn
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O \"%{id}n\" \"%{time}n\"" combinedio
CustomLog "logs/access_log" combinedio
ServerTokens ProductOnly
StartServers             3
MinSpareThreads        750
MaxSpareThreads        750
ThreadsPerChild        250
MaxRequestWorkers      750
MaxConnectionsPerChild 25000
ServerLimit              3
ThreadLimit            750
MaxKeepAliveRequests   500
KeepAlive               On
KeepAliveTimeout         3
ListenBacklog        65535

// sample. \"%{id}n\" \"%{time}n\"
// auto_prepend_file etc.
{
    function microtime_float()
    {
        list($usec, $sec) = explode(" ", microtime());
        return ((float)$usec + (float)$sec);
    }
    register_shutdown_function(function ($timeStart) {
            apache_note("time", sprintf("%.5f", microtime_float() - $timeStart));
            apache_note("id", mydb::getuid());
        }, microtime_float());
}
// dummy.
class mydb
{
    static function getuid()
    {
        return "dummy-" . substr(md5(microtime()), 0, 8);
    }
}

/manual/をindex.phpでは無いアクセスにする場合。
# なにかが必要。
LoadModule xxx_module   modules/mod_xxx.so
# Alias / の前に書く。
Alias /manual/ /usr/local/apache_mod-php/manual/
<Directory "/usr/local/apache_mod-php/manual/">
    AllowOverride None
    Options None
    Require all granted
    ForceType None
</Directory>

...

Alias / /usr/local/apache_mod-php/scripts/php/index.php/