postfixとdbmailからpgpoolへの接続、接続数
- smtpd
- アカウントの存在チェック
select transport from postfix_transport where domain = '*' select transport from postfix_transport where domain = 'hoge.hoge' select transport from postfix_transport where domain = 'hoge' ...
-
- pop before smtp 用テーブルへの接続
select since from dbmail_pbsp where ipnumber = '192x168x10x100ap1.fuga.fuga' select since from dbmail_pbsp where ipnumber = 'fuga.fuga' select since from dbmail_pbsp where ipnumber = 'fuga' select since from dbmail_pbsp where ipnumber = '192.168.10.100'
select username from postfix_users where username = 'from@fuga.fuga'
- lmtpd
- メールのアドレスの検索
SELECT deliver_to FROM dbmail_aliases WHERE lower(alias) = lower('hoge@hoge.hoge') AND lower(alias <> lower(deliver_to)
-
- メールの配送
BEGIN SELECT user_idnr FROM dbmail_users WHERE userid='__@!internal_delivery_user!@__' SELECT mailbox_idnr FROM dbmail_mailboxes WHERE name='INBOX' AND owner_idnr='1' INSERT INTO dbmail_physmessage (messagesize, internal_data) VALUES ('0', CURRENT_TIMESTAMP) SELECT currval('dbmail_physmessage_id_seq') INSERT INTO dbmail_message(mailbox_idnr, physmessage_id, unique_id, recent_flag, status) VALUES( '1', '2', '343af...', '3', 4) SELECT currval('dbmail_message_idnr_seq') SELECT physmessage_id FROM dbmail_message WHERE message_idnr = '6') INSERT INTO dbmail_messageblks (is_header, messageblk, blocksize, physmessage_id) VALUES ('1', 'Return-Path: hoge...', '8', '9') SELECT currval('dbmail_messageblk_idnr_seq') ...
postfixのプロセスがそれぞれ独立しているもんだから、DBへの接続リソースも独立している。
で、スパマーが10通とか20通とか同時に送ってくると、大量の接続が一気に開かれるわけ。
ここで本文データ格納のための接続が、pgpoolの接続最大数を超えているとリソース待ちになる。
いや・・しかしプロセスがそれぞれ独立しているなら、各プロセスの処理が終わったらDBへの接続を閉じればデッドロック(?)にならないわけだが・・閉じないの?接続を開いたままプロセスが待機しているとか?
# ps -A ... 23468 ? 00:00:00 dbmail-pop3d 23469 pts/5 00:00:00 postmaster 23470 ? 00:00:00 dbmail-pop3d 23471 pts/5 00:00:00 postmaster 23472 ? 00:00:00 dbmail-pop3d 23473 pts/5 00:00:00 postmaster 23474 ? 00:00:00 dbmail-pop3d 23475 pts/5 00:00:00 postmaster 23476 ? 00:00:00 dbmail-pop3d 23477 pts/5 00:00:00 postmaster ... 23482 ? 00:00:00 dbmail-lmtpd 23483 pts/5 00:00:00 postmaster 23485 ? 00:00:00 dbmail-lmtpd 23486 pts/5 00:00:00 postmaster 23487 ? 00:00:00 dbmail-lmtpd 23488 pts/5 00:00:00 postmaster 23489 ? 00:00:00 dbmail-lmtpd 23490 pts/5 00:00:00 postmaster 23491 ? 00:00:00 dbmail-lmtpd 23492 pts/5 00:00:00 postmaster ...
メール配送の処理が終わっても接続を持続させたまま待機していますね・・・。
ってことはですよ。
- dbmailのPOP3やらSMTPやらの最大接続数 * n =< pgpool の最大接続数 =< postgresql の最大接続数
の設定を行わないと固まるというわけか。
.......
dbmailの設定は
[LMTP] MAXCHILDREN=200 MAXCONNECTS=10000 # !!!
同じような設定がPOP等にもあるわけで・・・
一度のdbmailへの接続に対して複数のpgpoolへの接続が行われるわけで・・・
えっと・・・
orz
現在のプロセス数が200程度でカーネルの最大プロセス数が16382でメモリが1Gで・・・一体postgresqlのプロセスは何個まで立ち上げられるんだ?混乱してきた・・
# 追記
メモリは先にpostgresqlが使うshared memoryの上限値に引っかかる。取り敢えずプロセスを500ほど立ち上げてみて、様子見。
DBプロセス500で待機とか普通なの?大規模運用したことないから分からん。。
CPUをもりもり積んでるわけでもないので意味は無いんだが・・スパムのためのリソースを用意するっていうのはどうなんだこれ。
http://www.mono-space.net/doc/pgpool.html
num_init_childrenとmax_poolを理解し、正しく設定する。PostgreSQL側から見た最大同時接続数はnum_init_children * max_poolとなるが、クライアント側から見た最大同時接続数はnum_init_childrenとなる。
これ重要。
面倒なのでmax_poolを1に設定。9割以上がdbmailの接続だから大丈夫だろう。
あとは・・・MAXCONNECTS=10000 が気になる。一つのプロセスから大量にDB接続されたらやっぱり固まることになるな・・。