MariaDB/MySQL C client libraryまとめ

ちょっと勘違いしていたので、まとめ。

(2014.12.3追記:以下の書籍にも記述した。)


プロトコルバージョン

まず、プロトコルから。(少なくとも)MySQL 5.0.20以前から、プロトコルバージョンは"10"。

MySQL 5.6.3xもMariaDB 10.0.11も、プロトコルバージョンは10。

なので、ver5.0のmysqlクライアントでMySQL5.6サーバやMariaDB 10.0に接続なんてことができる。

ソースコードにバンドルされてるクライアントライブラリと、ライセンス

MySQLソースコードには、当然クライアントライブラリのソースも含まれ、ライセンスはGPL

MariaDBソースコードに含まれるクライアントライブラリはMySQLのforkで、やはりGPL。ここ、勘違いしてた。


MariaDBのクライアントライブラリはLGPL」というのは「別途、Cのクライアントライブラリを提供している」ということなので注意。

libmysqlclient.so

共有ライブラリlibmysqlclient.soは、5.0でのlibmysqlclient.so.15から徐々にナンバリングが上がり、MySQL5.6/MariaDB 10.0ではlibmysqlclient.so.18。

ソースコードからインストールすると、MySQL5.6/MariaDB 10.0ではlibmysqlclient.so.18だけど、MySQL/MariaDBの公式リポジトリからパッケージでserver/client/common/compatをインストールすると、少し古めのものが入る。
MySQL/MariaDB-shared-XXXX.rpmで最新版が入る感じ。何故かは分からない。

これらのライセンスはGPLLGPLじゃない。


念のため。上にも書いたように、これらのプロトコルバージョンはすべて"10"。

MariaDBが提供するLGPLのクライアントライブラリ

ということで、LPGLのクライアントライブラリを使いたいときは、ここからダウンロードしなければならない。

因みに、このライブラリのプロトコルバージョンも"10"である。


mysqlクライアント

これも思い込みで、libmysqlclient.soを呼んでると思ったら、じつはlibmysqlclient.aをstatic linkしていた。

MariaDB 10.0 GA記念 ダイナミックカラムって何?

(2014.12.3追記:以下の書籍にも記述した。)

(2014.4.16)微妙に反応があるので、PostgreSQLネタ追記。

PostgreSQLには古くから配列型複合型というのがあって、似たようなことができる。
あと、MariaDBのダイナミックカラムをJSONで取り出すcolumn_jsonなんてのもあるが、PostgreSQLはネイティブなデータ型としてJSON型があるので、わざわざBLOBを使わずとも、最初からJSON型でデータ処理できる。

そもそも、こんな感じで自由にデータ型も追加できたりと、中の作りはPostgreSQLのほうが圧倒的に出来が良い。

以下、本文。


MariaDB 5.3で導入されたダイナミックカラムという機能が、MariaDB 10.0でかなり使いやすくなった*1

これは、BLOB型のカラムの内部を独自フォーマットで分割し、一つのカラムに複数のデータを格納する機能である。分割する個数は後から自由に変更できるのでダイナミック(動的)と名付けられている。

具体例をみるのが最も分かりやすいので、以下に簡単な例を示す。



テーブルdynamic_col_testを作成して、データをインサートする。ダイナミックカラムとして使うカラムにはBLOB型を指定。


データをインサートする際、ダイナミックカラム型のカラムには関数COLUMN_CREATE()を使うところがこの機能のキーポイント。この関数によってBLOB型内部を独自フォーマットで分割してデータを格納する。

MariaDB [sampledb]> CREATE TABLE dynamic_col_test (id int, dynamic_col blob);
Query OK, 0 rows affected (1.48 sec)

MariaDB [sampledb]> INSERT INTO dynamic_col_test
   ->        VALUES (1, COLUMN_CREATE('name', 'Alice', 'color', 'red'));
Query OK, 1 row affected (0.54 sec)

MariaDB [sampledb]> INSERT INTO dynamic_col_test
   ->        VALUES (1, COLUMN_CREATE('name', 'Bob', 'color', 'blue'));
