fc2ブログ
ホーム   »  データベース/JDBC
Category | データベース/JDBC

PostgreSQL 運用メモ

◆ VACUUM の実行

PostgreSQL ドキュメント定常的なデータベース保守作業の俺様要約

  • PostgreSQL はレコードが更新/削除されても物理削除は行わない
  • これは VACUUM で行うので定期的な実行が必要
  • 更新頻度の高いテーブルほど頻繁に VACUUM のすること
  • 普通の VACUUMVACUUM FULL の 2 種類がある
  • 普通の VACUUM は使われていない領域に再利用可能なマークを付ける
  • 普通の VACUUM は不要領域がファイルの最後でない限りファイル縮小は行わない
  • 普通の VACUUM は他のトランザクションにほとんど影響しない
  • VACUUM FULL は不要領域の占有領域を削除しファイルを縮小する
  • VACUUM FULL は他のトランザクションに与える影響も甚大
  • 一般的には1日1回普通の VACUUM をしておけばよい
  • 全レコードを削除する場合は TRANCATE を使えば VACUUM する必要がない
  • トランザクション ID は 32 ビットで周回する
  • トランザクション ID が周回が発生するとデータ損失が起きる
  • 7.2 以降は 10 億トランザクション発行する前に VACUUM が必要
  • 残りトランザクション数が1000万を下回ると警告が出る
  • 残りトランザクション数が100万を下回ると発行が出来なくなる

俺様の理解

  • Java の Gabage Collection で例えるなら普通の VACUUM = Mark & Swept、VACUUM FULL = Compact 、Windows で例えるなら VACUUM FULL = デフラグ
  • 定期処理は1日1回普通の VACUUM だけで十分 (VACUUM FULL はディスク容量を見ながらの不定期で良い?)

◆ バックアップとリストア

PostgreSQL ドキュメントバックアップとリストアの俺様要約

  • pg_dump は運用中の実行が可能
  • pg_dump はテーブル構成や全レコードを SQL で出力する
  • 出力した SQL を psql に流し込むと再構築が可能
  • ユーザ等、クラスタまとめてバックアップしたい場合は pg_dumpall を使用
  • ファイルが大きくなる場合はパイプで圧縮すなり分割するなり
  • 単純なファイルコピーによるバックアップは postgreSQL の完全停止が必要 (全切断だけではNG)
  • ポイントインタイムリカバリ (PITR) という JFS やロールフォーワードのような障害復旧機構がある
  • RITR は WAL ファイルにログ (ジャーナル) を記録している
  • WAL ファイルを累積的に保管するだけで任意の時点でのスナップショットが再現できる
  • WAL ファイルをバックアップ機で再生すればホットスタンバイを実現できる

俺様の理解

  • 小規模システムなら pg_dump の定期バックアップで十分
  • pg_dump の定期バックアップが現実的でない大規模システムは WAL ファイルで

Java + PostgreSQL で BLOB を扱う その 3

さらに続きである。これで完結である (ことを願う…)。

まずは観測から。

何とかなりそう! ヽ(´ー`)ノ

PostgreSQL で大きなバイナリを扱うには、今まで試した BYTEA 型を使用するほかに OID 型を使用する方法がある。BYTEA 型がバイナリそのものをテーブルに格納するのに対し、OID 型はオブジェクトの ID のみを格納し、実体のバイナリはどこか別のところに保存される (PostgreSQL の場合はシステムカタログのどこかに入るらしい)。

元々 BLOB がロケーション ID やオフセット、長さなどを使って巨大なバイナリを扱うための手段だということを考えれば、むしろこの OID 型を BLOB と呼ぶ方が自然だ (ちなみに商用データベースの方は実体をテーブルスペース外の別ファイルにするか VARBINARY と同様にテーブル内に入れるかなど、きめ細かな構成を選択できるが)。

PostgreSQL の JDBC ドキュメントを参照すると、Java で OID 型を扱うには "LargeObject API" なるものを使わなければならいように見えるが、実は JDBC の java.sql.Blob と互換性のある方法で取り扱えるようになっているようだ。正にこっちが PostgreSQL 的 BLOB なのである。

ネットを検索してみる限り、BYTEA 型を扱うサンプルはいくつか見つかるものの、OID 型を java.sql.Blob で扱う Java チュートリアルはほとんど無いようだ (これが日本語初か?)。なので今回はチュートリアルっぽくまとめてみる。例によってコード簡略化のためリソースのクローズや変数宣言等は省略。

続きを読む

Java + PostgreSQL で BLOB を扱う その 2

出た! (;´ー`)y─┛~~

