Doveadm не может починить индекс в Maildir


Проблема наблюдается в апреле-мае 2018 года с Dovecot настроенным работать с Maildir, при условии, что в этих каталогах есть сообщения созданные старой версией Dovecot и-или другими программами. Проявляется в том, что:

Сообщение об ошибке

Вот пример такой ошибки, вызванный искусственно, перименованием одного файла сообщения:
j1# mv epa.ru/pay/Maildir/new/1260928839.55604.server.sksys.net\,S\=14982 epa.ru/pay/Maildir/new/1260928839.55604.server.sksys.net\,S\=1498
j1# doveadm index -u pay@epa.ru '*'                                             doveadm(pay@epa.ru): Error: Mailbox INBOX: UID=221: read(/usr/local/vpopmail/domains/epa.ru/pay/Maildir/new/1260928839.55604.server.sksys.net,S=1498) failed: Cached message size smaller than expected (1498 < 8192, box=INBOX, UID=221) (read reason=mail stream)
doveadm(pay@epa.ru): Error: Corrupted record in index cache file /usr/local/vpopmail/domains/epa.ru/pay/Maildir/dovecot.index.cache: UID 221: Broken physical size in mailbox INBOX: read(/usr/local/vpopmail/domains/epa.ru/pay/Maildir/new/1260928839.55604.server.sksys.net,S=1498) failed: Cached message size smaller than expected (1498 < 8192, box=INBOX, UID=221)
doveadm(pay@epa.ru): Error: Mailbox INBOX: UID=221: read(/usr/local/vpopmail/domains/epa.ru/pay/Maildir/new/1260928839.55604.server.sksys.net,S=1498) failed: Cached message size smaller than expected (1498 < 8192, box=INBOX, UID=221) (read reason=)
doveadm(pay@epa.ru): Error: Mailbox INBOX: UID=221: read(/usr/local/vpopmail/domains/epa.ru/pay/Maildir/new/1260928839.55604.server.sksys.net,S=1498) failed: Cached message size smaller than expected (1498 < 8192, box=INBOX, UID=221) (read reason=parse header)
j1# mv epa.ru/pay/Maildir/new/1260928839.55604.server.sksys.net\,S\=1498 epa.ru/pay/Maildir/new/1260928839.55604.server.sksys.net\,S\=14982
j1# doveadm index -u pay@epa.ru '*'
doveadm(pay@epa.ru): Warning: Maildir /usr/local/vpopmail/domains/epa.ru/pay/Maildir: Expunged message reappeared, giving a new UID (old uid=157, file=1260928839.55604.server.sksys.net,S=14982)
j1# doveadm index -u pay@epa.ru '*'
j1#

В чём причина

В Maildir имена файлов сообщений содержат часть имени ,S=1567 - и тут должен быть точный размер в байтах. Сообщение dovecot не имеет ни малейшего отношения к файлам индекса и кеша. Оно порождено исключительно тем, что в некоторых сообщениях число в S= отличается от реального размера в байтах.

Как чинить

Проще всего переименовать все такие неудачные файлы в соответствии с их точным размером в байтах. Приведённый скрипт стирает индексные файлы, находит все неудачные сообщения, проверяет их размер и переименовывает их. После чего проходит по всем пользователям с index и resync.
cd /usr/local/vpopmail/domains
find ./ -name dovecot.index -delete
find ./ -name dovecot.index.log -delete
find ./ -name dovecot.list.index.log -delete
for i in `find ./ -name *.*.server.sksys.net\,S\=*`; do nname=${i%%,S=*} ; nsize=${i##*=} ; nsize=${nsize%%:*} ; rsize=`stat -f "%z" "$i"`; echo "$nsize - $rsize " ; [ "$nsize" = "$rsize" ] || mv "$i" "$nname,S=$rsize" ; done
cd /usr/local/etc/dovecot
for i in `cat users | awk 'BEGIN { FS=":"; } { print \$1; }'`; do echo $i ; doveadm index -u $i '*' ; doveadm force-resync -u $i '*' ; done