Query OK, 1 row affected (0.23 sec)


ダイナミックカラムの内部データを取り出す場合には関数COLUMN_GET()を使う。

MariaDB [sampledb]> SELECT id, COLUMN_GET(dynamic_col, 'name' as char) as name
   ->                                                       FROM dynamic_col_test;
+------+-------+
| id   | name  |
+------+-------+
|    1 | Alice |
|    2 | Bob   |
+------+-------+
2 rows in set (0.00 sec)

ダイナミックカラムの項目を追加するには、次のようにする。

MariaDB [sampledb]> UPDATE dynamic_col_test SET dynamic_col = COLUMN_ADD(dynamic_col, 'age', 27)
   ->                            WHERE id = 1;
Query OK, 1 row affected (0.44 sec)
Rows matched: 1  Changed: 1  Warnings: 0

MariaDB [sampledb]> UPDATE dynamic_col_test SET dynamic_col = COLUMN_ADD(dynamic_col, 'age', 26)
   ->                            WHERE id = 2;
Query OK, 1 row affected (0.20 sec)
Rows matched: 1  Changed: 1  Warnings: 0


MariaDB [sampledb]> SELECT id, COLUMN_GET(dynamic_col, 'age' as int) as age
   ->                            FROM dynamic_col_test;
+------+-----+
| id   | age |
+------+-----+
|    1 |  27 |
|    2 |  26 |
+------+------+
2 rows in set (0.07 sec)

このようにダイナミックカラムは、COLUMN_XXXという関数を介してBLOB型で格納したデータを操作する。この仕組みから明らかなように、ダイナミックカラムで格納した項目についてインデックスを張ることはできない。


使い勝手のよいキーバリューストアとして使うとよいかも。普通のテーブルとJOINできる訳だし。


詳細はこちらを参照。チュートリアル風に使い方を説明している。

*1:5.3ではカラムを指定する場合に数字しか使えなかった。何番目のデータとか。10.0で内部のカラムに名前をつけることができるようになった。

MariaDB 10.0 GA記念 並列レプリケーションって何?

2014年3月末にMariaDB 10.0.10 GAがリリースされて、並列レプリケーション(Parallel replication)が目玉の1つっぽく書かれているので、簡単に解説。(2014.12.3追記:以下の書籍にも記述した。)


並列レプリケーションとはスレーブ側の機能で、従来はSQLスレッド1つで処理していたrelayログの再生を、複数のスレッドで並列に処理しようというもの。


MySQLにもパラレルworkerという機能があるが、MariaDBのそれとは並列化の粒度が全く異なる。(注:MySQL5.7でMariaDBと同レベルの機能が実装された。)


MariaDBのマスタがコミットしてバイナリログを書く際に、並列実行できるかどうかをバイナリログに書き込んでいる。スレーブはそれに応じて、並列に実行できるSQLは並列に実行する。
具体例をみてみよう。
マスタでbinlog_commit_wait_countとbinlog_commit_wait_usecに適当な値を設定した時の、バイナリログの内容を示す。

.. 略 ...

#140312 10:20:07 server id 1  end_log_pos 1045  GTID 1-1-1262369
BEGIN
# at 1045
UPDATE test1 SET id = 2 WHERE id = 2
# at 1148
COMMIT
# at 1221
#140312 10:20:07 server id 1  end_log_pos 1261  GTID 1-1-1262370 cid=472342
BEGIN
# at 1261
UPDATE test1 SET id = 3 WHERE id = 3
# at 1364
COMMIT
# at 1437
#140312 10:20:07 server id 1  end_log_pos 1477  GTID 1-1-1262371 cid=472342
BEGIN
# at 1477
UPDATE test3 SET id = 1 WHERE id = 1
# at 1580
COMMIT
# at 1653
#140312 10:20:07 server id 1  end_log_pos 1693  GTID 1-1-1262372 cid=472342
BEGIN
# at 1693
UPDATE test2 SET id = 1 WHERE id = 1
# at 1796
COMMIT
# at 1869
#140312 10:20:08 server id 1  end_log_pos 1907  GTID 1-1-1262373
BEGIN
# at 1907
UPDATE test1 SET id = 3 WHERE id = 3