前回、InputStream を使って巨大データを BYTEA 型カラムに格納出来たわけだが、今度は保存した内容を取り出すタイミングで再び OutOfMemoryError が姿を現した。

なんだかすごーく嫌な予感がするのだが… とりあえず 8.1 ドライバのソースでも見てみるか。

public InputStream getBinaryStream(int columnIndex)
    throws SQLException
{
    // ...
    if (connection.haveMinimumCompatibleVersion("7.2")){
        // Version 7.2 supports BinaryStream for
        //
all PG bytea type As the spec/javadoc for
        // this method indicate this is to be used for
        //large binary values (i.e. LONGVARBINARY)
        // PG doesn't have a separate long binary
        // datatype, but with toast the bytea datatype is
        // capable of handling very large values.  Thus
        // the implementation ends up calling getBytes()
        // since there is no current way to stream the
        // value from the server
        byte b[] = getBytes(columnIndex);
        if (b != null)
            return new ByteArrayInputStream(b);
    } else {
        // 7.1 以前の場合
    }
    return null;
}
 

. .: : : : : : : : :: :::: :: :: : :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    . . : : : :: : : :: : ::: :: : :::: :: ::: ::: ::::::::::::::::::::::::::::::::::::::
   . . .... ..: : :: :: ::: :::::: :::::::::::: : :::::::::::::::::::::::::::::::::::::::::::::
        Λ_Λ . . . .: : : ::: : :: ::::::::: :::::::::::::::::::::::::::::
       /:彡ミ゛ヽ;)ー、 . . .: : : :::::: :::::::::::::::::::::::::::::::::
      / :::/:: ヽ、ヽ、 ::i . .:: :.: ::: . :::::::::::::::::::::::::::::::::::::::
      / :::/;;:   ヽ ヽ ::l . :. :. .:: : :: :: :::::::: : ::::::::::::::::::
 ̄ ̄ ̄(_,ノ  ̄ ̄ ̄ヽ、_ノ ̄ ̄ ̄ ̄

 

続きを読む

Java+PostgreSQLでBLOBを扱う その1

PostgreSQL 7.4.11 (JDBC 3 Driver 7.4.215) の BYTEA (BLOB) 型カラムにファイルの内容を放り込もうと思ったのだが、ファイルサイズが数十MB になると例外が発生してしまうようだ。

java.lang.OutOfMemoryError: Java heap space

例外が起きなくてもディスクスワップが多発しているようだし、ひょっとしてファイルの全バイナリから巨大な SQL でも組み立てているのだろうか? 今回はそこらへんをちょっと突っ込んで調べてみようと思う。

続きを読む

PostgreSQL文字セット

PostgreSQL 8.0/8.1 の Windows 版をインストールする時、デフォルトの EUC_JP 以外の文字セット (UNICODE, UTF-8 など) を選択してはならない。

インストールで選択するのは initdb の際に用いられる文字セットなのだが、デフォルト以外を選択すると日本語で検索できなくなったりするのだ。ちなみに Linux 版だと initdb で UNICODE を選択しても問題はない。

なお CREATE DATABASE で指定する文字セットを EUC_JP 以外にして問題あるかは不明。

Profile
Takami Torao
Takami Torao
C/C++ 使いだった 1996年、運命の Java と出会い現在に至る。のらアーキテクト。
Yah, this is image so I don't wanna eat spam, sorry!
Search

Google
MOYO Laboratory
Web

カテゴリー
最近の記事
最近のコメント
最近のトラックバック
月別アーカイブ
ブロとも申請フォーム
RSSフィード
リンク