Здесь могла бы быть статья про установку и настройку связки DBMail + PostgreSQL. Но в процессе работы над ней выяснилось, что система получается, увы, не слишком жизнеспособной... :( В частности, так и не удалось побороть ошибку ERROR: invalid byte sequence for encoding "UTF8": 0x.... При этом, сообщение просто не попадает в базу. И не смотря на то, что таких писем обычно не так уж и много - за сутки из пары-тройки тысяч их может набраться с десяток-другой, это далеко не всегда спам. Таким образом, практика "тихой" потери писем для меня неприемлема, поэтому от использования DBMail в реальной работе пришлось отказаться. Ну что ж, теперь, не смотря на высказанные к нему ниже претензии, будем разбираться с dovecot'ом...
Решил в очередной раз пощупать систему хранения почты в базе данных. Посмотреть на разрекламированную скорость работы. Да, многие скажут, что БД не предназначены для хранения подобных данных, что это неэффективно, что это неудобно в конце концов. Со многим я согласен. Мне, например, было бы удобнее работать с почтовыми ящиками формата Maildir - куда проще переносить, бэкапить, надежность явно выше, т.к. потеря/порча одного/нескольких файлов не затронет остальное, но... Попробую по памяти описать проблемы, с которыми лично я сталкивался при тестировании систем на базе стандартных решений (dovecot, courier... В дальнейшем, для примеров и сравнений я буду использовать dovecot).
1. Основная проблема - наличие в именах IMAP-папок не предусмотренных стандартом символов, в моем случае - точек, т.к. некоторые названия папок у нас представляют из себя e-mail (например, архив почты с подпапками, совпадающими с названиями адресов получателей). Увы, но не везде это решается, а там, где все же удается обойти это ограничение, делается это при помощи весьма сомнительных костылей; 2. Система организации хранения в maildir представляет из себя папку почтового ящика с подкаталогами первого уровня, не смотря на вложенность в структуре IMAP.
Например, имеем такую структуру IMAP-папок: account@mail.ru `- INBOX |-Family |-Favorites | `-Subscribes | |-Interesting | `-Lor | `-Best `-Friends
Казалось бы, вполне логично было бы все это так и расположить в файловой системе, однако хранение Maildir предусматривает создание только служебных подпапок (типа /cur, /new, /tmp). Вся же структура дерева папок хранится в "плоском" виде, т.е. все папки создаются на одном уровне вложенности и содержат в названии полный путь. Так, приведенный выше пример будет выглядеть примерно так (служебные каталоги для упрощения не указаны): .../account@mail.ru/ /.INBOX.Family/ /.INBOX.Favorites/ /.INBOX.Favorites.Subscribes/ /.INBOX.Favorites.Subscribes.Interesting/ /.INBOX.Favorites.Subscribes.Lor/ /.INBOX.Favorites.Subscribes.Lor.Best/ /.INBOX.Friends/ ...
На первый взгляд - ничего особенно страшного, все вполне понятно и даже в чем-то удобно, но... Если бы не было всяких "НО", то и проблемы бы не было. НО, мы ведь с вами люди русскоговорящие, и если, например, админ или программист еще могут использовать для себя подобную структуру каталогов, то какая-нибудь секретарша или, скажем, бухгалтер - врядли. Они, естественно, захотят иметь что-то вроде
/Входящие/Рассылки/Мэйл.ру/Любимое....
А вот тут вступает в силу пункт 1, т.к. в данном примере мы использовали в названии папки точку. Придется воспользоваться костылями, т.е. "экранированием" служебных символов. Например, в dovecot'е это реализуется плагином listescape с переназначением символа разделителя папок (namespace separator). Плюс ко всему врожденная нелюбовь всяких стандартов к не ASCII-кодировкам. Имена папок по стандарту должны содержать только 7-битные символы, соответственно, их тоже придется перекодировать (благо, это за нас сделает сам сервер). В итоге мы получим... Даже не знаю как это и назвать...
Таким образом, бОльшая часть удобства файловой системы нивелируется способом хранения данных. А ведь это вполне реальная ситуация, часто встречающаяся на практике. А теперь представьте как будет выглядеть на уровне файловой системы реальная IMAP-папка какого-нибудь сотрудника, например, менеджера или бухгалтера с десятками, а иногда и сотнями вложенных подпапок... А ведь еще есть ограничение на длину пути/файла, правда, не уверен что до этого дойдет, но все же... Тем более, что и сами имена файлов не далеко ушли, например, у dovecot'а: ls ./cur 1287670624.M925898P2265.imapserv,S=1259,W=1288:2,a 1287670625.M209409P2265.imapserv,S=1259,W=1288:2,Sa 1287670625.M343291P2265.imapserv,S=1903,W=1954:2,a 1287670625.M465600P2265.imapserv,S=1259,W=1288:2,a 1287670625.M624947P2265.imapserv,S=1903,W=1954:2,a 1287670625.M759803P2265.imapserv,S=1259,W=1288:2,a 1287670625.M893354P2265.imapserv,S=1902,W=1952:2,a ... Информативненько, не правда ли? Дело в том, что, насколько я понял, в имени файла так же хранится информация о флагах сообщения, что и приводит к данному виду. С одной стороны это добавляет надежности, ведь таким образом они как бы становятся самодостаточными, с другой - производительности это вряд ли добавит. При этом, если присмотреться, в именах файлов присутствует как минимум один сомнительный символ - двоеточие. Таким образом, переносимость данных так же будет ограничена - попробуйте, например, скопировать такой файл на Windows-машину...
Тут, видимо, проявляется маниакальная любовь Open-Source разработчиков к жесткому соблюдению стандартов. В принципе, это очень даже не плохо, за исключением того, что большинство этих самых стандартов были написаны еще на заре компьютерной эры и с тех пор так и не пересматривались.
Итак, возвращаясь к собственно теме. Возьмите статистику используемых почтовых серверов корпоративного уровня - думаю, что мегамонстр по имени Exchange там будет однозначно рулить. Не будем сейчас брать в расчет его возможности помимо почты, политику всем известной компании по продвижению своих продуктов, отсутствие какой-либо приличной альтернативы на той же платформе и т.д. Это все тоже понятно, но речь не об этом - речь о способе хранения данных. А ведь там тоже используется самая настоящая БД, в чем-то схожая с Access. И ведь ничего - шуршит... Так почему бы тогда все же не попробовать? Ведь денег с нас за это не берут :)
Итак, начнем. Установка проводилась из стандартных репов на Ubuntu 10.10 Server x64
Установленные версии на момент написания (08.12.2010): # uname -a Linux 2.6.35-22-server #33-Ubuntu SMP Sun Sep 19 20:48:58 UTC 2010 x86_64 GNU/Linux
# psql -V psql (PostgreSQL) 8.4.5 contains support for command-line editing
# dbmail-imapd -V This is DBMail version 2.2.11 ...
Заморачиваться с постгресом 9-й версии я пока не стал, т.к. хотел просто погонять систему и посмотреть на что она способна. Если результат меня устроит, буду уже копать в сторону возможностей репликации и кластеризации в 9-й ветке.
Установка в общем-то тривиальная, через apt: apt-get install postgresql-8.4 dbmail-imap
Далее, необходимо определиться с тем, где будет лежать, собственно, сама база dbmail: {TODO}
и создать её : {TODO}
После чего, залить в неё шаблон таблиц: {TODO}
Теперь можно править /etc/dbmail/dbmail.conf {TODO} Здесь у меня возникли проблемы с постгресом. На этапе тестирования при заливке большого количества сообщений с другого IMAP-сервера обычным перетаскиванием писем/папок, ThunderBird рандомно падал. Вскрытие логов показало наличие большого количества сообщений, типа:
а) HINT: Use the escape string syntax for backslashes, e.g., E'\\'. WARNING: nonstandard use of \\ in a string literal
Ошибка возникает при нахождении в добавляемом письме (тексте
или заголовках) обратного слэша "\", который, как известно, в
Linux-системах играет роль спецсимвола, который как бы говорит системе
использовать следующий за ним символ "как есть", без какой-либо
интерпретации.
В принципе, это не ошибка, а предупреждение, но логи забивает ужасно.
Поэтому лечим: в /etc/postgresql/8.4/main/postgresql.conf дописываем в
самый конец: escape_string_warning = off (отключаем вывод предупреждений при нахождении слэша в запросе) standard_conforming_strings = on (включаем соответствие стандартам, т.е. текстовые строки в запросах не будут анализироваться на наличие управляющих символов, а восприниматься "как есть". В PostgreSql версии 9.1 обещают включить эту опцию в "on" по умолчанию)
б) ERROR: invalid byte sequence for encoding "UTF8": 0xa9 HINT: This error can also happen if the byte sequence does not match the encoding expected by the server, which is controlled by "client_encoding". .. и далее несколько инсертов и селектов, которые привели к ошибке или были отменены при откате транзакции.
Ошибка происходит когда сервер находит в текстовых данных символы, не поддерживаемые указанной кодировкой. Увы, именно эта ошибка и привела к закрытию данного проекта, т.к. побороть её я так и не смог.