[pgsql-jp: 41137] Re: ■質問■PostgresSQLのディスク使用量の増える仕組みについて

Satoshi Nagayasu satoshi.nagayasu @ gmail.com
2012年 6月 15日 (金) 00:10:38 JST


永安です。

> Date: Thu, 14 Jun 2012 16:21:21 +0900
> From: "S.Watanabe"<sywatanabe @ iwass.co.jp>
>
> しかし、int型5つからなるレコードを1レコード追加した時は、
> 上記4.3)でDBファイルが更新されますが、100レコード追加した場合は、
> 即座にDBファイルの更新時刻とサイズが変化していました。
> 更新前後ではWALログは1つしかない状態でした。
> また設定は非同期書込みで、バックグラウンドライタやバキュームは停止させ
ています。
>
> これはどういう要因で更新されているのでしょうか?
> 2.または3.の時点でDBファイルに書込み領域が無い場合は即座に
> DBファイルのサイズを8kbの倍数サイズ増やしてデータが書き込まれるので
しょうか?

「何を契機に増えるか」という質問に直接的に答えるのであれば、
「レコード数が増加して既存のファイル内に収まらなくなった時」です。

ご参考までに、PostgreSQLのデータブロックの格納構造(レイアウト)は、
以下の資料にあります。

PostgreSQLアーキテクチャ入門(INSIGHT OUT 2011)
http://www.slideshare.net/uptimejp/postgresqlinsight-out-2011/39

今回の場合、上記を踏まえて計算すると、

・1レコードサイズは・・・
 4バイト(アイテムポインタ)
  +24バイト(タプルヘッダ)
  +40バイト(integer型×5カラム)=合計68バイト

となります。

・100レコードのサイズは・・・
 72バイト(アラインメント込み)×100レコード=7200バイト

となりますが、テーブルブロックにはfillfactor(充足率)がありますので、

・fillfactor 90%(テーブルのデフォルト)の場合、
 1ブロックに使用できる空きスペースは・・・
 {8192バイト(ブロックサイズ)−28バイト(ページヘッダ)}×90%
  ≒7347バイト

となり、100レコードを記録すると、ほぼ1ブロック(8kB)を使い切る
サイズになることが分かります。(上記計算には誤差があり得ますが)

既存のブロックにデータが入り切らずに新規のブロックを必要とする場合、
別メールの片岡さんのコメントにもあったように、
即時にファイルサイズを1ブロック分(8kB)増加させます。

なので、既存ブロックを使い切って新規領域が必要な場合は、
即時にファイルサイズが増加します。

> 4.以下のいづれかでDBファイルが更新
>    1)CHECKPOINTコマンド実行時
>    2)サーバ停止時(pg_cnt -D DBクラスタパス stop)
>    3)checkpoint_timeoutで指定した時間が経過
>    4)WALログがcheckpoint_segmentsで指定した個数以上に達した時

> また設定は非同期書込みで、バックグラウンドライタやバキュームは停止させ
ています。

http://www2.uptimeforce.com/pgstatview/5022d3f8417dfda8c738be6cbd237838/

上記URLのグラフの「pgstat - Block Written」を見ると分かりますが、
実際にファイルを書き込んでいるのはbgwriterだけではなく、
postgresのプロセスも書き込んでいます。
(上記グラフは大量にINSERTしている際のグラフです)

より正確に言うと、チェックポイント以外で書き込む場合(新規ブロックの
確保とバッファの割り当て等)があります。
つまり、上記の4-1)〜4-4)以外のケースですがあるということです。

以上、よろしくお願いします。

> Date: Thu, 14 Jun 2012 16:21:21 +0900
> From: "S.Watanabe"<sywatanabe @ iwass.co.jp>
> 
> 渡辺と申します。
> 
> PostgreSQL(Ver.8.3.1)のDBファイル(base/nnnnn/配下のテーブル等のデータを含む
> ファイル)が
> 何を契機に増えているのか調べています。
> 
> 過去メール※は参照しましたが、いまひとつ理解できていません。
> 
> 私の理解では、以下のようなものです。
> 1.クライアントからデータ追加要求を受信
> 2.PostgreSQLサーバの共有バッファにデータが追加
> 3.WALログにデータが追加
> 4.以下のいづれかでDBファイルが更新
>    1)CHECKPOINTコマンド実行時
>    2)サーバ停止時(pg_cnt -D DBクラスタパス stop)
>    3)checkpoint_timeoutで指定した時間が経過
>    4)WALログがcheckpoint_segmentsで指定した個数以上に達した時
> 
> しかし、int型5つからなるレコードを1レコード追加した時は、
> 上記4.3)でDBファイルが更新されますが、100レコード追加した場合は、
> 即座にDBファイルの更新時刻とサイズが変化していました。
> 更新前後ではWALログは1つしかない状態でした。
> また設定は非同期書込みで、バックグラウンドライタやバキュームは停止させています。
> 
> これはどういう要因で更新されているのでしょうか?
> 2.または3.の時点でDBファイルに書込み領域が無い場合は即座に
> DBファイルのサイズを8kbの倍数サイズ増やしてデータが書き込まれるのでしょうか?
> だとすれば、WALログが実際にDBファイルに反映するデータはチェックポイント実行前の
> 8kb未満のデータしかないように思えるのですが。。。
> 
> 
> 動作させた時の設定は以下の通りです。
> ■設定
>    fsync = off
>    synchronous_commit = off
>    full_page_writes = off
>    checkpoint_segments = 3
>    checkpoint_timeout = 1h
>    checkpoint_completion_target = 0.5
>    bgwriter_lru_maxpages = 0
>    autovacuum = off
>    track_counts = off
>    shared_buffers = 24MB
> 
> 
> ※[pgsql-jp: 39573] Re: PostgreSQLのディスク使用量が増えるタイミングについて
> 
> _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
> Shuichi Watanabe
> 
> E-mail : sywatanabe @ iwass.co.jp
> 
> _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
> 
> 
> 
> 
> 
-- 
NAGAYASU Satoshi <satoshi.nagayasu @ gmail.com>


pgsql-jp メーリングリストの案内