... 略 ...


ここで3つのUPDATE文に、GTIDとともに、"cid=472342"という値が付与されている。
この3つのUPDATE文をよくみると、実行時刻はほぼ同時で、テーブルはそれぞれtest1,test3,test2とバラバラなことがわかる。よって、スレーブはこの3つのUPDATE文を並列に実行できる。
もちろん、マスタは全てのSQLを並列化するのではなく、パラメータで設定した時間(何10〜何100ミリ秒とか)内で並列化できるSQLにだけ、cidを割り当てる。

こんな感じで、MariaDBの並列レプリケーションはマスタとスレーブの協調作業だが、どちらかというとスレーブよりもマスタのほうが賢い。


これに対して、MySQL5.6のスレーブはデータベース毎に並列に実行するだけである。だからMySQLのマスタ側は何も考えない。スレーブがデータベース毎にrelayログの内容を分散してworkerが並列に実行する。

容易にわかるようにMySQL5.6までは、スレーブの並列性?はMariaDBと比較して著しく劣る。
MySQL 5.7で同レベルの機能が実装された。

溜まったアーカイブログを削除する

表題とおり、溜まったアーカイブログを削除するスクリプト*1。ここまでやる意味があるかどうかは別として。


commitやabortした時刻はWALログに記録されているので、pg_xlogdumpを使って「X日以前のWALアーカイブを削除する」スクリプトを書いた。


動作はpg_xlogdumpの表示フォーマットに依存しているので、バージョンが変わる毎に動作確認が必要。このスクリプトver9.3依存。
因みに依存している部分はawkで日時をひろう部分。"$17"とハードコーディングしている。

#!/bin/bash

## NDAYS以前のWALログを削除
NDAYS=3
## pg_xlogdump
PG_XLOGDUMP=/usr/local/pgsql/bin/pg_xlogdump
## アーカイブログを保存するディレクトリ
WAL_ARCHIVES=/home/postgres/wal_archives

declare -i TARGET_DATE DATE
TARGET_DATE=`/bin/date  '+%Y%m%d' --date "$NDAYS days ago"`

