ログ日記

作業ログと日記とメモ

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'
...
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の設定は

[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接続されたらやっぱり固まることになるな・・。