postgreSQL 9.1.2の使用
CPUが過度に使用され、postmasterタスクからディスクへの大量の書き込みが発生しています。これは、アプリケーションがほとんど何も実行していないときにも発生します(1分あたり数十回の挿入)。ただし、適切な数の接続が開いています。
私のアプリケーションの何がこれを引き起こしているのかを特定しようとしました。私はpostgresqlにかなり慣れていないので、今のところどこにも行きません。設定ファイルでいくつかのログオプションをオンにし、pg_stat_activityテーブルで接続を確認しましたが、すべてアイドル状態です。それでも、各接続は〜50%のCPUを消費し、ディスクに〜15M/sを書き込んでいます(何も読み取っていません)。
基本的には、調整をほとんど行わずに、ストックのpostgresql.confを使用しています。これを追跡するために何ができるかについてのアドバイスやアドバイスをいただければ幸いです。
Top/iotopが表示しているサンプルを以下に示します。
Cpu(s): 18.9%us, 14.4%sy, 0.0%ni, 53.4%id, 11.8%wa, 0.0%hi, 1.5%si, 0.0%st
Mem: 32865916k total, 7263720k used, 25602196k free, 575608k buffers
Swap: 16777208k total, 0k used, 16777208k free, 4464212k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
17057 postgres 20 0 236m 33m 13m R 45.0 0.1 73:48.78 postmaster
17188 postgres 20 0 219m 15m 11m R 42.3 0.0 61:45.57 postmaster
17963 postgres 20 0 219m 16m 11m R 42.3 0.1 27:15.01 postmaster
17084 postgres 20 0 219m 15m 11m S 41.7 0.0 63:13.64 postmaster
17964 postgres 20 0 219m 17m 12m R 41.7 0.1 27:23.28 postmaster
18688 postgres 20 0 219m 15m 11m R 41.3 0.0 63:46.81 postmaster
17088 postgres 20 0 226m 24m 12m R 41.0 0.1 64:39.63 postmaster
24767 postgres 20 0 219m 17m 12m R 41.0 0.1 24:39.24 postmaster
18660 postgres 20 0 219m 14m 9.9m S 40.7 0.0 60:51.52 postmaster
18664 postgres 20 0 218m 15m 11m S 40.7 0.0 61:39.61 postmaster
17962 postgres 20 0 222m 19m 11m S 40.3 0.1 11:48.79 postmaster
18671 postgres 20 0 219m 14m 9m S 39.4 0.0 60:53.21 postmaster
26168 postgres 20 0 219m 15m 10m S 38.4 0.0 59:04.55 postmaster
Total DISK READ: 0.00 B/s | Total DISK WRITE: 195.97 M/s
TID PRIO USER DISK READ DISK WRITE SWAPIN IO> COMMAND
17962 be/4 postgres 0.00 B/s 14.83 M/s 0.00 % 0.25 % postgres: aggw aggw [local] idle
17084 be/4 postgres 0.00 B/s 15.53 M/s 0.00 % 0.24 % postgres: aggw aggw [local] idle
17963 be/4 postgres 0.00 B/s 15.00 M/s 0.00 % 0.24 % postgres: aggw aggw [local] idle
17188 be/4 postgres 0.00 B/s 14.80 M/s 0.00 % 0.24 % postgres: aggw aggw [local] idle
17964 be/4 postgres 0.00 B/s 15.50 M/s 0.00 % 0.24 % postgres: aggw aggw [local] idle
18664 be/4 postgres 0.00 B/s 15.13 M/s 0.00 % 0.23 % postgres: aggw aggw [local] idle
17088 be/4 postgres 0.00 B/s 14.71 M/s 0.00 % 0.13 % postgres: aggw aggw [local] idle
18688 be/4 postgres 0.00 B/s 14.72 M/s 0.00 % 0.00 % postgres: aggw aggw [local] idle
24767 be/4 postgres 0.00 B/s 14.93 M/s 0.00 % 0.00 % postgres: aggw aggw [local] idle
18671 be/4 postgres 0.00 B/s 16.14 M/s 0.00 % 0.00 % postgres: aggw aggw [local] idle
17057 be/4 postgres 0.00 B/s 13.58 M/s 0.00 % 0.00 % postgres: aggw aggw [local] idle
26168 be/4 postgres 0.00 B/s 15.50 M/s 0.00 % 0.00 % postgres: aggw aggw [local] idle
18660 be/4 postgres 0.00 B/s 15.85 M/s 0.00 % 0.00 % postgres: aggw aggw [local] idle
Update:多くのファイル書き込みは、$ PG_DATA/base /ディレクトリー内のいくつかの一時(?)ファイルに対するもののようです。 私の理解 ここでのファイル構造は、各テーブルは基本的に、名前がOIDというテーブル名のファイルとして保存されます。しかし、 tnn_nnnnnnn
、そして常に書き込まれる(おそらく上書きされる)ように見えるのはこれらのファイルです。これらのファイルは何のためのものですか? 〜4700個のファイルがあり、すべてサイズが8Kです。
-rw-------. 1 postgres postgres 8192 Jul 3 23:08 t12_1430975
-rw-------. 1 postgres postgres 8192 Jul 3 23:08 t16_1432736
-rw-------. 1 postgres postgres 8192 Jul 3 23:08 t28_1439066
-rw-------. 1 postgres postgres 8192 Jul 3 23:08 t24_1436243
-rw-------. 1 postgres postgres 8192 Jul 3 23:08 t24_1436210
-rw-------. 1 postgres postgres 8192 Jul 3 23:08 t19_1393372
-rw-------. 1 postgres postgres 8192 Jul 3 23:08 t28_1439051
-rw-------. 1 postgres postgres 8192 Jul 3 23:08 t8_1430334
Update:postmasterプロセスでstraceを実行すると、基本的に多くのファイルI/Oが表示されます:
open("base/16388/t24_1435947_fsm", O_RDWR) = -1 ENOENT (No such file or directory)
open("base/16388/t24_1435947_vm", O_RDWR) = -1 ENOENT (No such file or directory)
open("base/16388/t24_1435947", O_RDWR) = 9
lseek(9, 0, SEEK_END) = 8192
ftruncate(9, 0) = 0
lseek(9, 0, SEEK_END) = 0
open("base/16388/t24_1435941", O_RDWR) = 18
lseek(18, 0, SEEK_END) = 0
write(9, "\0\0\0\0\0\0\0\0\1\0\0\0000\0\360\37\360\37\4 \0\0\0\0b1\5\0\2\0\0\0"..., 8192) = 8192
lseek(18, 0, SEEK_END) = 0
close(9) = 0
open("base/16388/t24_1435947", O_RDWR) = 9
lseek(9, 0, SEEK_END) = 8192
close(18) = 0
close(9) = 0
open("base/16388/t24_1435944_fsm", O_RDWR) = -1 ENOENT (No such file or directory)
open("base/16388/t24_1435944_vm", O_RDWR) = -1 ENOENT (No such file or directory)
open("base/16388/t24_1435944", O_RDWR) = 9
lseek(9, 0, SEEK_END) = 0
close(9) = 0
Update:したがって、この問題は一時テーブルに関するすべての問題のようです。一時テーブルが「通常の」テーブルになるように設定を変更し、すべてのディスクアクティビティがなくなり、パフォーマンスが期待したとおりに戻りました。さて、この変更は迅速でダーティなテストにすぎません。通常のテーブルを使用するように本当に変更する場合、同時実行性とクリーンアップに問題があります。一時テーブルは本当にそれが悪いのでしょうか、それとも悪用していますか?
更新:もう少し背景。私は社内で開発した ステートメントベースのレプリケーションミドルウェア を利用しています。それはかなり成熟しており、長年にわたって多くのプロジェクトで使用されてきましたが、MySQLを使用しています。私たちは過去1〜2年だけPostgreSQLを使用してきました。基本的に、レプリケーションメカニズムの一部として一時テーブルを使用していました。新しい接続が確立されるたびに、データベース内の各テーブルに一時テーブルを作成します。 10〜20(存続期間)の接続と約50のテーブルがある場合、これは大量の一時テーブルになる可能性があります。すべての一時テーブルは次のように作成されました:
CREATE TEMPORARY TABLE... ON COMMIT DELETE ROWS;
一時テーブルのセマンティクスはレプリケーションスキームに非常によく適合し、MySQLに使用する必要のあるコードの多くを簡素化しましたが、実装も公平ではなかったようです。私が行った少しの研究から、私は一時テーブルが私たちがそれらを使用していた関数のために本当に意図されていたとは思いません。
私はこのテーマについては社内の専門家ではなく(たとえ近づいてもいない)、それを使用しているだけなので、私の説明は100%正確ではないかもしれませんが、かなり近いと思います。
あなたのPostgreSQLの設定はかなりずれています。これはあなたの最初の投稿から不審でした、
Cpu(s): 18.9%us, 14.4%sy, 0.0%ni, 53.4%id, 11.8%wa, 0.0%hi, 1.5%si, 0.0%st
Mem: 32865916k total, 7263720k used, 25602196k free, 575608k buffers
Swap: 16777208k total, 0k used, 16777208k free, 4464212k cached
サーバー上の32GBのうち、約575MBのバッファーを除いて約25GBが無料です。
Postgresql.confファイルから、
shared_buffers = 32MB # min 128kB
#temp_buffers = 8MB # min 800kB
#max_prepared_transactions = 0 # zero disables the feature
...
#work_mem = 1MB # min 64kB
#maintenance_work_mem = 16MB # min 1MB
#max_stack_depth = 2MB
これは専用データベースだと思います。その場合は、次のパラメータに変更して、再読み込み/再起動します。
shared_buffers = 16GB # min 128kB
temp_buffers = 128MB # min 800kB
#max_prepared_transactions = 0 # zero disables the feature
...
work_mem = 8MB # min 64kB
maintenance_work_mem = 64MB # min 1MB
max_stack_depth = 4MB
これによりパフォーマンスがどのように変化し、必要に応じてさらに調整できるかを教えてください。
ログに記録されていないテーブルに関しては、一時テーブルに一時的な一時データが含まれ、前述のようにセッションで作成された場合、ログに記録されていないテーブルを使用することをお勧めします。
許容できる場合は、セッション後にテーブルを切り捨てることができます。
詳細はこちら http://michael.otacoo.com/postgresql-2/unlogged-table-performance-in-postgresql-9-1/
レプリケーションに一時テーブルが必要な理由がわかりません。 PostgreSQLストリーミングレプリケーションを使用できませんか?
Postgresql.confファイルを投稿できますか?あなたのpostgresqlは大幅に最適化されていないようです。
あなたも投稿してください:
一時テーブルにログなしのテーブルを使用している場合?
ディスク数とRAID構成は?
一時テーブルを使用し、長時間接続(おそらく接続プールが含まれる)を使用することは、サーバーで準備ができていない場合に負担となる可能性があります。試してみることができる1つのPostgreSQLパラメーターは temp_buffers
これは、制御を制御しますRAM一時テーブルに割り当てられます。これらの一時バッファーは接続ごとに割り当てられ、デフォルト値(8MB)はおそらくサイトに対して低すぎます。
一時テーブルの使用方法によっては、クライアントアプリケーションの動作を少し変更する必要があるかもしれません。 Stack Overflowの良い答え を使用した同様の質問があります。