Индексные файлы Dovecot
Основное преимущество использования индексных файлов в Dovecot в том, что благодаря им чтение почтового ящика происходит значительно быстрее. В состав индексных файлов входят:
- dovecot.index: основной индексный файл
- dovecot.index.cache: кэшированные данные почтового ящика
- dovecot.index.log: Файл лога транзакций
- dovecot.index.log.2: Основной файл лога транзакций - .log сдвигается в .log.2, когда он достигает определённых размеров.
Для каждого почтового ящика организуются собственные индексные файлы. Если отключить использование индексных файлов, то хранение индексов будет осуществляться в памяти, за исключением файла кэша (так как клиент, вероятно, не захочет получать те же данные дважды за сеанс).
Если индексные файлы отсутствуют, то Dovecot создаст их автоматически, при открытии почтового ящика. В случае если создание индексного файла или его рост приводят к ошибке "недостаточно места на диске", структура индексов прозрачно будет перемещена в память до конца сессии.
Более подробно о том как обрабатываются индексные файлы можно прочитать в статье Design/Indexes
Основной индекс
Основной индекс хранит в себе о каждом почтовом сообщении следующую информацию:
- IMAP UID
- Текущие флаги и ключевые слова
- Указатель на кэш-файл
- Только для mbox-типа: смещение внутри mbox-файла
- Только для mbox-типа: MD5-сумму некоторых заголовков сообщения, которая призвана помочь найти сообщение, если заголовок X-UID сообщения на текущий момент не заполнен
- Другие расширения Dovecot версии v1.1 и выше, такие как, например, данные для сортировки содержимого почтового ящика
В целом, эту же информацию обрабатывают и другие IMAP-сервера, храня всю структуру индекса в памяти пока почтовый ящик открыт. Преимущество Dovecot в том, что он хранит данные на на диске и считывает их только в момент открытия почтового ящика.
Заголовок индексного файла так же содержит некоторую дополнительную информацию, как например, сколько сообщений в почтовом ящике, сколько из них непрочитано и сколько помечено флагом "удалено". Таким образом, открывая почтовый ящик и запрашивая команду STATUS клиент получает данные из заголовка индексного файла. Вот почему эти операции выполняются Dovecot крайне быстро по-сравнению с другими серверами, которые не используют подобный индексный файл.
Синхронизация почтового ящика
Заголовок основного индексного файла помимо прочего содержит информацию о статусе синхронизации почтового ящика:
- Maildir-тип: временные отметки директорий cur/ и new/
- mbox-тип: время изменения файла и его размер
Индексный файл синхронизируется с почтовым ящиком только если данные о синхронизации были изменены.
Кэш-файл
Кэш-файл содержит следующую информацию:
- Заголовки сообщений (некоторые, но не все)
- Дату отправления (поле Date: в заголовке)
- Дата получения (внутреннее поле IMAP)
- Физический и виртуальный размер сообщения
- Разобранную MIME-структуру почтового сообщения, что позволяет быстро прочитать определённую MIME-часть сообщения (команда FETCH BODY[1.2.3])
- IMAP-поля BODY и BODYSTRUCTURE
- Если оба эти поля используются, то хранится только BODYSTRUCTURE , так как поле BODY может быть сгенерировано по этому полю
- IMAP-поле ENVELOPE (конверт почтового сообщения) на текущий момент не кэшируется. Вместо этого кэшируются заголовки, которые используются для построения этого поля.
IMAP-клиенты можно разделить на два основных типа, по принципу работы:
- Online-клиенты, которые запрашивают одну и ту же информацию несколько раз (например, web-почта, Pine)
- Offline-клиенты, которые прежде всего скачивают заголовки интересующих их сообщений и только после этого тело сообщения (возможно автоматическое скачиваение или же тело скачивается, когда пользователь открывает сообщение). Большинство IMAP-клиентов ведут себя подобным образом.
Кэш-файл особенно необходим при работе с клиентами первого типа. При первом же запросе клиентом заголовков сообщения или каких-то других метаданных они будут сохранены в кэш-файле. При последующих запросах Dovecot может быстро вернуть эти данные прочитав их из кэша, вместо того чтоб открывать сообщение и снова разбирать поля заголовка.
Для клиентов второго типа кэш-файл будет полезен в случае использования большого числа клиентов или при сохранении сообщения, тогда данные могут быть кэшированны (Dovecot версии 1.1 и выше это поддерживает). Некоторые данные особенно полезны, например, прежде чем скачать сообщение необходимо знать виртуальный размер письма. Если бы эти данные не хранились в кэше, Dovecot приходилось бы считывать всё сообщение каждый раз, чтобы посчитать его виртуальный размер.
Только те метаданные, которые прежде были запрошены клиентом(-ами) сохраняются в кэш-файл. Это позволяет Dovecot адаптироваться к различным потребностям клиентов не загружая дисковую систему постоянными обращениями к полям сообщения, которые клиенту попросту не нужны.
Dovecot может кэшировать поля как временно так и постоянно. Временно кэшированные поля будут удалены из кэш-файла приблизительно через неделю. Для определения типа кэширования (временное или постоянное) Dovecot использует два правила:
- Клиент запрашивал сообщения непоследовательно в пределах одной сессии. Обычно это означает, что этих сообщений нет в локальном кэше.
- Клиент запросил сообщение более чем недельной давности.
Статья Design/Indexes/Cache поясняет причины принятия этих правил.
Лог транзакций
Все изменения, производимые в основном индексе, прежде всего пишутся в лог транзакций. Такой подход выгоден в случае, если к почтовому ящику осуществляется несколько одновременных подключений:
- Этот подход позволяет получить список изменений настолько быстро, что IMAP-клиенты могут быть уведомлены об изменениях. Альтернативой этому было бы сравнение двух индексов, что собственно и делает большинство IMAP-серверов.
Включение параметра mmap_disable=yes указывает Dovecot, что необходимо работать с логом транзакций. Таким образом, вместо повторного прочтения всего основного индекса при каждом изменении достаточно прочесть всего лишь несколько байт из лога транзакций.
В Dovecot версии 1.1 и выше лог транзакций играет ещё более важную роль. Основной индексный файл обновляется очень редко, чтобы снизить количество обращений к диску. Поэтому первое что делается при обращении к основному индексу - это запись последних изменений из лога транзакций в начало индекса. В случае с пустыми почтовыми ящиками (например download+delete POP3 users) было бы возможным удалить весь основной индекс и оставить только лог транзакций (к сожалению на текущий момент это не сделано).