for timeline in $( ls $WAL_ARCHIVES/* | awk -F/ '{print $NF}' | \
    cut -c 1-8 | sort | uniq ); do
    CHECK_MODE="ON"
    for file in $( ls $WAL_ARCHIVES/${timeline}* | \
        grep '[0-9A-F]$'| sort -r ) ; do
        if [ $CHECK_MODE = "OFF" ]; then
            rm -f $file
        else
            seg=`echo $file | awk -F/ '{print $NF}'`
            DATE=`$PG_XLOGDUMP -r Transaction -p $WAL_ARCHIVES $seg $seg  | \
                 grep 'commit' |awk '{print $17}' |sed s/-//g | head -1 2>/dev/null`
            if [ $? -eq 0 -a $DATE -lt $TARGET_DATE ]; then
                rm -f $file
                CHECK_MODE="OFF"
            fi
        fi
    done
done
exit 0


ま、もっと簡単で(ほぼほぼ)合理的なのはfindを使うこれ、と思うけども...

postgres> find /home/postgres/wal_archives -mtime +3 -exec rm  -f {} \;

*1:pg_archivecleanupもあるけども、これは明示的にWALセグメントを指定しなければならないので、cronで自動的に削除するときには使えない。

pg_rmanの挙動

追記(2014.02.19):バグのようです。1.2.2から紛れ込んだ模様。開発者に連絡してもらったので、そのうち直るでしょう


ドキュメントと違う挙動をしているように見える。
私の解釈が間違っているのか、使い方が間違っているのか?

ドキュメントの記述を抜粋。

  1. archive mode(アーカイブWAL): アーカイブWALのみのバックアップ
  2. incremental mode(増分バックアップ): 最新の検証済みバックアップの開始以降に変更のあったファイル・ページのみをバックアップします。


だけど、手元環境ではどちらもまったく同じで、アーカイブWALと変更ファイルの両方が保存される

基本データ

実験環境。

pg_rman 1.2.7

因みに1.2.0も1.2.3も同じだった。

[postgres@localhost ~]$ env | grep BACKUP_PATH
BACKUP_PATH=/home/postgres/backup_archives

[postgres@localhost ~]$ cat $BACKUP_PATH/pg_rman.ini

ARCLOG_PATH='/home/postgres/wal_archives'
postgresql 9.3.0

postgresql.conf

wal_level = hot_standby
archive_mode = on
archive_command = 'cp %p /home/postgres/wal_archives/%f'

log_destination = 'stderr'
logging_collector = on

archive modeの挙動

まずはarchiveモード。

[postgres@localhost ~]$ pg_rman backup --backup-mode=archive -D /usr/local/pgsql/data/ -d template1
[postgres@localhost ~]$ pg_rman validate

[postgres@localhost ~]$ pg_rman show
============================================================================
Start                Time   Total    Data     WAL     Log  Backup   Status  
============================================================================
2014-02-18 04:15:43    0m    ----    ----    33MB    ----    33MB   OK
2014-02-18 04:00:13    0m    27MB    ----    83MB    ----   109MB   OK

ドキュメントから期待するのは、archive log領域だけコピーしてくるだけども、データベースクラスタの(更新された)テーブルデータファイルもコピーしている。

[postgres@localhost ~]$ find backup_archives/20140218/041543/
backup_archives/20140218/041543/
backup_archives/20140218/041543/arclog
backup_archives/20140218/041543/arclog/000000010000000000000007
backup_archives/20140218/041543/arclog/000000010000000000000006
backup_archives/20140218/041543/arclog/000000010000000000000007.00000028.backup
backup_archives/20140218/041543/backup.ini
backup_archives/20140218/041543/database
backup_archives/20140218/041543/database/base
backup_archives/20140218/041543/database/base/16384
backup_archives/20140218/041543/database/base/16384/16385 <== このファイルが何故、バックアップされるのか?
backup_archives/20140218/041543/database/base/12891
backup_archives/20140218/041543/database/base/12896
backup_archives/20140218/041543/database/base/1
backup_archives/20140218/041543/database/pg_twophase
backup_archives/20140218/041543/database/pg_log
backup_archives/20140218/041543/database/pg_notify
backup_archives/20140218/041543/database/pg_snapshots
backup_archives/20140218/041543/database/pg_tblspc
backup_archives/20140218/041543/database/pg_tblspc/16388
backup_archives/20140218/041543/database/pg_tblspc/16388/PG_9.3_201306121
backup_archives/20140218/041543/database/pg_tblspc/16388/PG_9.3_201306121/16384
backup_archives/20140218/041543/database/pg_multixact
backup_archives/20140218/041543/database/pg_multixact/members
backup_archives/20140218/041543/database/pg_multixact/offsets
backup_archives/20140218/041543/database/global
backup_archives/20140218/041543/database/global/pg_control
backup_archives/20140218/041543/database/pg_xlog
backup_archives/20140218/041543/database/pg_serial
backup_archives/20140218/041543/database/backup_label
backup_archives/20140218/041543/database/pg_subtrans
backup_archives/20140218/041543/database/pg_stat
backup_archives/20140218/041543/database/pg_stat_tmp
backup_archives/20140218/041543/database/pg_clog
backup_archives/20140218/041543/database/pg_clog/0000
backup_archives/20140218/041543/mkdirs.sh
backup_archives/20140218/041543/file_arclog.txt
backup_archives/20140218/041543/srvlog
backup_archives/20140218/041543/file_database.txt

incremental mode の挙動

次にincrementalモード。

[postgres@localhost ~]$ pg_rman backup --backup-mode=incremental -D /usr/local/pgsql/data/ -d template1
INFO: database backup start
NOTICE:  pg_stop_backup complete, all required WAL segments have been archived
[postgres@localhost ~]$ pg_rman validate
INFO: validate: 2014-02-18 04:27:39 backup and archive log files by CRC
[postgres@localhost ~]$ pg_rman show
============================================================================
Start                Time   Total    Data     WAL     Log  Backup   Status  
============================================================================
2014-02-18 04:27:39    0m    ----    24kB    33MB    ----    33MB   OK
2014-02-18 04:15:43    0m    ----    ----    33MB    ----    33MB   OK
2014-02-18 04:00:13    0m    27MB    ----    83MB    ----   109MB   OK

こっちは、変更のあったテーブルと、archive log領域がコピーされている。
つまり、archiveモードとincrementalモードは同じ挙動を示す!?

[postgres@localhost ~]$ find backup_archives/20140218/042739/
backup_archives/20140218/042739/
backup_archives/20140218/042739/arclog
backup_archives/20140218/042739/arclog/000000010000000000000009
backup_archives/20140218/042739/arclog/000000010000000000000008
backup_archives/20140218/042739/arclog/000000010000000000000009.00000028.backup
backup_archives/20140218/042739/backup.ini
backup_archives/20140218/042739/database
backup_archives/20140218/042739/database/base
backup_archives/20140218/042739/database/base/16384
backup_archives/20140218/042739/database/base/16384/16385
backup_archives/20140218/042739/database/base/12891
backup_archives/20140218/042739/database/base/12896
backup_archives/20140218/042739/database/base/1
backup_archives/20140218/042739/database/pg_twophase
backup_archives/20140218/042739/database/pg_log
backup_archives/20140218/042739/database/pg_notify
backup_archives/20140218/042739/database/pg_snapshots
backup_archives/20140218/042739/database/pg_tblspc
backup_archives/20140218/042739/database/pg_tblspc/16388
backup_archives/20140218/042739/database/pg_tblspc/16388/PG_9.3_201306121
backup_archives/20140218/042739/database/pg_tblspc/16388/PG_9.3_201306121/16384
backup_archives/20140218/042739/database/pg_multixact
backup_archives/20140218/042739/database/pg_multixact/members
backup_archives/20140218/042739/database/pg_multixact/offsets
backup_archives/20140218/042739/database/global
backup_archives/20140218/042739/database/global/pg_control
backup_archives/20140218/042739/database/pg_xlog
backup_archives/20140218/042739/database/pg_serial
backup_archives/20140218/042739/database/backup_label
backup_archives/20140218/042739/database/pg_subtrans
backup_archives/20140218/042739/database/pg_stat
backup_archives/20140218/042739/database/pg_stat_tmp
backup_archives/20140218/042739/database/pg_clog
backup_archives/20140218/042739/database/pg_clog/0000
backup_archives/20140218/042739/mkdirs.sh
backup_archives/20140218/042739/file_arclog.txt
backup_archives/20140218/042739/srvlog
backup_archives/20140218/042739/file_database.txt

ソース

backup.cをザックリ見ると、

if (current.backup_mode < BACKUP_MODE_FULL) {

とか

        if (current.backup_mode == BACKUP_MODE_FULL)
        {
                delete_online_wal_backup();
		delete_arclog_link();
        }


などなど、fullバックアップの記述はあるけども、incrementとarchiveの違いを生み出すはずの条件式が見当たらない。もっともgrepでcurrent.backup_modeを調べた限りだが。

archiveとincrementの違いがでるのは唯一、showコマンドだが、それは単にオプションとして保存しているから表示が異なるだけ。実際にバックアップ処理を行っているbackup.cの中では扱いに違いがない。

上の実験結果をもとにソースを眺めたから、なんらかの先入観があるのかもしれないが、どうもおかしい。


この挙動は、手元で実験する限りver1.2.0ver1.2.3から。それ以前のバージョンはコンパイルできないので試せない。

さて、どうなっているんでしょう?

VACUUM FULLとREINDEXはいつ行うべきか?

表題のとおり、みなさん「いつ、何をキッカケに実行してますか」という素朴な疑問。

VACUUM FULL

ひとつ考えたのがpg_freespacemapを使う方法。以下のSQLを実行するとテーブル"tablename"の空き領域(FreeSpace)の割合が求まる。

SELECT pg_size_pretty(cast(avg(avail) as bigint)) as "平均フリースペースサイズ",
 round(avg(avail)/8192 ,2) as "フリースペースの割合", 
count(*) as "総ブロック数"
FROM pg_freespace('tablename');    

(ブロック数が多く、且つ)この割合が大きな場合は、VACUUM FULLすればいいんじゃないという、定量的議論が可能かと。


他に定量的な指標はあるか?




REINDEX*1

インデックスにはpg_freespacemapが使えないので、どうしましょうか?という疑問。

インデックスでは、ページ内の空き領域ではなく、完全に未使用のページが追跡されます。 したがって、その値には意味がなく、単にページが一杯か空かを表します。

http://www.postgresql.jp/document/9.3/html/pgfreespacemap.html


インデックスの場合は空き領域だけじゃなくて、他にも考慮すべきパラメータがあると思うけども、それもよくわからない。よってpgstattupleなんか使えそうで使えない。


アイディア募集中。

*1:某MLでやたらとREINDEXを実行している会社があるが、何故頻繁にやってんだろう?という疑問はさておき

【はじめたばかりで1/3も書いてない】 OracleとPostgreSQLのシステムビュー/カタログ 比較

自分用メモ
OracleのシステムビューとPostgreSQLの各種カタログ(テーブルとかビューとか)の対応を緩くまとめる。

メモ書きをはじめたばかりで、内容には非常に多くの間違いが混じっているはずので信じないこと。
徐々に完成度を上げていく予定。

(なんとか)対応付け可能なもの

プロセス関係

基本的にPostgreSQLにはプロセス情報を得るためのシステムカタログがない。例外はBackgroundWriterのみ(pg_bgwriter)。

Oracle 説明 PostgreSQLの状況
V$PROCESS Oracleのプロセス情報 上記のようにPostgreSQLにはない。psコマンドで眺めるだけ。
V$BGPROCESS 現在のバックグランドプロセスの情報 同上

ただし、後述するpg_stat_activityのpidでセッション毎のプロセスid、stateでバックエンドプロセスの状態(active|idle|idle in transaction|idle in transaction (aborted)|fastpath function call|disabled)は分かる。

パラメータ

PostgreSQLの場合、postgresql.confでの設定がほぼ全て。
pg_settingsビューで表示できる。

Oracle 説明 PostgreSQLの状況
V$PARAMETER、V$OPTION 有効なパラメータやオプション pg_settingsビューがある。また”SHOW ALL”でパラメータを表示できる。
SESSIONの情報

PostgreSQLのセッション情報はpg_stat_activityに集約されている。よって、ここにない情報はPostgreSQLでは得られないということになる。

例えば、実行中のqueryは分かるが、そのqueryによってアクセスされているテーブルはqueryを目視して確認しなければならない。そうして目視したテーブル名からpg_classなど使って徐々にテーブルの情報を探り出すしかない。

Oracle 説明 PostgreSQLの状況
V$SESSION 現在接続されているセッション pg_stat_activity
V$SESSION_LONGOPS 処理に時間がかかっているセッション pg_stat_activityのxact_startとcurrent_timestampの差をみればよい。ただし、操作対象となっているリレーションはqueryから目視するしかない。

長くかかっているセッション、というかトランザクションを知るには以下のSELECT文を実行する。

SELECT pid, waiting, (current_timestamp - xact_start)::interval(3)
 AS duration, query FROM pg_stat_activity WHERE pid <> pg_backend_pid();


なお、pg_stat_activityの情報は、バックエンド単位の統計情報関数でも得られる。

LOCK

これはばっちり対応がつく。

Oracle PostgreSQL
V$LOCK pg_locks
Buffer Cache

これが書きたくてこのエントリーをはじめたようなもの。

PostgreSQLには標準ではshared_buffersの中身を知る手だてがない。しかしcontribのpg_buffercacheを使うとある程度わかる。

Oracle 説明 PostgreSQLの状況
V$CACHE メモリ上のオブジェクトを特定する pg_buffercacheを使ってqueryを組み立てると、ある程度わかる。

まだqueryが複雑過ぎて表にだせるレベルではないけども、例えばshared_buffersの利用率なら以下のqueryでそれっぽいのが表示できる。

-- 作成途中。間違ってる可能性あり。
WITH 
bc AS (SELECT count(*) AS block_num 
      	  FROM (SELECT DISTINCT ON (relfilenode,relforknumber,relblocknumber) relfilenode 
       	      	   FROM pg_buffercache WHERE relfilenode IS NOT NULL OR relfilenode != 0) AS a),
bs AS (SELECT cast(current_setting('block_size') AS integer) AS block_size),
sb AS (SELECT cast(setting AS bigint) shared_buffers 
           FROM pg_settings WHERE name = 'shared_buffers')
SELECT 
pg_size_pretty(bc.block_num * bs.block_size) AS "used buffer size",
pg_size_pretty(sb.shared_buffers * bs.block_size) AS "total buffer size",
CASE WHEN bc.block_num = 0 
THEN  0.00
ELSE round(cast(cast(bc.block_num AS numeric)/cast(sb.shared_buffers AS numeric) AS  numeric) ,2) 
END AS "usage ratio"
FROM bc, bs, sb;
 used buffer size | total buffer size | usage ratio 
------------------+-------------------+-------------
 7856 kB          | 20 MB             |        0.38
(1 row)

Oracleの共有プール関係のビュー(V$SGASTAT、V$DB_OBJECT_CHACE、V$SQLAREA)あたりは、PostgreSQLに共有プールという概念がないから対応不可でOK?


(私が今のところ)対応付けできないもの

OraclePostgreSQLもよく知らないので(今のところ)対応付けできていないもの。

TABLE,INDEX,DATABASEの統計情報

Oracleではなんでしたっけ?
PostgreSQLにはこんなものがあるのですが。

システムカタログ 説明
pg_stat_database データベースの統計情報。
pg_stat_all_tables テーブル毎の統計情報
pg_statio_all_tables テーブル毎の統計情報。バッファのヒット回数などIOレベルの情報
pg_stat_all_indexes インデックス毎の統計情報
pg_statio_all_indexes インデックス毎の統計情報。バッファのヒット回数などIOレベルの情報

因みにこれらのシステムカタログの情報は、当然ながらリレーションに紐付けされている。セッションやquery、トランザクション毎にリレーションの統計情報がどうなっているかは分からない。例えば、あるセッションがあるリレーションに読み書きしたブロック数などは分からない。




(概念的に違いすぎて)対応付け不可能なもの

TABLESPACE

OraclePostgreSQLでは"TABLESPACE"の意味が全く異なるので、比較しようがない。

Oracle 意味 PostgreSQLで無意味な理由(補足)
V$TABLESPACE Oracleでの表領域一覧 概念的に異なる。PostgreSQL的なTABLESPACEならば\dbか、pg_tablespaceで得られる。
OracleのTABLESPACEの空き(FREE): DBA_FREE_SPACE

これもPostgreSQLには概念的に存在しないものだけども、TALBLESPACEでなくTABLE(やINDEX)のFREE SPACEならば
contribのpg_freespacemapを使うとわかったりする。

メモ書きとして、書いておく。

V$TRANSACTION

「おいおいPostgreSQLにもトランザクションはあるだろ!M○S○Lみたいなポンコツとは違うだろ」という声も聞こえますが、OracleのV$TRANSACTIONはUNDO領域の情報だったりするのでPostgreSQLには関係ないわけですね*1

*1:PostgreSQLは追記型でUNDOログも持っていない