リリース日:2002/02/04
掲載日:2002/02/04
例: CREATE TABLE t1(i INTEGER) WITHOUT OIDS;
select timestamp(date '1998-02-24', time '23:07');
はエラーになります.代りに以下の記法を使ってください.
select "timestamp"(date '1998-02-24', time '23:07');
select timestamptz(date '1998-02-24', time '23:07');
select (date '1998-02-24' + time '23:07');
例:
VACUUM FULL;
例:
ANALYZE;
PostgreSQLでは,すべてのトランザクションにトランザクションID(XID)と いう連番の数字が割り当てられています.この数字は32ビットの整数で表 され,最大値は2の32乗,すなわち約42億です.一方,PostgreSQLではMVCC を採用しており,ある行の「バージョン」をこのXIDで識別します.すなわ ち,現在のトランザクションT1のXIDがXである場合,T1から見える行は, XID が X以下であることが条件となります.Xより大きなXIDを持つ行は, T1よりも新しいトランザクションが生成したものと見なし,T1からは見え ません.
もしもXIDが2の32乗を超えるとどうなるでしょう.XIDは0になり,再びそ こからカウントを開始します.その結果,新しいトランザクションから見 ると,ほとんどの行は自分よりも大きなXID持っているので不可視になってし まいます.つまり突然データが消えたように見えるのです.
この問題を解決するために導入されたのが"FrozenXID"です.FrozenXIDは 値が2の特別なXIDで,このXIDは他のどんなXIDよりも「古い」と見なされ ます(この他,値が1の特別なXIDがあり,これも同様です).普通にVACUUM をかけると,現在よりも10億よりも過去のXIDを持つ行が"FREEZE"され, XIDとして2がアサインされます.FREEZEされた行は,以後トランザクショ ンIDが0を回ってしまっても安全です.ただし,現在のXIDから遡って10億 過去までのXIDを持つ行はFREEZEされていませんから,いずれはVACUUMをか けてFREEZEする必要があります.この目安とするために,pg_databaseに datfrozenxidという列が追加されました.FREEZEされた最大のXIDがここに 格納されます.datfrozenxidと現在のXIDの差が15億よりも広がったら VACUUMをかけることが推奨されており,そのためにageという関数が提供さ れています.
例:
SELECT datname, age(datfrozenxid) FROM pg_database;
datname | age
-----------+------------
test | 41
test2 | 1073741946
template1 | 490
template0 | 490
(4 rows)
御覧のように,"test2"というDBは現在ageが約10億7千万ですので,後4億
2千万トランザクションほど余裕があることになります.うっかりVACUUMを
忘れるのを防止するために,VACUUMは,ageが15億を超えると警告を出しま
す.
lay=# vacuum;
NOTICE: Some databases have not been vacuumed in 1613770184 transactions.
Better vacuum them within 533713463 transactions,
or you may have a wraparound failure.
VACUUM
さらに完璧にFREEZEするために,VACUUM FREEZEというオプションがありま
す.VACUUM FREEZEを実行すると,トランザクション処理中でないすべての
行のXIDが2にセットされます.
| 文字コード | PostgreSQLでのエンコーディング名称 | 別名 | 7.2で追加 |
|---|---|---|---|
| ISO-8859-1 | LATIN1 | ISO_8859_1 | |
| ISO-8859-2 | LATIN2 | ISO_8859_2 | |
| ISO-8859-3 | LATIN3 | ISO_8859_3 | |
| ISO-8859-4 | LATIN4 | ISO_8859_4 | |
| ISO-8859-5 | ISO_8859_5 | ☆ | |
| ISO-8859-6 | ISO_8859_6 | ◯ | |
| ISO-8859-7 | ISO_8859_7 | ◯ | |
| ISO-8859-8 | ISO_8859_8 | ◯ | |
| ISO-8859-9 | LATIN5 | ISO_8859_9 | ☆ |
| ISO-8859-10 | LATIN6 | ISO_8859_10 | ◯ |
| ISO-8859-13 | LATIN7 | ISO_8859_13 | ◯ |
| ISO-8859-14 | LATIN8 | ISO_8859_14 | ◯ |
| ISO-8859-15 | LATIN9 | ISO_8859_15 | ◯ |
| ISO-8859-16 | LATIN10 | ISO_8859_16 | ◯ |
☆ 7.1までは"LATIN5"はISO-8859-5に対応していましたが,実はこれは正 しい対応ではないことが分かったため,7.2からはLATIN5=ISO-8859-9に 変更されています.
dynamic_library_path = '/usr/local/lib/postgresql:/home/my_project/lib:$libdir'
例:
LOCK t1, t2, t3;
例:
CREATE foo USER ENCRYPTED PASSWORD 'mypassword';
これにともない,pg_hba.confに"md5"というキーワードが追加されていま
す.使用例:
host template1 192.168.12.10 255.255.255.255 md5
SELECT SESSION_USER, CURRENT_USER;
current_user | session_user
--------------+--------------
peter | peter
SET SESSION AUTHORIZATION 'paul';
SELECT SESSION_USER, CURRENT_USER;
current_user | session_user
--------------+--------------
paul | paul
test=# CREATE TABLE t1(d TIME(2));
CREATE
test=# INSERT INTO t1 VALUES(CURRENT_TIME);
INSERT 116742 1
test=# SELECT * FROM t1;
d
-------------
15:11:34.05
(1 row)
DECLARE
...
curname CURSOR [(argname type [, ...])]
IS ;
...
BEGIN
...
OPEN curname [(expr [, ...])];
...
REFCURSORはカーソルに対応するデータ型です.REFCURSORはデータ型な
ので,関数の引数や関数の戻値に使えます.
DECLARE
...
varname REFCURSOR [:= カーソル名];
...
REFCURSORは以下のように開きます.
BEGIN
...
OPEN varname FOR ;
-- or
OPEN varname FOR EXECUTE ;
...
関数の戻値をREFCURSOR
にすることよって,複数の行を返す関数をPL/pgSQLで作ることができます.
CREATE OR REPLACE FUNCTION reftest() RETURNS REFCURSOR AS ' DECLARE ret REFCURSOR := ''r1''; BEGIN OPEN ret FOR SELECT * FROM t1; RETURN ret; END; ' LANGUAGE plpgsql; BEGIN; SELECT reftest(); FETCH r1; END;カーソルは以下のように使います.
BEGIN
...
FETCH cursorvar INTO {record | row | var [, ...]};
...
CLOSE cursorvar;
カーソルを使ったループ.
BEGIN
OPEN myrefcur FOR SELECT * FROM mytab;
LOOP
FETCH myrefcur INTO myrow;
EXIT WHEN NOT FOUND;
-- Process one row
END LOOP;
CLOSE myrefcur;
29621 ttyp0 S 0:00 postgres: stats buffer process
29623 ttyp0 S 0:00 postgres: stats collector process
この2本が,パフォーマンス情報を収集するプロセスです.実際にこの
プロセスに情報を収集させるには,postgresql.confの以下のフラグを
trueにする必要があります.
test=# select * from pg_stat_activity;
datid | datname | procpid | usesysid | usename | current_query
-------+---------+---------+----------+---------+------------------------------------------------------------------
16556 | test | 6229 | 1 | t-ishii | update branches set bbalance = bbalance + 19 where bid = 1
16556 | test | 6230 | 1 | t-ishii | update branches set bbalance = bbalance + 576 where bid = 1
16556 | test | 6231 | 1 | t-ishii | select abalance from accounts where aid = 49892
16556 | test | 6232 | 1 | t-ishii | <IDLE>
16556 | test | 6233 | 1 | t-ishii | end
16556 | test | 6234 | 1 | t-ishii | update accounts set abalance = abalance + 669 where aid = 5572
16556 | test | 6235 | 1 | t-ishii | update accounts set abalance = abalance + 520 where aid = 53106
16556 | test | 6236 | 1 | t-ishii | select abalance from accounts where aid = 50896
16556 | test | 6237 | 1 | t-ishii | <IDLE>
16556 | test | 6238 | 1 | t-ishii | update tellers set tbalance = tbalance + 548 where tid = 5
16556 | test | 6240 | 1 | t-ishii | <IDLE>
(11 rows)
test=# select * from pg_stat_sys_tables where relname = 'pg_am'; -[ RECORD 1 ]-+------ relid | 16396 relname | pg_am seq_scan | 17 seq_tup_read | 17 idx_scan | 0 idx_tup_fetch | 0 n_tup_ins | 0 n_tup_upd | 0 n_tup_del | 0
test=# select * from pg_statio_sys_tables where relname = 'pg_am'; -[ RECORD 1 ]---+------ relid | 16396 relname | pg_am heap_blks_read | 1 heap_blks_hit | 16 idx_blks_read | 0 idx_blks_hit | 0 toast_blks_read | toast_blks_hit | tidx_blks_read | tidx_blks_hit |
test=# CREATE INDEX pindex ON history(tid) WHERE tid BETWEEN 4 AND 6;これで,tidが4,5,6だけの部分インデックスが作られます.tidがこの値をはずれ るような検索では,
test=# EXPLAIN SELECT * FROM history WHERE tid = 8; NOTICE: QUERY PLAN: Seq Scan on history (cost=0.00..203.57 rows=49 width=50) EXPLAIN御覧のようにインデックスは使われません. それに対して,tid = 4の検索では,
test=# EXPLAIN SELECT * FROM history WHERE tid = 4; NOTICE: QUERY PLAN: Index Scan using pindex on history (cost=0.00..5.99 rows=49 width=50) EXPLAINインデックスが使われます.