Dovecot

為什麼使用 Dovecot 通過 IMAP 刪除郵件後磁碟空間沒有減少?

  • November 10, 2018

我在 Linux 上使用 OpenSMTPD 和 Dovecot 執行電子郵件伺服器,並使用帶有 Thunderbird 客戶端的 IMAP 訪問電子郵件。當我在 Thunderbird 中刪除電子郵件時,為什麼磁碟空間使用率沒有下降?

例如,一個使用者的 mbox 文件儲存在 /var/vmail/ $ {domain}/ $ [使用者}/:

$ ls
Archives  Drafts  inbox  Sent  Spam  TrainSpam  Trash

我不確定 mbox 文件是否是稀疏文件,所以我希望擁有最準確的“有效”文件大小,而不是du(這也顯示了問題),所以我將此目錄中所有文件的所有大小相加:ls

$ ls -al | grep vmail | awk '{print $5}' | paste -sd+ | bc
1119217444

接下來,我去 Thunderbird,刪除一封帶有附件的大電子郵件,顯示大小為 1MB。Thunderbird 將它發送到 Deleted 文件夾,然後我轉到 Deleted 文件夾,在那裡將其刪除,確認永久刪除對話框並重新計算文件大小:

$ ls -al | grep vmail | awk '{print $5}' | paste -sd+ | bc
1119217443

所以它下降了1個字節。也許它只是將其標記為已刪除?我如何真正取回磁碟空間?我知道這可能很重要,因為 mbox 文件只是一個巨大的平面文件。

找到 dovecot 命令:

$ doveadm expunge -u $user@$host mailbox Trash all

在 MBOX 格式中,消息一個接一個地儲存在一個巨大的文件中,結構非常簡單:

From envelope-sender@example.com  Sat Nov 10 06:00:00 2018
From: Author <author@example.com>
To: Recipient <recipient@example.com>
Subject: Sample message 1

Message body.
>From is escaped. Otherwise it would break the MBOX file.

From envelope-sender@example.net  Sat Nov 10 06:30:00 2018
From: Author <author@example.net>
To: Recipient <recipient@example.com>
Subject: Sample message 2

Another message body.

因此,從文件中間刪除一條消息將導致重寫文件的其餘部分,這可能對性能和數據完整性都不利,因為如果寫入中斷,文件可能會損壞。

一種解決方案是將消息標記為已刪除,而不是實際刪除它,因為它只需要修改一行,同時保持文件的其餘部分完好無損。這允許稍後將多個刪除組合到一個操作中。

MozillaZine 關於壓縮文件夾的文章從 Thunderbird 的角度解釋了這一點:

當您在 Thunderbird 等電子郵件客戶端中刪除郵件時,它們並沒有被物理刪除。即使清空垃圾箱也無法擺脫它們。相反,它們被標記為刪除並從視圖中隱藏。在您“壓縮”文件夾之前,它們不會被物理刪除。這是為了提高大型文件夾的性能而進行的權衡。

Dovecot 關於Mbox 郵箱格式的文章解釋了 Dovecot 如何處理 MBOX 格式的問題。刪除儲存在X-Status: D添加到消息標頭的標頭中。

Dovecot 在 mbox 消息中使用與 C-Client(即 UW-IMAP、Pine)兼容的標頭來儲存元數據。這些標題是:

  • X-IMAPbase:包含 UIDVALIDITY、上次使用的 UID 和使用的關鍵字列表
  • X-IMAP:與 X-IMAPbase 相同,但也指定消息是“偽消息”
  • X-UID:消息分配的 UID
  • Status: R(\Seen) 和O(非\Recent) 標誌
  • X-Status: A(\Answered)、F(\Flagged)、T(\Draft) 和D(\Deleted) 標誌
  • X-Keywords:消息的關鍵字
  • Content-Length:消息體的長度(以字節為單位)

只要存在這些標頭中的任何一個,Dovecot 就會將它們視為自己的私有元數據。它會對它們進行完整性檢查,因此標題也可以被修改或完全刪除。當 IMAP/POP3 客戶端讀取郵件時,這些標頭都不會發送到它們。

引用自:https://serverfault.com/questions/939415