

現在apache2.2、postgresql8.3.3、PHP5.3を利用しております。  
起こった現象は表題の通りですが、以下に行った操作を列挙します。

・新たにシステムへ手を加えるにあたりデータベースのバックアップを行うべくpg_dumpを発行した。  
・始めは問題なかったが、15分ほど経過した頃システムにつながらないことを確認。  
・pg_dumpをCtrl+Cで中断。  
・topコマンドで確認したところ、load averageが50くらい、cpu消費がsy20,waが70程度、またスワップ領域をかなり利用していた。  
・psコマンドで確認したところ、大量のselectプロセスが溜まっていた。  
・しばらくしたところサーバが応答を受け付けなくなった。  
・再起動を行ったが、新たにselectプロセスが発生しすぐにサーバが操作不能の状態になった。  
・再度再起動を行い、postgresqlを停止したところ、操作可能の状態に復帰した。  
・その後、また再起動したところ問題なくシステムが稼働している。

以上のようなことが起こったのですが、その後の調査でも再現せず、原因がつかめておりません。  
以上の時システムは稼働中であり、利用者がいくらかいたと思われます。  
またpostgresqlのログを確認したところ、その前後で大きなデータのupdateとselectが何度か走っていることがわかりました（一件当たりが大きく、5万文字のデータ）。  
ちなみにpg_dumpは毎日利用者の少ない時間に走っており、特にエラー等は出ておりません。

環境は以下の通りです。  
Apache 2.2  
Postgresql 8.3.3（データベースのサイズは、ダンプしたところ数十Gほど）  
PHP 5.3  
メモリ 16GB

どなたかお力を貸していただけないでしょうか。  
よろしくお願いします。


CC BY-SA 3.0
2015-08-25T07:31:50.740
14822
2015-08-26T08:55:41.907
11054
question
php apache postgresql
pg_dumpでサーバが停止してしまう


一般論ですが、運用中のDBをdumpすればそうなるんじゃないでしょうか。

まず、dumpが走るとDBMSは何をするかというと、保存されるデータの整合性を保つためdb本体への更新を止めます。  
しかし、dump中だからクエリに答えないわけにも行かないので、更新がかかったデータについては”後で本体を更新する予定”というファイルに逐次書き込んで行きます。  
この状態でSELECTが来るとどうなるかというと、本来更新されているべきデータを返さないわけにはいかないので、本体のほかに”後で本体を更新する予定”のエリアも検索します。しかし、このエリアはインデックスが付いているわけではないので検索するには全部読み込まなければならず、時間がかかります。

こんな理屈でどんどんSELECTが滞留していき、操作できなくなるくらいまで負荷が上がったのではないかと推測します。ただし、50kbyteを数回書き換えたくらいではこんなことにはならないので何かまだ見落としがあるものと思います。


CC BY-SA 3.0
2015-08-25T11:48:09.237
14832
2015-08-25T11:48:09.237
8136
14822
answer


ロックモードを洗い出して見てみると目星が付くかもしれません。

pg_dump は `ACCESS SHARE モード` でテーブルレベルのロックを取得します。  
`ACCESS SHARE モード` は 次の場合に衝突します。

  * `ALTER TABLE` `DROP TABLE`
  * `VACUUM`
  * `ACCESS EXCLUSIVE モード` で明示的にロックを取得したばあい
  * モードを省略した場合 (暗黙的に `ACCESS EXCLUSIVE モード`になる)

_余談_  
pd_dumpのマニュアルが良くない(と私は思っている)のですが `pg_dumpは他のユーザによるデータベースへのアクセス（読み書き）をブロックしません`
と書かれているので、一見、運用中でも影響なく取得できそうに思えますが、実際はロックモードの関係で排他制御が行われる可能性があります。


CC BY-SA 3.0
2015-08-26T08:55:41.907
14863
2015-08-26T08:55:41.907
5008
14822
answer