Author: Artis Caune Date: To: exim-users Subject: [exim] exim with postgres, address_data and variables
Hello exim-users,
We are trying to switch from postfix to exim, and I'm impressed how
flexible and powerfull exim is.
I was shockd about how postfix is using queries to databases.
For every mail, every recipient it's doing zillion of lookups
(user@???; user; @do.ma.in; do.ma.in; ma.in; in; *)
For every transport_maps, virtual_mailbox_domains,
virtual_mailbox_maps, virtual_alias_maps it's maiking those queries.
So for one mail message, we can have 100+ lookups (using two postfix instances).
Till this moment I can't figure out why postfix is doing forward
lookups for recipient. :)
I configured exim only to do 1 pgsql lookup for every recipient and/or
every forward, so 100+ or 2 lookups are big difference.
Second, when you need more and more services in your mail system,
there is nothing you can do with postfix, maybe just use 10 instances
of them.
I have some questions about address_data and variables, but first I
maybe tell big picture about what we are doing.
We have two kind of domains:
local domains - messages are scanned and forwarded to our mail stores
scan domains - messages are scanned and forwarded to clinet mail
server (catchall)
users are stored in postgres database.
for scan domains there is only one entry for @scan.domain pointing to
client mail server.
I use config:
while verifying:
- lookup user info in pgsql with "verify = recipient"
- save address_data to variable acl_m0
- if this is scan_domain require "verify = recipient/callout"
- extract different info from address_data and deny/accept recipient
while routing:
- get recipient data from acl_m0 and save to address_data
- if address_data is empty, lookup user data in pgsql
- [verify only] if this is scan domain, manual route it to client server
- fail if user or domain disabled
- check user forwards
- route local domains to local transport
- route scan domains to client mail server
- route all other by dnslookups
because scan domains use catchall address, transport host don't
change, so I save address_data a bit different for scan domains:
set acl_m0 = $acl_m0 @$domain="$address_data"
and for local domains
set acl_m0 = $acl_m0 $local_part@$domain="$address_data"
Now if message has multiple recipients for scan domain, only one query is used.
I lookup address_data with:
address_data =
${extract{$local_part@$domain}{$acl_m0}{$value}{${extract{@$domain}{$acl_m0}}}}
postgres return row with flags and mail store host:
local_domain=true, scan_domain=flase, store=10.0.0.1, forwards=true, ...
So here come questions:
*) Is it true, than address_data are deleted when verifying (when
calling verify = ... from acl)?
*) If user X has forwards and redirect router generates new addresses
Y, Z - address_data are copied from X and are not deleted.
*) Can I change acl_m variables from router? I need this because if
user has forwards I want to append new address_data lookups to acl_m0
cache and reuse later.
I see, that acl_m variable are saved in -H spool files, so this can be
done only while verifying. Is there any other variable which I can
change from routers, except address_data?
*) If user generates forwards to scan domains, I can't verify
recipients with /callout from routers.
*) acl_m variable with postgres lookups are saved in -H file, so if
delivery fails, those queries are out of date, but this looks okay.
*) Is it okay to append address_data to acl_m0 for every recipient? Is
there any limits on how big acl variables can be? Message with 500
recipients? :)