Thank you for reading this post, don't forget to subscribe!
Столкнулся с необычной ошибкой во время работы postfix. Ошибка не сложная, но первые признаки этой ошибки странные и вызывают вопросы. Это мешает быстро разобраться в ситуации
Началось все с того, что иногда я стал на почту получать вот такие оповещения:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
Transcript of session follows. Out: 220 mx.mailserver.ru ESMTP EME Postfix In: EHLO EMEserv Out: 250-mx.mailserver.ru Out: 250-PIPELINING Out: 250-SIZE 50000000 Out: 250-ETRN Out: 250-STARTTLS Out: 250-AUTH PLAIN LOGIN Out: 250-AUTH=PLAIN LOGIN Out: 250-ENHANCEDSTATUSCODES Out: 250-8BITMIME Out: 250 DSN In: AUTH LOGIN Out: 334 VXNlcrthbWU6 In: dW1qQmwtZS5ydQ== Out: 334 UGFzc3dvcmQ6 In: aXNyQXBQDpmY3OA== Out: 235 2.7.0 Authentication successful In: MAIL FROM: <> Out: 250 2.1.0 Ok In: RCPT TO: <user@mailserver.ru> Out: 250 2.1.5 Ok In: DATA Out: 354 End data with . Out: 451 4.3.0 <strong>Error: queue file write error</strong> Session aborted, reason: lost connection For other details, see the local mail logfile |
Первое что пришло в голову, когда увидел такое сообщение — что-то с файловой системой или с диском. Ошибка на тему невозможности записи очереди на это намекает. Все внимательно проверил на севере, ошибок с диском не заметил.
Подобные сообщения приходили не часто, сервер при этом нормально работал, мониторинг никаких проблем не видел, тестовые письма пролетали. Когда подобные ошибки стали появляться все чаще, начал разбираться подробнее.
Сервер достаточно нагруженный, поэтому его maillog читать неудобно, но пришлось. В логе обнаружил следующие предупреждения:
1 2 |
warning: connect to mysql server 10.1.6.224: Too many connections Aug 30 00:03:51 mailsrv postfix/smtpd[1137]: warning: mysql:/etc/postfix/alias-mysql.cf lookup error for "user@mailserver.ru" |
Тут стало все понятно. Срабатывает ограничение mysql сервера на количество параллельных запросов. Причем ошибка возникает не постоянно, а время от времени, скорее всего во время всплесков нагрузки. У меня mysql сервер это отдельная машина. Идем на этот сервер, заходим в консоль mysql и проверяем параметр max_connections. Если вы его не трогали, то по-умолчанию он будет равен 100.
Проверяем это в консоли mysql:
1 |
> show variables like "max_connections"; |
Я уже изменил на 200, поэтому у меня такое значение. Сделал я это следующей командой mysql:
1 |
> set global max_connections = 200; |
Параметр применяется сразу же, без перезагрузки. Чтобы после перезапуска сервера, значение осталось равным 200, добавляем в my.cnf в секцию [mysqld] следующий парметр.
1 |
max_connections = 200 |
Для того, чтобы посмотреть количество текущих соединений, используйте следующую команду в mysql консоли:
1 |
> show full processlist; |
Когда вы управляете почтовыми серверами Postfix с помощью соединений SQL для поиска информации об именах пользователей, расположениях почтовых ящиков / maildir на диске, в своем main.cf, у вас что-то вроде:
1 2 3 4 |
virtual_alias_maps = mysql: /etc/postfix/mysql_virtual_alias_maps.cf virtual_mailbox_domains = mysql: /etc/postfix/mysql_virtual_domains_maps.cf virtual_mailbox_maps = mysql: /etc/postfix/mysql_virtual_mailbox_maps.cf relay_domains = mysql: /etc/postfix/mysql_relay_domains_maps.cf |
Но, таким образом, каждый процесс (постфиксный процесс) использует одно соединение MySQL. Каждое сообщение, которое проходит через ваш сервер, будет открывать и закрывать соединение MySQL. Вероятно, это работает на простом почтовом сервере, который обрабатывает 3 доменных имени и около 15 обычных почтовых ящиков, но если у вас есть тысячи писем в час, которые проходят через ваш почтовый сервер, это может создавать много-много бесполезной нагрузки на ваш сервер.
Простой способ заставить Postfix использовать меньше соединений - это просто поместить «proxy:» перед всеми операторами «mysql:» в main.cf. Вы будете иметь:
1 2 3 4 |
virtual_alias_maps = proxy: mysql: /etc/postfix/mysql_virtual_alias_maps.cf virtual_mailbox_domains = proxy: mysql: /etc/postfix/mysql_virtual_domains_maps.cf virtual_mailbox_maps = proxy: mysql: /etc/postfix/mysql_virtual_mailbox_maps.cf relay_domains = proxy: mysql: /etc/postfix/mysql_relay_domains_maps.cf |
Таким образом, Postfix направляет все запросы SQL через один из двух своих демонов, называемых proxymap (используется для получения информации из базы данных) и proxywrite (используется для записи информации в базу данных).