餅が・・・
PostgreSQL8.1.3のDBで、LIKE検索がヘンなマッチをしたときがありました。
たとえば、、、
CREATE TABLE test (name1 text);
INSERT INTO test VALUES('北澤');
SELECT * from test
WHERE name1 LIKE '%餅%';
とやったら、「北澤」が引っかかる状態です。
はて?と思い、それぞれの文字コードを調べてみると
北(CBCC)澤(DFB7)
一方、餅くんは
餅(CCDF)
なので、どうやら北の後ろと澤の前のバイトでマッチしてる様子。
ということは・・・と思って
psql -l
してみると、
| Name | Owner | Encoding |
| hogehoge | hogehoge | SQL_ASCII |
(ノ∀`) アチャー
通常はconfigure時かcreatedb時に文字エンコーディングをセットしますが、それを忘れていたのですね。
エンコーディングがセットされてなくても、日常的に使っている分には問題が起きにくいので、なかなか気づきにくいのかもしれません。
PostgreSQLで手っ取り早くサイズを調べたい
一つのPostgreSQLの中に、いくつかのデータベースを入れていた場合、各サイズを調べるのは意外に面倒なので、以下のようなPHPスクリプトで、ちょいちょいと見ることがあります。
なんか異常に肥大してるけど、どいつが悪さしてんだYo!!というときにでも、お使い下さいませ。
pg_database_sizeなど、PostgreSQL8.1以上の関数を使ってますが、それ以下のバージョンでもcontribで入るdbsizeを使えば同じようなことはできると思います。未検証ですが。。。
あとPEAR::DBを使っていますので、使えない方は適宜読み替えて下さい(・ω・;)
require_once("DB.php");
$db_user = "postgres";
$db_pw = "hogehoge";
$db_ip = "192.168.0.***";
$db_name = "template1";
$dsn = "pgsql://${db_user}:${db_pw}@${db_ip}/${db_name}";
$conn = DB::connect($dsn);
$result = getDbSize($conn);
print_R($result);
$result = getTableSize($conn);
print_R($result);
function getDbSize(&$conn){
$sql = "SELECT datname FROM pg_database";
$arrDb = $conn->getAll($sql,DB_FETCHMODE_ASSOC);
if ( $arrDb ){
foreach($arrDb as $data){
$sql = "SELECT pg_database_size(?) as size, pg_size_pretty(pg_database_size(?)) as disp_size";
$result = $conn->getAll($sql, array($data["datname"], $data["datname"]), DB_FETCHMODE_ASSOC);
$return[$result[0]["size"]] = array("size"=>$result[0]["disp_size"], "db_name"=>$data["datname"]);
}
}
krsort($return);
return $return;
}
function getTableSize(&$conn){
$sql = "SELECT
relname
FROM
pg_class
WHERE
relkind='r' AND
relname not in (SELECT
c.relname
FROM
pg_class c,
pg_rewrite r
WHERE
(r.ev_class = c.oid) AND
(r.ev_type = '1')
GROUP BY
relname
)
AND relname !~ '^sql_'
AND relname !~ '^pg_'
ORDER BY
relname";
$arrDb = $conn->getAll($sql, DB_FETCHMODE_ASSOC);
if ( $arrDb ){
foreach($arrDb as $data){
$sql = "SELECT pg_total_relation_size(?) as size, pg_size_pretty(pg_total_relation_size(?)) as disp_size";
$result = $conn->getAll($sql, array($data["relname"], $data["relname"]), DB_FETCHMODE_ASSOC);
$return[$result[0]["size"]] = array("size"=>$result[0]["disp_size"], "name"=>$data["relname"]);
}
}
krsort($return);
return $return;
}
「PostgreSQLは充分成熟」なのかを考える
今更な話ですが、6月5日に開催された『PostgreSQLカンファレンス2007』に参加してきました。
講演メンバーもかなり豪華で、PostgreSQL開発コアメンバーのJosh Berkus氏、日本PostgreSQLユーザ会会長の片岡裕生氏、スターロジックCEOの羽生章洋氏といった方々の講演を聞かせて頂きました。
様々なセッションの中には、PostgreSQLの今後について考えるセッションもあり、その様子がITproやZDNetに紹介されています。
PostgreSQL 8.3は"あのDBMS"よりも速くなる
PostgreSQLは充分成熟--今後必要なのは周辺ツール
PostgreSQLは、以前から「商用データベースに遜色ない」データベースシステムとして高く評価されてきたが、やはりそこには「オープンソースでありながら」とか、「フリーソフトウェアにも関わらず」といった但し書きが付けられるのが常であった。しかし、十分豊富な機能を持ち、なおかつバージョンアップ毎に性能面の改善が達成されている現状では、もはやこれらの但し書きも不要なほど、PostgreSQLは成熟したと言えるだろう。
仕事では常にPostgreSQLにお世話になっていますが、このカンファレンスに参加することで、PostgreSQLの凄さなんかを知ることができたと思います。
しかし、MySQLに比べると、人気アプリケーションへの採用数が少ないとか、レンタルサーバのサービスメニューとして提供されないとか、いつも不思議に感じていました。
今回は、その理由について考えたいと思います。
レンサバ事業者の観点からすると、一番問題なのは、データベースのファイル占有量が不明である点ではないでしょうか。
レンサバ事業者は、共用レンサバの場合、メールやウェブなどユーザの占有できるディスク容量に制限を設けています。
Aコースは300MB、Bコースは1GBとかです。
当然、データベース容量もコントロールしたいかと思います。
MySQLは、ファイル占有量が簡単なSQLコマンドで分かるようになっています。
PostgreSQLでは、ソースコードを入手すれば、データベースサイズを調べるユーティリティコマンドがオプションで付いてくるのですが、自分でコンパイル/インストールしなければなりません。
最初からSQLコマンドとして組み込まれているMySQLと比べて、なんとも面倒です。
レンタルサーバで使えなければ、アプリケーションでも採用されない。
アプリケーションに使われなければ、レンタルサーバでも提供されない。
みたいな悪循環があるのかなぁと考えます。
「PostgreSQLはカスタムアプリ組込用に使うから、メジャーなソフトに対応しなくても問題無い。」 という意見も有りそうですが…。
いつも使う者としては、もっとメジャーになってくれると嬉しいです。
pgpoolについて
こんにちは。
PostgreSQL専用のコネクションプーリング・ソフトウェアであるpgpoolですが、やっかいな問題があります。
それは、「クライアントから接続を中断されたときに、そのコネクションが残り続けること」です。
その状態が連続すると、pgpoolがハングアップし、pgpoolのポートへの接続ができなくなります。
例えば、5433番ポートでpgpoolを動かしているとすると、
$ psql -l -p 5433
と入力しても、応答が全く帰ってきません。
また、この時
$ psql -l
は、応答がかえってきます。
postgresには直接接続できるということです。
特に高負荷時、クライアント側でコネクションタイムアウト処理が行われるときに発生しやすいように思います。
この問題は、pgpoolのパラメータであるconnection_life_timeを使うことで、アイドル状態のコネクションを解放できることは確認できましたが、高負荷な場合には意味をなさないようです。
また、pgpool3.3を使用していた頃、3.4がリリースされてChangeLogを見たところ、そのあたりに関係しそうなことが記載されていて、pgpool3.4にアップデートしましたが状況は変わらずでした。
クライアント側のコネクションタイムアウト処理は変えずに、pgpoolの設定のみで対応する方法としましては、実メモリとpostgresql.confのmax_connection値の範囲内で、num_init_childrenを増やせば、同現象が起こる可能性は低くなります。
(理論的にはその分max_pool値は低く設定しなければパフォーマンスは低下するので、高負荷にはなりますが、要は、ある親プロセスに紐づく子プロセスを使い切らないようにすることがポイントかと)
話は変わって、パラメータのlogdirですが、/tmp以外に変更されることをお勧めします。
pidファイルもここに格納されるようになっていますが、Linuxはtmpwatchなどで/tmp以下を自動で削除する仕組みになっていますので。
もし万が一pidファイルを消失してしまった場合は、pgpoolの起動、停止ができません。
その場合、親プロセスからプロセスIDを調べて、noeolバイナリーでpgpool.pidファイルを作成します。
viモードで「:set bin noeol」で、保存します。
おそらくpgpoolを使用されている方も多いと思い、いろいろと気になる現象を挙げてみました。
同様の現象に心当たりのある方はおられますでしょうか。