апгрейд popa3d (или любого другого pop3 сервера) на dovecot, c сохранением UIDL сообщений

Автор: oleg , 29 октября 2018

С ростом размера ящика, работа popa3d становится всё заметнее и заметнее на общей загруженности сервера. Это довольно очевидно, т.к. popa3d сервер индексирует mbox при каждом открытии, индекс ящика в файле не хранит, а пользователи всё чаще и чаще предпочитают храниить почту на сервере (обычно - копии писем за несколько дней/недель). Что-же делать? Да на dovecot перейти, но тут такая засада - надо как-то уболтать почтовые клиенты не считывать письма повторно. Для этого надо сделать так, чтобы uidl сообщений, которые почтовые клиенты уже `видели', не изменились. Итак:

  1. в /usr/local/etc/dovecot/conf.d/20-pop3.conf добавляем pop3_reuse_xuidl = yes
  2. с помощью нехитрых скриптов ( в один каталог кладём)

    xuidl.awk

     

    BEGIN { i=1 }

    1 { F=FILENAME;gsub("^.+/","",F);F=F".uidlz" }

    /^X-UIDL: / { next }

    /^From / {
        print
        getline ID < F; sub("^"i" ","",ID)
        print "X-UIDL: "ID
        i++
        next
    }

    { print }

    # vim:ts=4:sw=4:

    uidlz.sh

     

    #!/bin/sh

    _sleep=1

    # host 127.0.0.1 !!!
    _poport=110
    # indexz -> /var/mail/indexz/

    if [ -z "$BACKUPED_ALREADY" ]; then
        test -f /var/mail/$1-bak && echo seems to have been already X-UIDLed\! Check it out && exit
        cp -vp /var/mail/$1 /var/mail/$1-bak
    fi

    eval `stat -f 'echo -n > %N-new && chown %u:%g %N-new && chmod %Lp %N-new' /var/mail/$1` && \
        echo -e "user $1\nPASS $2\nUIDL\nquit" | nc 127.0.0.1 $_poport |\
        awk '/^1/,/^\./{if($0 ~ /^[0-9]/)print}' > $1.uidlz

    test `stat -f "%z" $1.uidlz` -eq 0 && echo "no UIDLZ, no gain =(" ||
    ( awk -f `dirname $0`/xuidl.awk /var/mail/$1 > /var/mail/$1-new && 
        mv -v /var/mail/$1-new /var/mail/$1 && touch -r /var/mail/$1-bak /var/mail/$1 && rm -r /var/mail/indexz/$1 )

    # check it, e.g.[tcsh]
    #
    # foreach a ( *.uidlz )
    #   sh -c 'echo -e "user '$a:r'\npass 123\nstat\nuidl\nquit"' | nc 192.168.0.1 110 | diffc 0 - $a
    # end

    # vim:ts=4:sw=4:

    обрабатываем все ящики.

Как-то так

Комментарии