7

Sometimes, mails stay stuck in my postfix queue, the distant server saying "Too many connections, slow down". I already configured my postfix for specific domains to send only one mail per second, but sometimes it seems insufficient.

I know of postqueue -f, but it send all mails at the same time and the mails stays in queue with the same status.

I would like to flush the queue of a postfix one mail at a time, let's say one mail every second (or 2, or more).

vincent.m
  • 75
  • 1
  • 1
  • 6

2 Answers2

8

It's possible to flush one particular email, instead of the whole queue. If you do this for each message in turn, with a two-second sleep between messages, that should do what you ask for.

First, you need to find the queue IDs of the mails in the queue. You can get this by using the command postqueue -p. Here's an example output:

-Queue ID- --Size-- ----Arrival Time---- -Sender/Recipient-------
6777D6E1E      3517 Mon Jan 25 03:03:02  sender@example.se
                                         recipient@example.com

69F6471CA      2820 Tue Jan 26 03:24:17  sender@example.se
                                         recipient@example.net

What you need is in the first column. You can get all of the IDs by some piping through grep and cut, like so:

[jenny@sameen ~]$ postqueue -p | grep -v ^- | grep -v "(" | cut -d' ' -f1 |grep -e [[:alnum:]]
6777D6E1E
69F6471CA

Now that you know how to get at the IDs, you can throw them in a bash loop with some sleep:

[jenny@sameen ~]$ for ID in `postqueue -p | grep -v ^- | grep -v "(" | cut -d' ' -f1 |grep -e [[:alnum:]] `; do postqueue -i $ID; sleep 2; done
Jenny D
  • 27,358
  • 21
  • 74
  • 110
  • 2
    Nearly perfect, just had to exclude lines beginning with "(", thanks ! Which gives : `for ID in \`postqueue -p | grep -v ^-| cut -d' ' -f1 |grep -e [[:alnum:]]\` | grep -v "("; do postqueue -i $ID; sleep 2; done` – vincent.m Jan 29 '16 at 15:52
  • 2
    First of all, congratulations to @JennyD for the great idea and to @vincent.m for the necessary improvement (I have done +1 to both of you). Unfortunately vincent.m's answer has the backtick in the wrong position. Here you are the correct command, tested in Debian 8: `for ID in \`postqueue -p | grep -v ^-| cut -d' ' -f1 |grep -e [[:alnum:]] | grep -v "("\`; do postqueue -i $ID; sleep 2; done` – lucaferrario Aug 28 '17 at 08:56
  • 1
    Thanks @lucaferrario, I've updated the answer to include your edit - except that I moved the `grep -v "("` earlier, since I usually want to get rid of all the lines that shouldn't be processed before starting the processing. Thanks for the heads-up on the errors! – Jenny D Aug 28 '17 at 09:14
  • Thanks to both of you, i'm still using this every once in a while ! – vincent.m Sep 07 '17 at 09:59
0

my awk version:

for mailid in `postqueue -p | awk '$1 ~ /^[0-9A-F]{11}$/ {print $1}'`; do postqueue -i $mailid; sleep 5; done;